diff --git a/.dev_to/compose.yml b/.dev_to/compose.yml index 6db3e51f..557748df 100644 --- a/.dev_to/compose.yml +++ b/.dev_to/compose.yml @@ -9,6 +9,7 @@ x-app: &app environment: &env NODE_ENV: ${NODE_ENV:-development} RAILS_ENV: ${RAILS_ENV:-development} + RACK_ENV: ${RACK_ENV:-development} tmpfs: - /tmp - /app/tmp/pids diff --git a/.gitignore b/.gitignore index 53c5b710..db33e9f4 100644 --- a/.gitignore +++ b/.gitignore @@ -56,3 +56,6 @@ package-lock.json #sitemap /public/sitemap.xml.gz + +#newrelic +newrelic-infra/newrelic-infra.yml diff --git a/.ruby-version b/.ruby-version index bea438e9..47b322c9 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.3.1 +3.4.1 diff --git a/Envfile b/Envfile index 944a3fac..2820e85a 100644 --- a/Envfile +++ b/Envfile @@ -53,6 +53,9 @@ variable :ALGOLIASEARCH_API_KEY, :String, default: only_in_test variable :ALGOLIASEARCH_APPLICATION_ID, :String, default: only_in_test variable :ALGOLIASEARCH_SEARCH_ONLY_KEY, :String, default: only_in_test +# NewRelic +variable :NEW_RELIC_LICENSE_KEY, :String, default: "Optional" + # AWS for images storages variable :AWS_ID, :String, default: "Optional" variable :AWS_SECRET, :String, default: "Optional" diff --git a/Gemfile b/Gemfile index b107eb92..300649f5 100644 --- a/Gemfile +++ b/Gemfile @@ -13,6 +13,10 @@ group :production do gem "nakayoshi_fork" end +gem 'newrelic_rpm' +gem 'newrelic-infinite_tracing' +gem 'rack-mini-profiler' + gem "psych", "< 4" gem "skylight" @@ -105,7 +109,7 @@ gem "validate_url", "~> 1.0" gem "webpacker", "~> 3.6" gem "webpush", "~> 0.3" -group :development do +group :development, :local_production do gem "better_errors", "~> 2.5" gem "binding_of_caller", "~> 0.8" gem "brakeman", "~> 4.4", require: false @@ -119,7 +123,7 @@ group :development do gem "web-console", "~> 3.7" end -group :development, :test do +group :development, :test, :local_production do gem "capybara", "~> 3.13" gem "derailed", "~> 0.1" gem "erb_lint", "~> 0.0", require: false diff --git a/Gemfile.lock b/Gemfile.lock index 130d7472..27571167 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -505,12 +505,22 @@ GEM google-apis-core (>= 0.11.0, < 2.a) google-apis-discovery_v1 (~> 0.5) thor (>= 0.20, < 2.a) + google-protobuf (3.25.6-aarch64-linux) + google-protobuf (3.25.6-x86_64-linux) + googleapis-common-protos-types (1.18.0) + google-protobuf (>= 3.18, < 5.a) googleauth (1.8.1) faraday (>= 0.17.3, < 3.a) jwt (>= 1.4, < 3.0) multi_json (~> 1.11) os (>= 0.9, < 2.0) signet (>= 0.16, < 2.a) + grpc (1.65.2-aarch64-linux) + google-protobuf (>= 3.25, < 5.0) + googleapis-common-protos-types (~> 1.0) + grpc (1.65.2-x86_64-linux) + google-protobuf (>= 3.25, < 5.0) + googleapis-common-protos-types (~> 1.0) guard (2.19.1) formatador (>= 0.2.4) listen (>= 2.7, < 4.0) @@ -646,9 +656,16 @@ GEM net-smtp (0.5.1) net-protocol netrc (0.11.0) + newrelic-infinite_tracing (9.17.0) + google-protobuf (< 4.0) + grpc (~> 1.34) + newrelic_rpm (= 9.17.0) + newrelic_rpm (9.17.0) nio4r (2.7.4) nokogiri (1.15.7-aarch64-linux) racc (~> 1.4) + nokogiri (1.15.7-x86_64-linux) + racc (~> 1.4) notiffany (0.1.3) nenv (~> 0.1) shellany (~> 0.0) @@ -726,6 +743,8 @@ GEM rack (2.2.11) rack-host-redirect (1.3.0) rack + rack-mini-profiler (3.3.1) + rack (>= 1.2.0) rack-protection (2.2.4) rack rack-proxy (0.7.7) @@ -1011,6 +1030,7 @@ GEM PLATFORMS aarch64-linux + x86_64-linux DEPENDENCIES actionpack-action_caching (~> 1.2) @@ -1081,6 +1101,8 @@ DEPENDENCIES liquid (~> 4.0) memory_profiler (~> 0.9) nakayoshi_fork + newrelic-infinite_tracing + newrelic_rpm nokogiri (~> 1.10) octokit (~> 4.13) omniauth (~> 1.9) @@ -1098,6 +1120,7 @@ DEPENDENCIES pusher (~> 1.3) pusher-push-notifications (~> 1.0) rack-host-redirect (~> 1.3) + rack-mini-profiler rack-timeout (~> 0.5) rails (~> 5.1.6) rails-assets-airbrake-js-client (~> 1.5)! diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index fdad0526..195c8de6 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -83,7 +83,7 @@ def icon_url(name) end def cloudinary(url, width = nil, _quality = 80, _format = "jpg") - return url if Rails.env.development? && (url.blank? || url.exclude?("http")) + return url if (Rails.env.development? || Rails.env.local_production?) && (url.blank? || url.exclude?("http")) service_path = "https://res.cloudinary.com/practicaldev/image/fetch" @@ -101,7 +101,7 @@ def cloudinary(url, width = nil, _quality = 80, _format = "jpg") def cloud_cover_url(url) return if url.blank? return asset_path("triple-unicorn") if Rails.env.test? - return url if Rails.env.development? + return url if (Rails.env.development? || Rails.env.local_production?) width = 1000 height = 420 diff --git a/app/observers/article_observer.rb b/app/observers/article_observer.rb index 17192106..ac3ec075 100644 --- a/app/observers/article_observer.rb +++ b/app/observers/article_observer.rb @@ -1,6 +1,6 @@ class ArticleObserver < ApplicationObserver def after_save(article) - return if Rails.env.development? + return if (Rails.env.development? || Rails.env.local_production?) if article.published && article.published_at > 30.seconds.ago SlackBot.delay.ping "New Article Published: #{article.title}\nhttps://dev.to#{article.path}", diff --git a/app/observers/comment_observer.rb b/app/observers/comment_observer.rb index 410a0029..3d282fc7 100644 --- a/app/observers/comment_observer.rb +++ b/app/observers/comment_observer.rb @@ -1,6 +1,6 @@ class CommentObserver < ApplicationObserver def after_save(comment) - return if Rails.env.development? + return if (Rails.env.development? || Rails.env.local_production?) warned_user_ping(comment) rescue StandardError diff --git a/app/observers/organization_observer.rb b/app/observers/organization_observer.rb index 5fb91cd0..27f3c7ba 100644 --- a/app/observers/organization_observer.rb +++ b/app/observers/organization_observer.rb @@ -1,6 +1,6 @@ class OrganizationObserver < ActiveRecord::Observer def after_create(organization) - return if Rails.env.development? + return if (Rails.env.development? || Rails.env.local_production?) SlackBot.delay.ping( "New Org Created: #{organization.name}\nhttps://dev.to/#{organization.username}", diff --git a/app/views/stories/_main_stories_feed.html.erb b/app/views/stories/_main_stories_feed.html.erb index b6cd0a65..3e175010 100644 --- a/app/views/stories/_main_stories_feed.html.erb +++ b/app/views/stories/_main_stories_feed.html.erb @@ -55,7 +55,9 @@ <% if !user_signed_in? && i == 4 %> <%= render "stories/sign_in_invitation" %> <% end %> - <%= render "articles/single_story", story: story %> + <% cache story do %> + <%= render "articles/single_story", story: story %> + <% end %> <% end %> <% end %> <% if @stories.size > 1 %> diff --git a/case-study.md b/case-study.md new file mode 100644 index 00000000..6ded8d59 --- /dev/null +++ b/case-study.md @@ -0,0 +1,233 @@ +# Case Strudy + +## Подготовка + +- [x] запустить проект +- [x] настроить NewRelic (docker compose -f docker-compose.yaml up -d) +- [x] настроить rack-mini-profiler +- [x] для нагрузки подготовил siege +- [x] local_production +- [] использовать альтернативу NewRelic + +## Оптимизация + +Сразу для того чтобы сравнить решил сравнивать вывод в NewRelic и RMP(по подробности данным всё же RMP более удобный, меньше повторяющейся информации и больше подробностей). + +Получил что при первой загруку страница запускалась где-то 3252.06 ms, при повторной ускорилось до 1300 - 1600.1 ms, из-за разных кэшей браузера и уже настроенных кэшей приложения. + +через RMP видно что проблема рендерингом main_stories_feed, а точнее _single_story +
+ +``` +/ (1362.6 ms) + +event duration (ms) from start (ms) query time (ms) +GET http://localhost:3000/ 36.3 +0.0 + Executing: stories#index 103.1 +17.0 2 sql 5.1 + Rendering: layouts/application.html.erb 169.8 +120.7 + Rendering: articles/index.html.erb 124.4 +147.2 2 sql 23.9 + Rendering: articles/_sidebar.html.erb 27.7 +162.3 + Rendering: stories/_main_stories_feed.html.er... 368.9 +257.5 + Rendering: articles/_single_story.html.erb 21.6 +275.3 + Rendering: articles/_single_story.html.erb 18.3 +312.3 + Rendering: articles/_single_story.html.erb 16.1 +344.4 + Rendering: articles/_single_story.html.erb 16.8 +373.9 + Rendering: articles/_single_story.html.erb 18.8 +419.8 + Rendering: articles/_single_story.html.erb 59.2 +452.3 + Rendering: articles/_single_story.html.erb 17.6 +532.9 + Rendering: articles/_single_story.html.erb 19.3 +566.2 + Rendering: articles/_single_story.html.erb 16.7 +599.8 + Rendering: articles/_single_story.html.erb 15.7 +630.7 + Rendering: articles/_single_story.html.erb 23.4 +660.1 + Rendering: articles/_single_story.html.erb 21.3 +699.0 + Rendering: articles/_single_story.html.erb 17.6 +742.9 + Rendering: articles/_single_story.html.erb 19.5 +774.9 + Rendering: articles/_single_story.html.erb 18.3 +810.2 + Rendering: articles/_single_story.html.erb 17.9 +844.7 + Rendering: articles/_single_story.html.erb 17.9 +876.7 + Rendering: articles/_single_story.html.erb 17.4 +908.2 + Rendering: articles/_single_story.html.erb 17.7 +939.9 + Rendering: articles/_single_story.html.erb 16.1 +972.5 + Rendering: articles/_single_story.html.erb 16.0 +1002.6 + Rendering: articles/_single_story.html.erb 16.4 +1031.2 + Rendering: articles/_single_story.html.erb 18.0 +1061.9 + Rendering: articles/_single_story.html.erb 18.1 +1096.4 + Rendering: articles/_sidebar_additional.html.... 28.2 +1128.8 + Rendering: layouts/_styles.html.erb 14.6 +1200.4 +show time with childrensnapshots2.1 % in sql +``` +
+ +при нагрузке через ab, сразу отваливается по таймауту, результаты получит не получилось. +
+ +``` +romaS:~/ $ ab -n 100 -c 5 127.0.0.1:3000/ +This is ApacheBench, Version 2.3 <$Revision: 1913912 $> +Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ +Licensed to The Apache Software Foundation, http://www.apache.org/ + +Benchmarking 127.0.0.1 (be patient)...apr_pollset_poll: The timeout specified has expired (70007) +``` +
+ + +Посмотревчто можно сделать, и учитывая совет из задачи мы понимаем что нам позволительно закэшировать `<%= render "articles/single_story", story: story %>`. +Проверим эту гипотезу, добавляем кэширование + + +Как результат первая загрузка не поменялас в среднем как и было 3252.06 ms, но при этом любая повторная загрузка уже выполняется в среднем за 588 ms. Что довольно силь что в 2.2 быстрее чем без использования кэшей. Так же успешно удалось назузить через `ab -n 100 -c 5 127.0.0.1:3000/` + +
+ +``` + + (588.4 ms) +event duration (ms) from start (ms) query time (ms) +GET http://localhost:3000/ 28.9 +0.0 + Executing: stories#index 94.8 +10.0 2 sql 3.7 + Rendering: layouts/application.html.erb 197.5 +105.2 + Rendering: articles/index.html.erb 114.0 +139.3 2 sql 16.0 + Rendering: articles/_sidebar.html.erb 31.6 +156.4 + Rendering: stories/_main_stories_feed.html.er... 77.7 +242.8 + Rendering: articles/_sidebar_additional.html.... 27.8 +335.2 + Rendering: layouts/_styles.html.erb 14.6 +407.4 +show time with childrensnapshots3.3 % in sql + +``` + +``` + +romaS:~/ $ ab -n 100 -c 5 127.0.0.1:3000/ + +This is ApacheBench, Version 2.3 <$Revision: 1913912 $> +Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ +Licensed to The Apache Software Foundation, http://www.apache.org/ + +Benchmarking 127.0.0.1 (be patient).....done + + +Server Software: +Server Hostname: 127.0.0.1 +Server Port: 3000 + +Document Path: / +Document Length: 158268 bytes + +Concurrency Level: 5 +Time taken for tests: 209.115 seconds +Complete requests: 100 +Failed requests: 99 + (Connect: 0, Receive: 0, Length: 99, Exceptions: 0) +Total transferred: 15946689 bytes +HTML transferred: 15846641 bytes +Requests per second: 0.48 [#/sec] (mean) +Time per request: 10455.725 [ms] (mean) +Time per request: 2091.145 [ms] (mean, across all concurrent requests) +Transfer rate: 74.47 [Kbytes/sec] received + +Connection Times (ms) + min mean[+/-sd] median max +Connect: 0 0 0.0 0 0 +Processing: 1701 10294 7288.4 8318 43677 +Waiting: 1697 10285 7288.8 8297 43675 +Total: 1701 10294 7288.5 8318 43677 + +Percentage of the requests served within a certain time (ms) + 50% 8318 + 66% 8570 + 75% 9021 + 80% 9435 + 90% 15895 + 95% 31402 + 98% 43428 + 99% 43677 + 100% 43677 (longest request) +``` + +
+ +## Заключение +Как вердикт проверка теории о использовании кэшей для `articles/single_story` принесла свои результаты и ускорила повторные загрузки страницы в 2 раза. + + + + +# Доп подкючение local_production + +При создании local_production окружении и использовании его, видны следующие улучшения максимально приближённые к продовому окруэениею. + - время загрузки посторной страницы занимает теперь не 588.4 ms, а 129 ms + - при нагрузки через `ab -n 100 -c 5 127.0.0.1:3000/`, уменьшилось в 10 раз среднее время по всем показателям + было + ``` + Time per request: 10455.725 [ms] (mean) + Time per request: 2091.145 [ms] (mean, across all concurrent requests) + ``` + стало + ``` + Time per request: 1043.882 [ms] (mean) + Time per request: 208.776 [ms] (mean, across all concurrent requests) + ``` + +
+``` +/ (129.9 ms) +event duration (ms) from start (ms) query time (ms) +GET http://localhost:3000/ 46.0 +0.0 + Executing: stories#index -29.6 +15.0 2 sql 4.0 + Rendering: articles/index.html.erb 46.0 +39.4 2 sql 22.6 + Rendering: stories/_main_stories_feed.html.er... 7.1 +85.7 + Rendering: layouts/application.html.erb 58.8 +40.0 +show time with childrensnapshots20.5 % in sql +client event duration (ms) from start (ms) +Response 2.0 +160.0 +sharemore show trivial +``` + +``` +romaS:.dev_to/ (master✗) $ ab -n 100 -c 5 127.0.0.1:3000/ +This is ApacheBench, Version 2.3 <$Revision: 1913912 $> +Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ +Licensed to The Apache Software Foundation, http://www.apache.org/ + +Benchmarking 127.0.0.1 (be patient).....done + + +Server Software: +Server Hostname: 127.0.0.1 +Server Port: 3000 + +Document Path: / +Document Length: 129969 bytes + +Concurrency Level: 5 +Time taken for tests: 20.878 seconds +Complete requests: 100 +Failed requests: 99 + (Connect: 0, Receive: 0, Length: 99, Exceptions: 0) +Total transferred: 13115169 bytes +HTML transferred: 13014935 bytes +Requests per second: 4.79 [#/sec] (mean) +Time per request: 1043.882 [ms] (mean) +Time per request: 208.776 [ms] (mean, across all concurrent requests) +Transfer rate: 613.47 [Kbytes/sec] received + +Connection Times (ms) + min mean[+/-sd] median max +Connect: 0 0 0.0 0 0 +Processing: 394 968 548.3 787 2999 +Waiting: 392 958 549.7 779 2986 +Total: 394 968 548.3 787 2999 + +Percentage of the requests served within a certain time (ms) + 50% 787 + 66% 911 + 75% 1017 + 80% 1223 + 90% 1844 + 95% 2187 + 98% 2959 + 99% 2999 + 100% 2999 (longest request) +``` +
\ No newline at end of file diff --git a/config/environments/development.rb b/config/environments/development.rb index ad3b97cb..a4ff2ae4 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -98,6 +98,7 @@ def yarn_integrity_enabled? config.after_initialize do Bullet.enable = true Bullet.console = true + Rack::MiniProfiler.config.authorization_mode = :allow_all end end diff --git a/config/environments/local_production.rb b/config/environments/local_production.rb new file mode 100644 index 00000000..ef39dabb --- /dev/null +++ b/config/environments/local_production.rb @@ -0,0 +1,108 @@ +# rubocop:disable Metrics/BlockLength +# +def yarn_integrity_enabled? + ENV.fetch("YARN_INTEGRITY_ENABLED", "true") == "true" +end + +Rails.application.configure do + # Verifies that versions and hashed value of the package contents in the project's package.json + config.webpacker.check_yarn_integrity = yarn_integrity_enabled? + + # Settings specified here will take precedence over those in config/application.rb. + + # In the development environment your application's code is reloaded on + # every request. This slows down response time but is perfect for development + # since you don't have to restart the web server when you make code changes. + config.cache_classes = true + + # Do not eager load code on boot. + config.eager_load = true + + # Show full error reports and disable caching. + config.consider_all_requests_local = true + + # Enable/disable caching. By default caching is disabled. + if Rails.root.join("tmp/caching-dev.txt").exist? + config.action_controller.perform_caching = true + + config.cache_store = :memory_store + config.public_file_server.headers = { + "Cache-Control" => "public, max-age=172800" + } + else + config.action_controller.perform_caching = false + + config.cache_store = :null_store + end + + # Don't care if the mailer can't send. + config.action_mailer.raise_delivery_errors = false + + # Print deprecation notices to the Rails logger. + config.active_support.deprecation = :log + + # Raise an error on page load if there are pending migrations. + config.active_record.migration_error = :page_load + + # Debug mode disables concatenation and preprocessing of assets. + # This option may cause significant delays in view rendering with a large + # number of complex assets. + config.assets.debug = false + + # Asset digests allow you to set far-future HTTP expiration dates on all assets, + # yet still be able to expire them through the digest params. + config.assets.digest = false + config.assets_compile = false + + # Supress logger output for asset requests. + config.assets.quiet = true + + # Adds additional error checking when serving assets at runtime. + # Checks for improperly declared sprockets dependencies. + # Raises helpful error messages. + config.assets.raise_runtime_errors = true + + config.action_mailer.perform_caching = false + + config.web_console.development_only = false + + config.app_domain = "localhost:3000" + + config.action_mailer.default_url_options = { host: "localhost:3000" } + config.action_mailer.delivery_method = :smtp + config.action_mailer.perform_deliveries = true + config.action_mailer.default_url_options = { host: config.app_domain } + config.action_mailer.smtp_settings = { + address: "smtp.gmail.com", + port: "587", + enable_starttls_auto: true, + user_name: '<%= ENV["DEVELOPMENT_EMAIL_USERNAME"] %>', + password: '<%= ENV["DEVELOPMENT_EMAIL_PASSWORD"] %>', + authentication: :plain, + domain: "localhost:3000" + } + + config.action_mailer.preview_path = "#{Rails.root}/spec/mailers/previews" + + # Raises error for missing translations + # config.action_view.raise_on_missing_translations = true + + config.public_file_server.enabled = true + + config.file_watcher = ActiveSupport::EventedFileUpdateChecker + + # Install the Timber.io logger + send_logs_to_timber = ENV["SEND_LOGS_TO_TIMBER"] || "false" # <---- set to false to stop sending dev logs to Timber.io + log_device = send_logs_to_timber == "true" ? Timber::LogDevices::HTTP.new(ENV["TIMBER"]) : STDOUT + logger = Timber::Logger.new(log_device) + logger.level = config.log_level + config.logger = ActiveSupport::TaggedLogging.new(logger) + + config.after_initialize do + Bullet.enable = true + Bullet.console = true + Rack::MiniProfiler.config.authorization_mode = :allow_all + end +end + +# rubocop:enable Metrics/BlockLength diff --git a/config/initializers/airbrake.rb b/config/initializers/airbrake.rb index 0a3fffc7..c530ddc8 100644 --- a/config/initializers/airbrake.rb +++ b/config/initializers/airbrake.rb @@ -41,7 +41,7 @@ # environments. # NOTE: This option *does not* work if you don't set the 'environment' option. # https://github.com/airbrake/airbrake-ruby#ignore_environments - c.ignore_environments = %w[test development] + c.ignore_environments = %w[test development local_production] # A list of parameters that should be filtered out of what is sent to # Airbrake. By default, all "password" attributes will have their contents diff --git a/config/initializers/carrierwave.rb b/config/initializers/carrierwave.rb index 9e191ac1..f90ec1ed 100644 --- a/config/initializers/carrierwave.rb +++ b/config/initializers/carrierwave.rb @@ -3,7 +3,7 @@ require "carrierwave/storage/fog" CarrierWave.configure do |config| - if Rails.env.development? || Rails.env.test? + if (Rails.env.development? || Rails.env.local_production?) || Rails.env.test? config.storage = :file else # config.fog_provider = 'fog-aws' diff --git a/config/initializers/delayed_job.rb b/config/initializers/delayed_job.rb index 4c0241a0..202e0790 100644 --- a/config/initializers/delayed_job.rb +++ b/config/initializers/delayed_job.rb @@ -1,4 +1,4 @@ -Delayed::Worker.destroy_failed_jobs = !Rails.env.development? +Delayed::Worker.destroy_failed_jobs = !(Rails.env.development? || Rails.env.local_production?) Delayed::Worker.sleep_delay = 60 Delayed::Worker.max_attempts = 10 Delayed::Worker.max_run_time = 30.minutes diff --git a/config/initializers/honeycomb.rb b/config/initializers/honeycomb.rb index 0ac4787a..f1810bad 100644 --- a/config/initializers/honeycomb.rb +++ b/config/initializers/honeycomb.rb @@ -3,7 +3,7 @@ key = ApplicationConfig["HONEYCOMB_API_KEY"] dataset = "dev.to-#{Rails.env}" -$libhoney = if Rails.env.development? || Rails.env.test? +$libhoney = if (Rails.env.development? || Rails.env.local_production?) || Rails.env.test? Libhoney::NullClient.new else Libhoney::Client.new( diff --git a/config/initializers/reverse_markdown.rb b/config/initializers/reverse_markdown.rb index 86e6500d..22c2a167 100644 --- a/config/initializers/reverse_markdown.rb +++ b/config/initializers/reverse_markdown.rb @@ -4,7 +4,7 @@ # Because files are eagerloaded in production, this fix is only # applicable in development (and test, when needed) -if Rails.env.development? || Rails.env.test? +if (Rails.env.development? || Rails.env.local_production?) || Rails.env.test? Rails.application.config.to_prepare do Dir.glob(Rails.root.join("app/lib/reverse_markdown/converters/*.rb")).sort.each do |filename| require_dependency filename diff --git a/config/initializers/timber.rb b/config/initializers/timber.rb index 726d3f22..fcfdc412 100644 --- a/config/initializers/timber.rb +++ b/config/initializers/timber.rb @@ -12,7 +12,7 @@ config = Timber::Config.instance config.integrations.action_view.silence = true -config.integrations.active_record.silence = !Rails.env.development? +config.integrations.active_record.silence = !(Rails.env.development? || Rails.env.local_production?) config.integrations.rack.http_events.collapse_into_single_event = true # Add additional configuration here. diff --git a/config/initializers/timeout.rb b/config/initializers/timeout.rb index 076288f3..d578d877 100644 --- a/config/initializers/timeout.rb +++ b/config/initializers/timeout.rb @@ -1,7 +1,7 @@ -if Rails.env.development? && ENV["RACK_TIMEOUT_WAIT_TIMEOUT"].nil? +if (Rails.env.development? || Rails.env.local_production?) && ENV["RACK_TIMEOUT_WAIT_TIMEOUT"].nil? ENV["RACK_TIMEOUT_WAIT_TIMEOUT"] = "100000" ENV["RACK_TIMEOUT_SERVICE_TIMEOUT"] = "100000" end -Rack::Timeout.unregister_state_change_observer(:logger) if Rails.env.development? +Rack::Timeout.unregister_state_change_observer(:logger) if (Rails.env.development? || Rails.env.local_production?) Rack::Timeout::Logger.disable diff --git a/config/newrelic.yml b/config/newrelic.yml new file mode 100644 index 00000000..ad267869 --- /dev/null +++ b/config/newrelic.yml @@ -0,0 +1,69 @@ +# +# This file configures the New Relic Agent. New Relic monitors Ruby, Java, +# .NET, PHP, Python, Node, and Go applications with deep visibility and low +# overhead. For more information, visit www.newrelic.com. +# +# Generated October 28, 2022 +# +# This configuration file is custom generated for NewRelic Administration +# +# For full documentation of agent configuration options, please refer to +# https://docs.newrelic.com/docs/agents/ruby-agent/installation-configuration/ruby-agent-configuration + +common: &default_settings + # Required license key associated with your New Relic account. + license_key: <%= ENV['NEW_RELIC_LICENSE_KEY'] %> + + # Your application name. Renaming here affects where data displays in New + # Relic. For more details, see https://docs.newrelic.com/docs/apm/new-relic-apm/maintenance/renaming-applications + app_name: 'dev_to_local' + + distributed_tracing: + enabled: true + + # To disable the agent regardless of other settings, uncomment the following: + + # agent_enabled: false + + # Logging level for log/newrelic_agent.log + log_level: info + + application_logging: + # If `true`, all logging-related features for the agent can be enabled or disabled + # independently. If `false`, all logging-related features are disabled. + enabled: true + forwarding: + # If `true`, the agent captures log records emitted by this application. + enabled: true + # Defines the maximum number of log records to buffer in memory at a time. + max_samples_stored: 10000 + metrics: + # If `true`, the agent captures metrics related to logging for this application. + enabled: true + local_decorating: + # If `true`, the agent decorates logs with metadata to link to entities, hosts, traces, and spans. + # This requires a log forwarder to send your log files to New Relic. + # This should not be used when forwarding is enabled. + enabled: false + +# Environment-specific settings are in this section. +# RAILS_ENV or RACK_ENV (as appropriate) is used to determine the environment. +# If your application has other named environments, configure them here. +development: + <<: *default_settings + app_name: 'dev_to_local (Development)' + +test: + <<: *default_settings + # It doesn't make sense to report to New Relic from automated test runs. + monitor_mode: false + +staging: + <<: *default_settings + app_name: 'dev_to_local (Staging)' + +production: + <<: *default_settings + +local_production: + <<: *default_settings diff --git a/config/sample_application.yml b/config/sample_application.yml index a829dae5..0e1c7d05 100644 --- a/config/sample_application.yml +++ b/config/sample_application.yml @@ -15,3 +15,5 @@ PUSHER_APP_ID: PUSHER_KEY: PUSHER_SECRET: PUSHER_CLUSTER: + +NEW_RELIC_LICENCE_KEY: \ No newline at end of file diff --git a/config/secrets.yml b/config/secrets.yml index 73f5e05c..181bd560 100644 --- a/config/secrets.yml +++ b/config/secrets.yml @@ -16,6 +16,9 @@ development: test: secret_key_base: 42dd7834039ebbea271af22635a6782ee15e519b14629c5276bfcdd4cff841e9926994784bb43a335a8f8c9739bb254ea3afe831839d4dc65654ec7516ec25f0 +local_production: + secret_key_base: a60edc976c913b19fd9fc8118936fbe1df2b07f4eecc5ad32f975e33cd4ea36b150c1ce933b681b90874a46568041629003dcbfc07238f7dca91741bcd1ec870 + # Do not keep production secrets in the repository, # instead read values from the environment. diff --git a/config/webpacker.yml b/config/webpacker.yml index 2dfcd170..18ef8e71 100644 --- a/config/webpacker.yml +++ b/config/webpacker.yml @@ -54,3 +54,12 @@ production: # Cache manifest.json for performance cache_manifest: true + +local_production: + <<: *default + + # Production depends on precompilation of packs prior to booting for performance. + compile: false + + # Cache manifest.json for performance + cache_manifest: true \ No newline at end of file diff --git a/dip.yml b/dip.yml index 05d96de5..431b903f 100644 --- a/dip.yml +++ b/dip.yml @@ -3,7 +3,7 @@ version: '7.1' # Define default environment variables to pass # to Docker Compose environment: - RAILS_ENV: development + RAILS_ENV: <%= ENV.fetch('RAILS_ENV', 'development') %> compose: files: diff --git a/newrelic-infra/docker-compose.yaml b/newrelic-infra/docker-compose.yaml new file mode 100644 index 00000000..8f64959e --- /dev/null +++ b/newrelic-infra/docker-compose.yaml @@ -0,0 +1,17 @@ +version: '3' + +services: + agent: + container_name: newrelic-infra + build: + context: . + dockerfile: newrelic-infra.dockerfile + cap_add: + - SYS_PTRACE + network_mode: host + pid: host + privileged: true + volumes: + - "/:/host:ro" + - "/var/run/docker.sock:/var/run/docker.sock" + restart: unless-stopped diff --git a/newrelic-infra/newrelic-infra.dockerfile b/newrelic-infra/newrelic-infra.dockerfile new file mode 100644 index 00000000..05bb7e74 --- /dev/null +++ b/newrelic-infra/newrelic-infra.dockerfile @@ -0,0 +1,2 @@ +FROM newrelic/infrastructure:latest +ADD newrelic-infra.yml /etc/newrelic-infra.yml