From d4892a02dada4ea194361aee1feffd96c4f34a04 Mon Sep 17 00:00:00 2001 From: Igor Arkhipov Date: Sat, 18 Nov 2023 00:34:37 +0100 Subject: [PATCH 1/6] Initial commit --- .ruby-version | 2 +- Gemfile | 2 +- Gemfile.lock | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.ruby-version b/.ruby-version index ec1cf33c..1f7da99d 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.6.3 +2.7.7 diff --git a/Gemfile b/Gemfile index 1a5f4c0b..98963db8 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ # rubocop:disable LineLength source "https://rubygems.org" -ruby "2.6.3" +ruby "2.7.7" # Enforce git to transmitted via https. # workaround until bundler 2.0 is released. diff --git a/Gemfile.lock b/Gemfile.lock index c7c050cf..be75ae5a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -317,7 +317,7 @@ GEM faraday_middleware (>= 0.9) loofah (>= 2.0) sax-machine (>= 1.0) - ffi (1.9.25) + ffi (1.16.3) figaro (1.1.1) thor (~> 0.14) fission (0.5.0) @@ -613,7 +613,7 @@ GEM connection_pool (~> 2.2) netrc (0.11.0) nio4r (2.3.1) - nokogiri (1.10.1) + nokogiri (1.10.2) mini_portile2 (~> 2.4.0) notiffany (0.1.1) nenv (~> 0.1) @@ -1082,7 +1082,7 @@ DEPENDENCIES zonebie (~> 0.6.1) RUBY VERSION - ruby 2.6.3p62 + ruby 2.7.7p221 BUNDLED WITH 1.17.3 From 7dd4d88923b294ce1cb22c09c16c73bb78379ca2 Mon Sep 17 00:00:00 2001 From: Igor Arkhipov Date: Sat, 18 Nov 2023 14:11:03 +0100 Subject: [PATCH 2/6] Add profilers --- Gemfile | 2 ++ Gemfile.lock | 9 +++++++++ config/initializers/rack_mini_profiler.rb | 8 ++++++++ 3 files changed, 19 insertions(+) create mode 100644 config/initializers/rack_mini_profiler.rb diff --git a/Gemfile b/Gemfile index 98963db8..fc002f1d 100644 --- a/Gemfile +++ b/Gemfile @@ -72,6 +72,7 @@ gem "pundit", "~> 2.0" gem "pusher", "~> 1.3" gem "pusher-push-notifications", "~> 1.0" gem "rack-host-redirect", "~> 1.3" +gem "rack-mini-profiler", "~> 3.1", require: false gem "rack-timeout", "~> 0.5" gem "rails", "~> 5.1.6" gem "rails-assets-airbrake-js-client", "~> 1.5", source: "https://rails-assets.org" @@ -124,6 +125,7 @@ group :development, :test do gem "faker", git: "https://github.com/stympy/faker.git", branch: "master" gem "fix-db-schema-conflicts", github: "jakeonrails/fix-db-schema-conflicts", branch: "master" gem "memory_profiler", "~> 0.9" + gem 'meta_request', "~> 0.7" gem "parallel_tests", "~> 2.27" gem "pry-byebug", "~> 3.7" gem "rspec-rails", "~> 3.8" diff --git a/Gemfile.lock b/Gemfile.lock index be75ae5a..19a61db1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -592,6 +592,9 @@ GEM memoizable (0.4.2) thread_safe (~> 0.3, >= 0.3.1) memory_profiler (0.9.12) + meta_request (0.7.4) + rack-contrib (>= 1.1, < 3) + railties (>= 3.0.0, < 7.1) method_source (0.9.2) mime-types (3.2.2) mime-types-data (~> 3.2015) @@ -675,8 +678,12 @@ GEM pusher-signature (0.1.8) raabro (1.1.6) rack (2.0.6) + rack-contrib (2.4.0) + rack (< 4) rack-host-redirect (1.3.0) rack + rack-mini-profiler (3.1.1) + rack (>= 1.2.0) rack-protection (2.0.4) rack rack-proxy (0.6.5) @@ -1012,6 +1019,7 @@ DEPENDENCIES libhoney (~> 1.11) liquid (~> 4.0) memory_profiler (~> 0.9) + meta_request (~> 0.7) nakayoshi_fork nokogiri (~> 1.10) octokit (~> 4.13) @@ -1029,6 +1037,7 @@ DEPENDENCIES pusher (~> 1.3) pusher-push-notifications (~> 1.0) rack-host-redirect (~> 1.3) + rack-mini-profiler (~> 3.1) rack-timeout (~> 0.5) rails (~> 5.1.6) rails-assets-airbrake-js-client (~> 1.5)! diff --git a/config/initializers/rack_mini_profiler.rb b/config/initializers/rack_mini_profiler.rb new file mode 100644 index 00000000..14e63a30 --- /dev/null +++ b/config/initializers/rack_mini_profiler.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +if Rails.env.development? + require "rack-mini-profiler" + + # The initializer was required late, so initialize it manually. + Rack::MiniProfilerRails.initialize!(Rails.application) +end From 77feba08b3ae3f2f97ea168cb7cbbb58048e7110 Mon Sep 17 00:00:00 2001 From: Igor Arkhipov Date: Sat, 18 Nov 2023 15:30:33 +0100 Subject: [PATCH 3/6] Update skylight and add NewRelic --- Gemfile | 3 +- Gemfile.lock | 20 +- config/newrelic.yml | 824 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 838 insertions(+), 9 deletions(-) create mode 100644 config/newrelic.yml diff --git a/Gemfile b/Gemfile index fc002f1d..66c4d9e0 100644 --- a/Gemfile +++ b/Gemfile @@ -59,6 +59,7 @@ gem "jquery-rails", "~> 4.3" gem "kaminari", "~> 1.1" gem "libhoney", "~> 1.11" gem "liquid", "~> 4.0" +gem 'newrelic_rpm', "~> 9.6" gem "nokogiri", "~> 1.10" gem "octokit", "~> 4.13" gem "omniauth", "~> 1.9" @@ -90,7 +91,7 @@ gem "sdoc", "~> 1.0", group: :doc gem "serviceworker-rails", "~> 0.5" gem "share_meow_client", "~> 0.1" gem "sitemap_generator", "~> 6.0" -gem "skylight", "~> 3.1" +gem "skylight", "~> 4.3" gem "slack-notifier", "~> 2.3" gem "sprockets", "~> 3.7" gem "staccato", "~> 0.5" diff --git a/Gemfile.lock b/Gemfile.lock index 19a61db1..eee6d1ab 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -137,6 +137,7 @@ GEM descendants_tracker (~> 0.0.4) ice_nine (~> 0.11.0) thread_safe (~> 0.3, >= 0.3.1) + base64 (0.2.0) bcrypt (3.1.12) benchmark-ips (2.7.2) better_errors (2.5.0) @@ -212,7 +213,7 @@ GEM coffee-script-source execjs coffee-script-source (1.12.2) - concurrent-ruby (1.1.5) + concurrent-ruby (1.2.2) connection_pool (2.2.2) counter_culture (2.1.2) activerecord (>= 3.0.0) @@ -536,7 +537,7 @@ GEM mime-types (~> 3.0) multi_xml (>= 0.5.2) httpclient (2.8.3) - i18n (1.6.0) + i18n (1.14.1) concurrent-ruby (~> 1.0) ice_nine (0.11.2) inflecto (0.0.2) @@ -601,7 +602,7 @@ GEM mime-types-data (3.2018.0812) mini_mime (1.0.1) mini_portile2 (2.4.0) - minitest (5.11.3) + minitest (5.20.0) momentjs-rails (2.20.1) railties (>= 3.1) msgpack (1.2.4) @@ -615,6 +616,8 @@ GEM net-http-persistent (3.0.0) connection_pool (~> 2.2) netrc (0.11.0) + newrelic_rpm (9.6.0) + base64 nio4r (2.3.1) nokogiri (1.10.2) mini_portile2 (~> 2.4.0) @@ -850,9 +853,9 @@ GEM tilt (~> 2.0) sitemap_generator (6.0.2) builder (~> 3.0) - skylight (3.1.4) - skylight-core (= 3.1.4) - skylight-core (3.1.4) + skylight (4.3.2) + skylight-core (= 4.3.2) + skylight-core (4.3.2) activesupport (>= 4.2.0) slack-notifier (2.3.2) smart_properties (1.13.1) @@ -902,7 +905,7 @@ GEM multipart-post (~> 2.0) naught (~> 1.0) simple_oauth (~> 0.3.0) - tzinfo (1.2.5) + tzinfo (1.2.11) thread_safe (~> 0.1) uber (0.1.0) uglifier (4.1.20) @@ -1021,6 +1024,7 @@ DEPENDENCIES memory_profiler (~> 0.9) meta_request (~> 0.7) nakayoshi_fork + newrelic_rpm (~> 9.6) nokogiri (~> 1.10) octokit (~> 4.13) omniauth (~> 1.9) @@ -1066,7 +1070,7 @@ DEPENDENCIES simplecov (~> 0.16) sinatra (~> 2.0) sitemap_generator (~> 6.0) - skylight (~> 3.1) + skylight (~> 4.3) slack-notifier (~> 2.3) spring (~> 2.0) spring-commands-rspec (~> 1.0) diff --git a/config/newrelic.yml b/config/newrelic.yml new file mode 100644 index 00000000..b45f04f6 --- /dev/null +++ b/config/newrelic.yml @@ -0,0 +1,824 @@ +# +# 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 <%= Time.now.strftime('%B %d, %Y') %><%= ", for version #{@agent_version}" if @agent_version %> +#<%= "\n# #{generated_for_user}\n#" if generated_for_user %> +# 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_API_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 fork + + # To disable the agent regardless of other settings, uncomment the following: + # agent_enabled: false + + # Logging level for log/newrelic_agent.log; options are error, warn, info, or + # debug. + log_level: info + + # All of the following configuration options are optional. Review them, and + # uncomment or edit them if they appear relevant to your application needs. + + # An array of ActiveSupport custom event names to subscribe to and instrument. For + # example, + # - one.custom.event + # - another.event + # - a.third.event + # active_support_custom_events_names: [] + + # If true, enables capture of all HTTP request headers for all destinations. + # allow_all_headers: false + + # Your New Relic userKey. Required when using the New Relic REST API v2 to record + # deployments using the newrelic deployments command. + # api_key: "" + + # If true, enables log decoration and the collection of log events and metrics. + # application_logging.enabled: true + + # A hash with key/value pairs to add as custom attributes to all log events + # forwarded to New Relic. If sending using an environment variable, the value must + # be formatted like: "key1=value1,key2=value2" + # application_logging.forwarding.custom_attributes: {} + + # If true, the agent captures log records emitted by your application. + # application_logging.forwarding.enabled: true + + # Sets the minimum level a log event must have to be forwarded to New Relic. + # This is based on the integer values of Ruby's Logger::Severity constants: + # https://github.com/ruby/ruby/blob/master/lib/logger/severity.rb + # The intention is to forward logs with the level given to the configuration, as + # well as any logs with a higher level of severity. + # For example, setting this value to "debug" will forward all log events to New + # Relic. Setting this value to "error" will only forward log events with the + # levels "error", "fatal", and "unknown". + # Valid values (ordered lowest to highest): + # * "debug" + # * "info" + # * "warn" + # * "error" + # * "fatal" + # * "unknown" + # application_logging.forwarding.log_level: debug + + # Defines the maximum number of log records to buffer in memory at a time. + # application_logging.forwarding.max_samples_stored: 10000 + + # If true, the agent decorates logs with metadata to link to entities, hosts, + # traces, and spans. + # application_logging.local_decorating.enabled: false + + # If true, the agent captures metrics related to logging for your application. + # application_logging.metrics.enabled: true + + # If true, enables capture of attributes for all destinations. + # attributes.enabled: true + + # Prefix of attributes to exclude from all destinations. Allows * as wildcard at + # end. + # attributes.exclude: [] + + # Prefix of attributes to include in all destinations. Allows * as wildcard at + # end. + # attributes.include: [] + + # If true, enables an audit log which logs communications with the New Relic + # collector. + # audit_log.enabled: false + + # List of allowed endpoints to include in audit log. + # audit_log.endpoints: [".*"] + + # Specifies a path to the audit log file (including the filename). + # audit_log.path: log/newrelic_audit.log + + # Specify a list of constants that should prevent the agent from starting + # automatically. Separate individual constants with a comma ,. For example, + # "Rails::Console,UninstrumentedBackgroundJob". + # autostart.denylisted_constants: Rails::Command::ConsoleCommand,Rails::Command::CredentialsCommand,Rails::Command::Db::System::ChangeCommand,Rails::Command::DbConsoleCommand,Rails::Command::DestroyCommand,Rails::Command::DevCommand,Rails::Command::EncryptedCommand,Rails::Command::GenerateCommand,Rails::Command::InitializersCommand,Rails::Command::NotesCommand,Rails::Command::RoutesCommand,Rails::Command::SecretsCommand,Rails::Console,Rails::DBConsole + + # Defines a comma-delimited list of executables that the agent should not + # instrument. For example, "rake,my_ruby_script.rb". + # autostart.denylisted_executables: irb,rspec + + # Defines a comma-delimited list of Rake tasks that the agent should not + # instrument. For example, "assets:precompile,db:migrate". + # autostart.denylisted_rake_tasks: about,assets:clean,assets:clobber,assets:environment,assets:precompile,assets:precompile:all,db:create,db:drop,db:fixtures:load,db:migrate,db:migrate:status,db:rollback,db:schema:cache:clear,db:schema:cache:dump,db:schema:dump,db:schema:load,db:seed,db:setup,db:structure:dump,db:version,doc:app,log:clear,middleware,notes,notes:custom,rails:template,rails:update,routes,secret,spec,spec:features,spec:requests,spec:controllers,spec:helpers,spec:models,spec:views,spec:routing,spec:rcov,stats,test,test:all,test:all:db,test:recent,test:single,test:uncommitted,time:zones:all,tmp:clear,tmp:create,webpacker:compile + + # Backports the faster ActiveRecord connection lookup introduced in Rails 6, which + # improves agent performance when instrumenting ActiveRecord. Note that this + # setting may not be compatible with other gems that patch ActiveRecord. + # backport_fast_active_record_connection_lookup: false + + # If true, the agent captures attributes from browser monitoring. + # browser_monitoring.attributes.enabled: false + + # Prefix of attributes to exclude from browser monitoring. Allows * as wildcard at + # end. + # browser_monitoring.attributes.exclude: [] + + # Prefix of attributes to include in browser monitoring. Allows * as wildcard at + # end. + # browser_monitoring.attributes.include: [] + + # If true, enables auto-injection of the JavaScript header for page load timing + # (sometimes referred to as real user monitoring or RUM). + # browser_monitoring.auto_instrument: true + + # Manual override for the path to your local CA bundle. This CA bundle will be + # used to validate the SSL certificate presented by New Relic's data collection + # service. + # ca_bundle_path: nil + + # Enable or disable the capture of memcache keys from transaction traces. + # capture_memcache_keys: false + + # When true, the agent captures HTTP request parameters and attaches them to + # transaction traces, traced errors, and TransactionError events. + # When using the capture_params setting, the Ruby agent will not attempt to filter + # secret information. Recommendation: To filter secret information from request + # parameters, use the attributes.include setting instead. For more information, + # see the Ruby attribute examples. + # capture_params: false + + # If true, the agent will clear Tracer::State in Agent.drop_buffered_data. + # clear_transaction_state_after_fork: false + + # If true, the agent will report source code level metrics for traced methods. + # see: + # https://docs.newrelic.com/docs/apm/agents/ruby-agent/features/ruby-codestream-integration/ + # code_level_metrics.enabled: true + + # Path to newrelic.yml. If undefined, the agent checks the following directories + # (in order): + # * config/newrelic.yml + # * newrelic.yml + # * $HOME/.newrelic/newrelic.yml + # * $HOME/newrelic.yml + # config_path: newrelic.yml + + # If false, custom attributes will not be sent on events. + # custom_attributes.enabled: true + + # If true, the agent captures custom events. + # custom_insights_events.enabled: true + + # Specify a maximum number of custom events to buffer in memory at a time. + # custom_insights_events.max_samples_stored: 3000 + + # If false, the agent will not add database_name parameter to transaction or slow + # sql traces. + # datastore_tracer.database_name_reporting.enabled: true + + # If false, the agent will not report datastore instance metrics, nor add host or + # port_path_or_id parameters to transaction or slow SQL traces. + # datastore_tracer.instance_reporting.enabled: true + + # If true, disables Action Cable instrumentation. + # disable_action_cable_instrumentation: false + + # If true, disables Action Controller instrumentation. + # disable_action_controller: false + + # If true, disables Action Mailbox instrumentation. + # disable_action_mailbox: false + + # If true, disables Action Mailer instrumentation. + # disable_action_mailer: false + + # If true, disables Active Record instrumentation. + # disable_active_record_instrumentation: false + + # If true, disables instrumentation for Active Record 4+ + # disable_active_record_notifications: false + + # If true, disables Active Storage instrumentation. + # disable_active_storage: false + + # If true, disables Active Support instrumentation. + # disable_active_support: false + + # If true, disables Active Job instrumentation. + # disable_activejob: false + + # If true, the agent won't sample the CPU usage of the host process. + # disable_cpu_sampler: false + + # If true, the agent won't measure the depth of Delayed Job queues. + # disable_delayed_job_sampler: false + + # If true, disables the use of GC::Profiler to measure time spent in garbage + # collection + # disable_gc_profiler: false + + # If true, the agent won't sample the memory usage of the host process. + # disable_memory_sampler: false + + # If true, the agent won't wrap third-party middlewares in instrumentation + # (regardless of whether they are installed via Rack::Builder or Rails). + # When middleware instrumentation is disabled, if an application is using + # middleware that could alter the response code, the HTTP status code reported on + # the transaction may not reflect the altered value. + # disable_middleware_instrumentation: false + + # If true, disables agent middleware for Roda. This middleware is responsible for + # advanced feature support such as page load timing and error collection. + # disable_roda_auto_middleware: false + + # If true, disables the collection of sampler metrics. Sampler metrics are metrics + # that are not event-based (such as CPU time or memory usage). + # disable_samplers: false + + # If true, disables Sequel instrumentation. + # disable_sequel_instrumentation: false + + # If true, disables Sidekiq instrumentation. + # disable_sidekiq: false + + # If true, disables agent middleware for Sinatra. This middleware is responsible + # for advanced feature support such as cross application tracing, page load + # timing, and error collection. + # Cross application tracing is deprecated in favor of distributed tracing. + # Distributed tracing is on by default for Ruby agent versions 8.0.0 and above. + # Middlewares are not required to support distributed tracing. + # To continue using cross application tracing, update the following options in + # your newrelic.yml configuration file: + # ``yaml + # # newrelic.yml + # cross_application_tracer: + # enabled: true + # distributed_tracing: + # enabled: false + # `` + # disable_sinatra_auto_middleware: false + + # If true, disables view instrumentation. + # disable_view_instrumentation: false + + # If true, the agent won't sample performance measurements from the Ruby VM. + # disable_vm_sampler: false + + # Distributed tracing lets you see the path that a request takes through your + # distributed system. Enabling distributed tracing changes the behavior of some + # New Relic features, so carefully consult the transition guide before you enable + # this feature. + # distributed_tracing.enabled: true + + # If true, the agent captures Elasticsearch queries in transaction traces. + # elasticsearch.capture_queries: true + + # If true, the agent obfuscates Elasticsearch queries in transaction traces. + # elasticsearch.obfuscate_queries: true + + # If true, the agent captures attributes from error collection. + # error_collector.attributes.enabled: true + + # Prefix of attributes to exclude from error collection. Allows * as wildcard at + # end. + # error_collector.attributes.exclude: [] + + # Prefix of attributes to include in error collection. Allows * as wildcard at + # end. + # error_collector.attributes.include: [] + + # If true, the agent collects TransactionError events. + # error_collector.capture_events: true + + # If true, the agent captures traced errors and error count metrics. + # error_collector.enabled: true + + # A list of error classes that the agent should treat as expected. + # This option can't be set via environment variable. + # error_collector.expected_classes: [] + + # A map of error classes to a list of messages. When an error of one of the + # classes specified here occurs, if its error message contains one of the strings + # corresponding to it here, that error will be treated as expected. + # This option can't be set via environment variable. + # error_collector.expected_messages: {} + + # A comma separated list of status codes, possibly including ranges. Errors + # associated with these status codes, where applicable, will be treated as + # expected. + # error_collector.expected_status_codes: "" + + # A list of error classes that the agent should ignore. + # This option can't be set via environment variable. + # error_collector.ignore_classes: ["ActionController::RoutingError", "Sinatra::NotFound"] + + # A map of error classes to a list of messages. When an error of one of the + # classes specified here occurs, if its error message contains one of the strings + # corresponding to it here, that error will be ignored. + # This option can't be set via environment variable. + # error_collector.ignore_messages: {} + + # A comma separated list of status codes, possibly including ranges. Errors + # associated with these status codes, where applicable, will be ignored. + # error_collector.ignore_status_codes: "" + + # Defines the maximum number of frames in an error backtrace. Backtraces over this + # amount are truncated at the beginning and end. + # error_collector.max_backtrace_frames: 50 + + # Defines the maximum number of TransactionError events reported per harvest + # cycle. + # error_collector.max_event_samples_stored: 100 + + # Allows newrelic distributed tracing headers to be suppressed on outbound + # requests. + # exclude_newrelic_header: false + + # Forces the exit handler that sends all cached data to collector before shutting + # down to be installed regardless of detecting scenarios where it generally should + # not be. Known use-case for this option is where Sinatra is running as an + # embedded service within another framework and the agent is detecting the Sinatra + # app and skipping the at_exit handler as a result. Sinatra classically runs the + # entire application in an at_exit block and would otherwise misbehave if the + # agent's at_exit handler was also installed in those circumstances. Note: + # send_data_on_exit should also be set to true in tandem with this setting. + # force_install_exit_handler: false + + # Ordinarily the agent reports dyno names with a trailing dot and process ID (for + # example, worker.3). You can remove this trailing data by specifying the prefixes + # you want to report without trailing data (for example, worker). + # heroku.dyno_name_prefixes_to_shorten: ["scheduler", "run"] + + # If true, the agent uses Heroku dyno names as the hostname. + # heroku.use_dyno_names: true + + # If true, enables high security mode. Ensure you understand the implications of + # high security mode before enabling this setting. + # high_security: false + + # If true (the default), data sent to the trace observer is batched instead of + # sending each span individually. + # infinite_tracing.batching: true + + # Configure the compression level for data sent to the trace observer. + # May be one of: :none, :low, :medium, :high. + # Set the level to :none to disable compression. + # infinite_tracing.compression_level: high + + # Configures the hostname for the trace observer Host. When configured, enables + # tail-based sampling by sending all recorded spans to a trace observer for + # further sampling decisions, irrespective of any usual agent sampling decision. + # infinite_tracing.trace_observer.host: "" + + # Configures the TCP/IP port for the trace observer Host + # infinite_tracing.trace_observer.port: 443 + + # Controls auto-instrumentation of ActiveSupport::BroadcastLogger at start up. May + # be one of: auto, prepend, chain, disabled. Used in Rails versions >= 7.1. + # instrumentation.active_support_broadcast_logger: auto + + # Controls auto-instrumentation of ActiveSupport::Logger at start up. May be one + # of: auto, prepend, chain, disabled. Used in Rails versions below 7.1. + # instrumentation.active_support_logger: auto + + # Controls auto-instrumentation of Async::HTTP at start up. May be one of: auto, + # prepend, chain, disabled. + # instrumentation.async_http: auto + + # Controls auto-instrumentation of bunny at start-up. May be one of: auto, + # prepend, chain, disabled. + # instrumentation.bunny: auto + + # Controls auto-instrumentation of the concurrent-ruby library at start-up. May be + # one of: auto, prepend, chain, disabled. + # instrumentation.concurrent_ruby: auto + + # Controls auto-instrumentation of Curb at start-up. May be one of: auto, prepend, + # chain, disabled. + # instrumentation.curb: auto + + # Controls auto-instrumentation of Delayed Job at start-up. May be one of: auto, + # prepend, chain, disabled. + # instrumentation.delayed_job: auto + + # Controls auto-instrumentation of the elasticsearch library at start-up. May be + # one of: auto, prepend, chain, disabled. + # instrumentation.elasticsearch: auto + + # Controls auto-instrumentation of ethon at start up. May be one of + # [auto|prepend|chain|disabled] + # instrumentation.ethon: auto + + # Controls auto-instrumentation of Excon at start-up. May be one of: enabled, + # disabled. + # instrumentation.excon: enabled + + # Controls auto-instrumentation of the Fiber class at start-up. May be one of: + # auto, prepend, chain, disabled. + # instrumentation.fiber: auto + + # Controls auto-instrumentation of Grape at start-up. May be one of: auto, + # prepend, chain, disabled. + # instrumentation.grape: auto + + # Specifies a list of hostname patterns separated by commas that will match gRPC + # hostnames that traffic is to be ignored by New Relic for. New Relic's gRPC + # client instrumentation will ignore traffic streamed to a host matching any of + # these patterns, and New Relic's gRPC server instrumentation will ignore traffic + # for a server running on a host whose hostname matches any of these patterns. By + # default, no traffic is ignored when gRPC instrumentation is itself enabled. For + # example, "private.com$,exception.*" + # instrumentation.grpc.host_denylist: [] + + # Controls auto-instrumentation of gRPC clients at start-up. May be one of: auto, + # prepend, chain, disabled. + # instrumentation.grpc_client: auto + + # Controls auto-instrumentation of gRPC servers at start-up. May be one of: auto, + # prepend, chain, disabled. + # instrumentation.grpc_server: auto + + # Controls auto-instrumentation of HTTPClient at start-up. May be one of: auto, + # prepend, chain, disabled. + # instrumentation.httpclient: auto + + # Controls auto-instrumentation of http.rb gem at start-up. May be one of: auto, + # prepend, chain, disabled. + # instrumentation.httprb: auto + + # Controls auto-instrumentation of httpx at start up. May be one of + # [auto|prepend|chain|disabled] + # instrumentation.httpx: auto + + # Controls auto-instrumentation of Ruby standard library Logger at start-up. May + # be one of: auto, prepend, chain, disabled. + # instrumentation.logger: auto + + # Controls auto-instrumentation of dalli gem for Memcache at start-up. May be one + # of: auto, prepend, chain, disabled. + # instrumentation.memcache: auto + + # Controls auto-instrumentation of memcache-client gem for Memcache at start-up. + # May be one of: auto, prepend, chain, disabled. + # instrumentation.memcache_client: auto + + # Controls auto-instrumentation of memcached gem for Memcache at start-up. May be + # one of: auto, prepend, chain, disabled. + # instrumentation.memcached: auto + + # Controls auto-instrumentation of Mongo at start-up. May be one of: enabled, + # disabled. + # instrumentation.mongo: enabled + + # Controls auto-instrumentation of Net::HTTP at start-up. May be one of: auto, + # prepend, chain, disabled. + # instrumentation.net_http: auto + + # Controls auto-instrumentation of Puma::Rack. When enabled, the agent hooks into + # the to_app method in Puma::Rack::Builder to find gems to instrument during + # application startup. May be one of: auto, prepend, chain, disabled. + # instrumentation.puma_rack: auto + + # Controls auto-instrumentation of Puma::Rack::URLMap at start-up. May be one of: + # auto, prepend, chain, disabled. + # instrumentation.puma_rack_urlmap: auto + + # Controls auto-instrumentation of Rack. When enabled, the agent hooks into the + # to_app method in Rack::Builder to find gems to instrument during application + # startup. May be one of: auto, prepend, chain, disabled. + # instrumentation.rack: auto + + # Controls auto-instrumentation of Rack::URLMap at start-up. May be one of: auto, + # prepend, chain, disabled. + # instrumentation.rack_urlmap: auto + + # Controls auto-instrumentation of rake at start-up. May be one of: auto, prepend, + # chain, disabled. + # instrumentation.rake: auto + + # Controls auto-instrumentation of Redis at start-up. May be one of: auto, + # prepend, chain, disabled. + # instrumentation.redis: auto + + # Controls auto-instrumentation of resque at start-up. May be one of: auto, + # prepend, chain, disabled. + # instrumentation.resque: auto + + # Controls auto-instrumentation of Roda at start-up. May be one of: auto, prepend, + # chain, disabled. + # instrumentation.roda: auto + + # Controls auto-instrumentation of Sinatra at start-up. May be one of: auto, + # prepend, chain, disabled. + # instrumentation.sinatra: auto + + # Controls auto-instrumentation of Stripe at startup. May be one of: enabled, + # disabled. + # instrumentation.stripe: enabled + + # Controls auto-instrumentation of the Thread class at start-up to allow the agent + # to correctly nest spans inside of an asynchronous transaction. This does not + # enable the agent to automatically trace all threads created (see + # instrumentation.thread.tracing). May be one of: auto, prepend, chain, disabled. + # instrumentation.thread: auto + + # Controls auto-instrumentation of the Thread class at start-up to automatically + # add tracing to all Threads created in the application. + # instrumentation.thread.tracing: true + + # Controls auto-instrumentation of the Tilt template rendering library at + # start-up. May be one of: auto, prepend, chain, disabled. + # instrumentation.tilt: auto + + # Controls auto-instrumentation of Typhoeus at start-up. May be one of: auto, + # prepend, chain, disabled. + # instrumentation.typhoeus: auto + + # A dictionary of label names and values that will be applied to the data sent + # from this agent. May also be expressed as a semicolon-delimited ; string of + # colon-separated : pairs. For example, Server:One;Data Center:Primary. + # labels: "" + + # Defines a name for the log file. + # log_file_name: newrelic_agent.log + + # Defines a path to the agent log file, excluding the filename. + # log_file_path: log/ + + # Specifies a marshaller for transmitting data to the New Relic collector. + # Currently json is the only valid value for this setting. + # marshaller: json + + # If true, the agent will collect metadata about messages and attach them as + # segment parameters. + # message_tracer.segment_parameters.enabled: true + + # If true, the agent captures Mongo queries in transaction traces. + # mongo.capture_queries: true + + # If true, the agent obfuscates Mongo queries in transaction traces. + # mongo.obfuscate_queries: true + + # When true, the agent transmits data about your app to the New Relic collector. + # monitor_mode: true + + # If true, uses Module#prepend rather than alias_method for ActiveRecord + # instrumentation. + # prepend_active_record_instrumentation: false + + # Specify a custom host name for display in the New Relic UI. + # process_host.display_name: default hostname + + # Defines a host for communicating with the New Relic collector via a proxy + # server. + # proxy_host: nil + + # Defines a password for communicating with the New Relic collector via a proxy + # server. + # proxy_pass: nil + + # Defines a port for communicating with the New Relic collector via a proxy + # server. + # proxy_port: 8080 + + # Defines a user for communicating with the New Relic collector via a proxy + # server. + # proxy_user: nil + + # Timeout for waiting on connect to complete before a rake task + # rake.connect_timeout: 10 + + # Specify an Array of Rake tasks to automatically instrument. This configuration + # option converts the Array to a RegEx list. If you'd like to allow all tasks by + # default, use rake.tasks: [.+]. No rake tasks will be instrumented unless they're + # added to this list. For more information, visit the New Relic Rake + # Instrumentation docs. + # rake.tasks: [] + + # Define transactions you want the agent to ignore, by specifying a list of + # patterns matching the URI you want to ignore. For more detail, see the docs on + # ignoring specific transactions. + # rules.ignore_url_regexes: [] + + # Applies Language Agent Security Policy settings. + # security_policies_token: "" + + # If true, enables the exit handler that sends data to the New Relic collector + # before shutting down. + # send_data_on_exit: true + + # An array of strings that will collectively serve as a denylist for filtering + # which Sidekiq job arguments get reported to New Relic. To capture any Sidekiq + # arguments, 'job.sidekiq.args.*' must be added to the separate + # :'attributes.include' configuration option. Each string in this array will be + # turned into a regular expression via Regexp.new to permit advanced matching. For + # job argument hashes, if either a key or value matches the pair will be excluded. + # All matching job argument array elements and job argument scalars will be + # excluded. + # sidekiq.args.exclude: [] + + # An array of strings that will collectively serve as an allowlist for filtering + # which Sidekiq job arguments get reported to New Relic. To capture any Sidekiq + # arguments, 'job.sidekiq.args.*' must be added to the separate + # :'attributes.include' configuration option. Each string in this array will be + # turned into a regular expression via Regexp.new to permit advanced matching. For + # job argument hashes, if either a key or value matches the pair will be included. + # All matching job argument array elements and job argument scalars will be + # included. + # sidekiq.args.include: [] + + # If true, the agent collects slow SQL queries. + # slow_sql.enabled: true + + # If true, the agent collects explain plans in slow SQL queries. If this setting + # is omitted, the transaction_tracer.explain_enabled setting will be applied as + # the default setting for explain plans in slow SQL as well. + # slow_sql.explain_enabled: true + + # Specify a threshold in seconds. The agent collects slow SQL queries and explain + # plans that exceed this threshold. + # slow_sql.explain_threshold: 0.5 + + # Defines an obfuscation level for slow SQL queries. Valid options are obfuscated, + # raw, or none. + # slow_sql.record_sql: obfuscated + + # Generate a longer sql_id for slow SQL traces. sql_id is used for aggregation of + # similar queries. + # slow_sql.use_longer_sql_id: false + + # If true, the agent captures attributes on span events. + # span_events.attributes.enabled: true + + # Prefix of attributes to exclude from span events. Allows * as wildcard at end. + # span_events.attributes.exclude: [] + + # Prefix of attributes to include on span events. Allows * as wildcard at end. + # span_events.attributes.include: [] + + # If true, enables span event sampling. + # span_events.enabled: true + + # Defines the maximum number of span events reported from a single harvest. Any + # Integer between 1 and 10000 is valid. + # span_events.max_samples_stored: 2000 + + # Sets the maximum number of span events to buffer when streaming to the trace + # observer. + # span_events.queue_size: 10000 + + # Specify a list of exceptions you do not want the agent to strip when + # strip_exception_messages is true. Separate exceptions with a comma. For example, + # "ImportantException,PreserveMessageException". + # strip_exception_messages.allowed_classes: "" + + # If true, the agent strips messages from all exceptions except those in the + # allowlist. Enabled automatically in high security mode. + # strip_exception_messages.enabled: false + + # An array of strings to specify which keys and/or values inside a Stripe event's + # user_data hash should + # not be reported to New Relic. Each string in this array will be turned into a + # regular expression via + # Regexp.new to permit advanced matching. For each hash pair, if either the key or + # value is matched the + # pair will not be reported. By default, no user_data is reported, so this option + # should only be used if + # the stripe.user_data.include option is being used. + # stripe.user_data.exclude: [] + + # An array of strings to specify which keys inside a Stripe event's user_data hash + # should be reported + # to New Relic. Each string in this array will be turned into a regular expression + # via Regexp.new to + # permit advanced matching. Setting the value to ["."] will report all user_data. + # stripe.user_data.include: [] + + # When set to true, forces a synchronous connection to the New Relic collector + # during application startup. For very short-lived processes, this helps ensure + # the New Relic agent has time to report. + # sync_startup: false + + # If true, enables use of the thread profiler. + # thread_profiler.enabled: false + + # Defines the maximum number of seconds the agent should spend attempting to + # connect to the collector. + # timeout: 120 + + # If true, the agent captures attributes from transaction events. + # transaction_events.attributes.enabled: true + + # Prefix of attributes to exclude from transaction events. Allows * as wildcard at + # end. + # transaction_events.attributes.exclude: [] + + # Prefix of attributes to include in transaction events. Allows * as wildcard at + # end. + # transaction_events.attributes.include: [] + + # If true, enables transaction event sampling. + # transaction_events.enabled: true + + # Defines the maximum number of transaction events reported from a single harvest. + # transaction_events.max_samples_stored: 1200 + + # If true, the agent captures attributes on transaction segments. + # transaction_segments.attributes.enabled: true + + # Prefix of attributes to exclude from transaction segments. Allows * as wildcard + # at end. + # transaction_segments.attributes.exclude: [] + + # Prefix of attributes to include on transaction segments. Allows * as wildcard at + # end. + # transaction_segments.attributes.include: [] + + # If true, the agent captures attributes from transaction traces. + # transaction_tracer.attributes.enabled: true + + # Prefix of attributes to exclude from transaction traces. Allows * as wildcard at + # end. + # transaction_tracer.attributes.exclude: [] + + # Prefix of attributes to include in transaction traces. Allows * as wildcard at + # end. + # transaction_tracer.attributes.include: [] + + # If true, enables collection of transaction traces. + # transaction_tracer.enabled: true + + # If true, enables the collection of explain plans in transaction traces. This + # setting will also apply to explain plans in slow SQL traces if + # slow_sql.explain_enabled is not set separately. + # transaction_tracer.explain_enabled: true + + # Threshold (in seconds) above which the agent will collect explain plans. + # Relevant only when explain_enabled is true. + # transaction_tracer.explain_threshold: 0.5 + + # Maximum number of transaction trace nodes to record in a single transaction + # trace. + # transaction_tracer.limit_segments: 4000 + + # If true, the agent records Redis command arguments in transaction traces. + # transaction_tracer.record_redis_arguments: false + + # Obfuscation level for SQL queries reported in transaction trace nodes. + # By default, this is set to obfuscated, which strips out the numeric and string + # literals. + # - If you do not want the agent to capture query information, set this to none. + # - If you want the agent to capture all query information in its original form, + # set this to raw. + # - When you enable high security mode, this is automatically set to obfuscated. + # transaction_tracer.record_sql: obfuscated + + # Specify a threshold in seconds. The agent includes stack traces in transaction + # trace nodes when the stack trace duration exceeds this threshold. + # transaction_tracer.stack_trace_threshold: 0.5 + + # Specify a threshold in seconds. Transactions with a duration longer than this + # threshold are eligible for transaction traces. Specify a float value or the + # string apdex_f. + # transaction_tracer.transaction_threshold: 1.0 + + # If true, the agent automatically detects that it is running in an AWS + # environment. + # utilization.detect_aws: true + + # If true, the agent automatically detects that it is running in an Azure + # environment. + # utilization.detect_azure: true + + # If true, the agent automatically detects that it is running in Docker. + # utilization.detect_docker: true + + # If true, the agent automatically detects that it is running in an Google Cloud + # Platform environment. + # utilization.detect_gcp: true + + # If true, the agent automatically detects that it is running in Kubernetes. + # utilization.detect_kubernetes: true + + # If true, the agent automatically detects that it is running in a Pivotal Cloud + # Foundry environment. + # utilization.detect_pcf: true + +# 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: <%= app_name %> (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: <%= app_name %> (Staging) + +production: + <<: *default_settings From abbf2fb3da2144aa52cfe1ec0a8f888451494f13 Mon Sep 17 00:00:00 2001 From: Igor Arkhipov Date: Sat, 18 Nov 2023 22:54:34 +0100 Subject: [PATCH 4/6] Add prometheus and grafana --- Gemfile | 1 + Gemfile.lock | 4 + Procfile.dev | 1 + config/initializers/prometheus.rb | 6 + config/newrelic.yml | 4 +- prometheus/docker-compose.yml | 42 + .../provisioning/dashboards/dashboard.yml | 12 + .../dashboards/monitor_services.json | 3023 +++++++++++++++++ .../provisioning/datasources/datasource.yml | 11 + prometheus/prometheus.yml | 13 + 10 files changed, 3115 insertions(+), 2 deletions(-) create mode 100644 config/initializers/prometheus.rb create mode 100644 prometheus/docker-compose.yml create mode 100644 prometheus/grafana/provisioning/dashboards/dashboard.yml create mode 100644 prometheus/grafana/provisioning/dashboards/monitor_services.json create mode 100644 prometheus/grafana/provisioning/datasources/datasource.yml create mode 100644 prometheus/prometheus.yml diff --git a/Gemfile b/Gemfile index 66c4d9e0..8b542d1e 100644 --- a/Gemfile +++ b/Gemfile @@ -66,6 +66,7 @@ gem "omniauth", "~> 1.9" gem "omniauth-github", "~> 1.3" gem "omniauth-twitter", "~> 1.4" gem "pg", "~> 1.1" +gem "prometheus_exporter", "~> 2.0" gem "pry", "~> 0.12" gem "pry-rails", "~> 0.3" gem "puma", "~> 3.12" diff --git a/Gemfile.lock b/Gemfile.lock index eee6d1ab..1132b1dd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -657,6 +657,8 @@ GEM ast (~> 2.4.0) pg (1.1.4) powerpack (0.1.2) + prometheus_exporter (2.0.8) + webrick pry (0.12.2) coderay (~> 1.1.0) method_source (~> 0.9.0) @@ -942,6 +944,7 @@ GEM webpush (0.3.2) hkdf (~> 0.2) jwt + webrick (1.8.1) websocket-driver (0.6.5) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.3) @@ -1032,6 +1035,7 @@ DEPENDENCIES omniauth-twitter (~> 1.4) parallel_tests (~> 2.27) pg (~> 1.1) + prometheus_exporter (~> 2.0) pry (~> 0.12) pry-byebug (~> 3.7) pry-rails (~> 0.3) diff --git a/Procfile.dev b/Procfile.dev index f6093523..b1cd4045 100644 --- a/Procfile.dev +++ b/Procfile.dev @@ -1,3 +1,4 @@ web: bin/rails s -p 3000 webpacker: ./bin/webpack-dev-server job: bin/rake jobs:work +prometheus_exporter: bundle exec prometheus_exporter diff --git a/config/initializers/prometheus.rb b/config/initializers/prometheus.rb new file mode 100644 index 00000000..40e3a5b2 --- /dev/null +++ b/config/initializers/prometheus.rb @@ -0,0 +1,6 @@ +if Rails.env != "test" + require 'prometheus_exporter/middleware' + + # This reports stats per request like HTTP status and timings + Rails.application.middleware.unshift PrometheusExporter::Middleware +end diff --git a/config/newrelic.yml b/config/newrelic.yml index b45f04f6..c2382543 100644 --- a/config/newrelic.yml +++ b/config/newrelic.yml @@ -809,7 +809,7 @@ common: &default_settings # Required license key associated with your New Relic # If your application has other named environments, configure them here. development: <<: *default_settings - app_name: <%= app_name %> (Development) + app_name: DEV.to fork dev test: <<: *default_settings @@ -818,7 +818,7 @@ test: staging: <<: *default_settings - app_name: <%= app_name %> (Staging) + app_name: DEV.to fork staging production: <<: *default_settings diff --git a/prometheus/docker-compose.yml b/prometheus/docker-compose.yml new file mode 100644 index 00000000..7eb39649 --- /dev/null +++ b/prometheus/docker-compose.yml @@ -0,0 +1,42 @@ +version: '3' +services: + dockerhost: + image: qoomon/docker-host + cap_add: [ 'NET_ADMIN', 'NET_RAW' ] + mem_limit: 8M + restart: on-failure + prometheus: + depends_on: [ dockerhost ] + image: prom/prometheus:latest + volumes: + - ./prometheus.yml:/etc/prometheus/prometheus.yml + - prometheus_data:/prometheus + command: + - '--config.file=/etc/prometheus/prometheus.yml' + - '--storage.tsdb.path=/prometheus' + - '--web.console.libraries=/etc/prometheus/console_libraries' + - '--web.console.templates=/etc/prometheus/consoles' + - '--storage.tsdb.retention.time=48h' + - '--web.enable-lifecycle' + restart: unless-stopped + ports: + - '9090:9090' # localhost:9090 + labels: + org.label-schema.group: "monitoring" + grafana: + image: grafana/grafana:latest + environment: + - GF_SECURITY_ADMIN_USER=admin + - GF_SECURITY_ADMIN_PASSWORD=pass + depends_on: + - prometheus + ports: + - "3030:3000" # localhost:3030 dashboard, prometheus:9090 data source + volumes: + - grafana_data:/var/lib/grafana + - ./grafana/provisioning:/etc/grafana/provisioning + labels: + org.label-schema.group: "monitoring" +volumes: + prometheus_data: {} + grafana_data: {} diff --git a/prometheus/grafana/provisioning/dashboards/dashboard.yml b/prometheus/grafana/provisioning/dashboards/dashboard.yml new file mode 100644 index 00000000..4c387ae1 --- /dev/null +++ b/prometheus/grafana/provisioning/dashboards/dashboard.yml @@ -0,0 +1,12 @@ +apiVersion: 1 + +providers: + - name: 'Prometheus' + orgId: 1 + folder: '' + type: file + disableDeletion: false + editable: true + allowUiUpdates: true + options: + path: /etc/grafana/provisioning/dashboards diff --git a/prometheus/grafana/provisioning/dashboards/monitor_services.json b/prometheus/grafana/provisioning/dashboards/monitor_services.json new file mode 100644 index 00000000..ceac7dc9 --- /dev/null +++ b/prometheus/grafana/provisioning/dashboards/monitor_services.json @@ -0,0 +1,3023 @@ +{ + "id": null, + "title": "Monitor Services", + "tags": ["prometheus"], + "style": "dark", + "timezone": "browser", + "editable": true, + "hideControls": false, + "sharedCrosshair": true, + "panels": [ + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": "Prometheus", + "decimals": 1, + "editable": true, + "error": false, + "format": "s", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 0, + "y": 0 + }, + "hideTimeOverride": true, + "id": 1, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "s", + "postfixFontSize": "80%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "(time() - process_start_time_seconds{instance=\"localhost:9090\",job=\"prometheus\"})", + "interval": "10s", + "intervalFactor": 1, + "legendFormat": "", + "refId": "A", + "step": 10 + } + ], + "thresholds": "", + "timeFrom": "10s", + "timeShift": null, + "title": "Prometheus Uptime", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": "Prometheus", + "editable": true, + "error": false, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 12, + "y": 0 + }, + "hideTimeOverride": true, + "id": 3, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "prometheus_tsdb_head_chunks", + "interval": "10s", + "intervalFactor": 1, + "refId": "A", + "step": 10 + } + ], + "thresholds": "", + "timeFrom": "10s", + "timeShift": null, + "title": "In-Memory Chunks", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": "Prometheus", + "editable": true, + "error": false, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 18, + "y": 0 + }, + "hideTimeOverride": true, + "id": 2, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "prometheus_tsdb_head_series", + "interval": "10s", + "intervalFactor": 1, + "refId": "A", + "step": 10 + } + ], + "thresholds": "", + "timeFrom": "10s", + "timeShift": null, + "title": "In-Memory Series", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 24 + }, + "id": 22, + "panels": [], + "repeat": null, + "title": "Prometheus Metrics", + "type": "row" + }, + { + "aliasColors": { + "Max": "#e24d42", + "Open": "#508642" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 25 + }, + "id": 18, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "process_max_fds{job=\"prometheus\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Max", + "refId": "A" + }, + { + "expr": "process_open_fds{job=\"prometheus\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Open", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "File Descriptors", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Allocated bytes": "#7EB26D", + "Allocated bytes - 1m max": "#BF1B00", + "Allocated bytes - 1m min": "#BF1B00", + "Allocated bytes - 5m max": "#BF1B00", + "Allocated bytes - 5m min": "#BF1B00", + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833", + "RSS": "#447EBC" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": null, + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 25 + }, + "id": 58, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/-/", + "fill": 0 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "process_resident_memory_bytes{job=\"prometheus\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "RSS", + "metric": "process_resident_memory_bytes", + "refId": "B", + "step": 10 + }, + { + "expr": "prometheus_local_storage_target_heap_size_bytes{job=\"prometheus\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Target heap size", + "metric": "go_memstats_alloc_bytes", + "refId": "D", + "step": 10 + }, + { + "expr": "go_memstats_next_gc_bytes{job=\"prometheus\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Next GC", + "metric": "go_memstats_next_gc_bytes", + "refId": "C", + "step": 10 + }, + { + "expr": "go_memstats_alloc_bytes{job=\"prometheus\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Allocated", + "metric": "go_memstats_alloc_bytes", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Memory", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Allocated bytes": "#F9BA8F", + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833", + "RSS": "#890F02" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 25 + }, + "id": 60, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(go_memstats_alloc_bytes_total{job=\"prometheus\"}[1m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Allocated", + "metric": "go_memstats_alloc_bytes", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Allocations", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833", + "Time series": "#70dbed" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 32 + }, + "id": 20, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "prometheus_tsdb_head_series", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Time series", + "metric": "prometheus_local_storage_memory_series", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Head Time series", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 32 + }, + "id": 24, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "prometheus_tsdb_head_active_appenders", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Head Appenders", + "metric": "prometheus_local_storage_memory_series", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Head Active Appenders", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "samples/s": "#e5a8e2" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 32 + }, + "id": 26, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_tsdb_head_samples_appended_total[1m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Samples", + "metric": "prometheus_local_storage_ingested_samples_total", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Samples Appended", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": "", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833", + "To persist": "#9AC48A" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 39 + }, + "id": 28, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/Max.*/", + "fill": 0 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "prometheus_tsdb_head_chunks", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Chunks", + "metric": "prometheus_local_storage_memory_chunks", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Head Chunks", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 39 + }, + "id": 30, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_tsdb_head_chunks_created_total[1m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Created", + "metric": "prometheus_local_storage_chunk_ops_total", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Head Chunks Created", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833", + "Removed": "#e5ac0e" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 39 + }, + "id": 32, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_tsdb_head_chunks_removed_total[1m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Removed", + "metric": "prometheus_local_storage_chunk_ops_total", + "refId": "B", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Head Chunks Removed", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max": "#447ebc", + "Max chunks": "#052B51", + "Max to persist": "#3F6833", + "Min": "#447ebc", + "Now": "#7eb26d" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 46 + }, + "id": 34, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "Max", + "fillBelowTo": "Min", + "lines": false + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "prometheus_tsdb_head_min_time", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Min", + "metric": "prometheus_local_storage_series_chunks_persisted_count", + "refId": "A", + "step": 10 + }, + { + "expr": "time() * 1000", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "Now", + "refId": "C" + }, + { + "expr": "prometheus_tsdb_head_max_time", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Max", + "metric": "prometheus_local_storage_series_chunks_persisted_count", + "refId": "B", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Head Time Range", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "dateTimeAsIso", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 46 + }, + "id": 36, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_tsdb_head_gc_duration_seconds_sum[1m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "GC Time", + "metric": "prometheus_local_storage_series_chunks_persisted_count", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Head GC Time/s", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 46 + }, + "id": 38, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "Queue length", + "yaxis": 2 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "prometheus_tsdb_blocks_loaded", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Blocks Loaded", + "metric": "prometheus_local_storage_indexing_batch_sizes_sum", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Blocks Loaded", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Failed Compactions": "#bf1b00", + "Failed Reloads": "#bf1b00", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 53 + }, + "id": 40, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_tsdb_reloads_total[10m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Reloads", + "metric": "prometheus_local_storage_series_chunks_persisted_count", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "TSDB Reloads", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Failed Compactions": "#bf1b00", + "Max chunks": "#052B51", + "Max to persist": "#3F6833", + "{instance=\"demo.robustperception.io:9090\",job=\"prometheus\"}": "#bf1b00" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 53 + }, + "id": 44, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_tsdb_wal_corruptions_total[10m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "WAL Corruptions", + "metric": "prometheus_local_storage_series_chunks_persisted_count", + "refId": "A", + "step": 10 + }, + { + "expr": "rate(prometheus_tsdb_reloads_failures_total[10m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Reload Failures", + "metric": "prometheus_local_storage_series_chunks_persisted_count", + "refId": "B", + "step": 10 + }, + { + "expr": "rate(prometheus_tsdb_head_series_not_found[10m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Head Series Not Found", + "metric": "prometheus_local_storage_series_chunks_persisted_count", + "refId": "C", + "step": 10 + }, + { + "expr": "rate(prometheus_tsdb_compactions_failed_total[10m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Compaction Failures", + "metric": "prometheus_local_storage_series_chunks_persisted_count", + "refId": "D", + "step": 10 + }, + { + "expr": "rate(prometheus_tsdb_retention_cutoffs_failures_total[10m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Retention Cutoff Failures", + "metric": "prometheus_local_storage_series_chunks_persisted_count", + "refId": "E", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "TSDB Problems", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Failed Compactions": "#bf1b00", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 53 + }, + "id": 42, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_tsdb_wal_fsync_duration_seconds_sum[1m]) / rate(prometheus_tsdb_wal_fsync_duration_seconds_count[1m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Fsync Latency", + "metric": "prometheus_local_storage_series_chunks_persisted_count", + "refId": "A", + "step": 10 + }, + { + "expr": "rate(prometheus_tsdb_wal_truncate_duration_seconds_sum[1m]) / rate(prometheus_tsdb_wal_truncate_duration_seconds_count[1m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Truncate Latency", + "metric": "prometheus_local_storage_series_chunks_persisted_count", + "refId": "B", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "WAL Latencies", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Failed Compactions": "#bf1b00", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 60 + }, + "id": 46, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_tsdb_compactions_total[10m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Compactions", + "metric": "prometheus_local_storage_series_chunks_persisted_count", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Compactions", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 60 + }, + "id": 48, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_tsdb_compaction_duration_seconds_sum[10m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Compaction Time", + "metric": "prometheus_local_storage_series_chunks_persisted_count", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Compaction Time", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Allocated bytes": "#F9BA8F", + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833", + "RSS": "#890F02" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 60 + }, + "id": 50, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_tsdb_retention_cutoffs_total[10m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Retention Cutoffs", + "metric": "last", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Retention Cutoffs", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 67 + }, + "id": 56, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_tsdb_compaction_chunk_samples_sum[10m]) / rate(prometheus_tsdb_compaction_chunk_samples_count[10m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Chunk Samples", + "metric": "prometheus_local_storage_series_chunks_persisted_count", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "First Compaction, Avg Chunk Samples", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 67 + }, + "id": 10, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_target_interval_length_seconds_count[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{ interval }}", + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Target Scrapes", + "tooltip": { + "msResolution": true, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 67 + }, + "id": 11, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "prometheus_target_interval_length_seconds{quantile!=\"0.01\", quantile!=\"0.05\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{quantile}} ({{interval}})", + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Scrape Duration", + "tooltip": { + "msResolution": true, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 74 + }, + "id": 62, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_http_request_duration_seconds_count[1m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{handler}}", + "metric": "prometheus_local_storage_memory_chunkdescs", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "HTTP requests", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "reqps", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 74 + }, + "id": 64, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_http_request_duration_seconds_sum[1m]) / rate(prometheus_http_request_duration_seconds_count[1m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{handler}}", + "metric": "prometheus_local_storage_memory_chunkdescs", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "HTTP request latency", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 74 + }, + "id": 66, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_http_request_duration_seconds_sum[1m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{handler}}", + "metric": "prometheus_local_storage_memory_chunkdescs", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Time spent in HTTP requests", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "Time spent in each mode, per second", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 81 + }, + "id": 68, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_engine_query_duration_seconds_sum[1m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{slice}}", + "metric": "prometheus_local_storage_memory_chunkdescs", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Query engine timings", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 81 + }, + "id": 70, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_rule_group_iterations_missed_total[1m]) ", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Rule group missed", + "metric": "prometheus_local_storage_memory_chunkdescs", + "refId": "B", + "step": 10 + }, + { + "expr": "rate(prometheus_rule_evaluation_failures_total[1m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Rule evals failed", + "metric": "prometheus_local_storage_memory_chunkdescs", + "refId": "C", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Rule group evaulation problems", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 81 + }, + "id": 72, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_rule_group_duration_seconds_sum[1m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Rule evaluation duration", + "metric": "prometheus_local_storage_memory_chunkdescs", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Evaluation time of rule groups", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "time": { + "from": "now-15m", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] + }, + "templating": { + "list": [] + }, + "annotations": { + "list": [] + }, + "refresh": "10s", + "schemaVersion": 12, + "version": 22, + "links": [], + "gnetId": null +} diff --git a/prometheus/grafana/provisioning/datasources/datasource.yml b/prometheus/grafana/provisioning/datasources/datasource.yml new file mode 100644 index 00000000..bb37f13d --- /dev/null +++ b/prometheus/grafana/provisioning/datasources/datasource.yml @@ -0,0 +1,11 @@ +apiVersion: 1 + +datasources: + - name: Prometheus + type: prometheus + access: proxy + orgId: 1 + url: http://prometheus:9090 + basicAuth: false + isDefault: true + editable: true \ No newline at end of file diff --git a/prometheus/prometheus.yml b/prometheus/prometheus.yml new file mode 100644 index 00000000..cb40481a --- /dev/null +++ b/prometheus/prometheus.yml @@ -0,0 +1,13 @@ +global: + scrape_interval: 5s + external_labels: + monitor: 'local-monitor' +scrape_configs: + - job_name: 'prometheus' + honor_labels: true + static_configs: + - targets: ["localhost:9090"] + - job_name: 'devto' + honor_labels: true + static_configs: + - targets: ['dockerhost:9394'] From 3aac662c395966dc222095bd9054e2679a2eeeec Mon Sep 17 00:00:00 2001 From: Igor Arkhipov Date: Sun, 19 Nov 2023 02:22:23 +0100 Subject: [PATCH 5/6] Add local production ENV --- .eslintrc.yml | 16 ++++ Gemfile | 5 +- Procfile.localproduction | 4 + bin/startup | 7 +- bin/webpack-dev-server | 3 +- config/application.rb | 2 + config/environments/localproduction.rb | 107 ++++++++++++++++++++++ config/initializers/airbrake.rb | 2 +- config/initializers/carrierwave.rb | 2 +- config/initializers/honeycomb.rb | 2 +- config/initializers/rack_mini_profiler.rb | 3 +- config/newrelic.yml | 10 +- config/secrets.yml | 3 + config/webpack/localproduction.js | 3 + config/webpacker.yml | 15 +++ 15 files changed, 174 insertions(+), 10 deletions(-) create mode 100644 .eslintrc.yml create mode 100644 Procfile.localproduction create mode 100644 config/environments/localproduction.rb create mode 100644 config/webpack/localproduction.js diff --git a/.eslintrc.yml b/.eslintrc.yml new file mode 100644 index 00000000..30a021f9 --- /dev/null +++ b/.eslintrc.yml @@ -0,0 +1,16 @@ +env: + browser: true + node: true + es6: true +extends: 'eslint:recommended' +globals: + Atomics: readonly + SharedArrayBuffer: readonly +parserOptions: + ecmaFeatures: + jsx: true + ecmaVersion: 2018 + sourceType: module +plugins: + - react +rules: {} diff --git a/Gemfile b/Gemfile index 8b542d1e..dbcb23d9 100644 --- a/Gemfile +++ b/Gemfile @@ -106,6 +106,10 @@ gem "validate_url", "~> 1.0" gem "webpacker", "~> 3.5" gem "webpush", "~> 0.3" +group :localproduction, :development do + gem 'meta_request', "~> 0.7" +end + group :development do gem "better_errors", "~> 2.5" gem "binding_of_caller", "~> 0.8" @@ -127,7 +131,6 @@ group :development, :test do gem "faker", git: "https://github.com/stympy/faker.git", branch: "master" gem "fix-db-schema-conflicts", github: "jakeonrails/fix-db-schema-conflicts", branch: "master" gem "memory_profiler", "~> 0.9" - gem 'meta_request', "~> 0.7" gem "parallel_tests", "~> 2.27" gem "pry-byebug", "~> 3.7" gem "rspec-rails", "~> 3.8" diff --git a/Procfile.localproduction b/Procfile.localproduction new file mode 100644 index 00000000..b1cd4045 --- /dev/null +++ b/Procfile.localproduction @@ -0,0 +1,4 @@ +web: bin/rails s -p 3000 +webpacker: ./bin/webpack-dev-server +job: bin/rake jobs:work +prometheus_exporter: bundle exec prometheus_exporter diff --git a/bin/startup b/bin/startup index c7e84efb..feee8bff 100755 --- a/bin/startup +++ b/bin/startup @@ -12,5 +12,10 @@ end chdir APP_ROOT do puts "== STARTING UP ==" - system! "foreman start -f Procfile.dev" + if ENV['RAILS_ENV'] == 'localproduction' + system! "bundle exec rake assets:precompile" + system! "foreman start -f Procfile.localproduction" + else + system! "foreman start -f Procfile.dev" + end end diff --git a/bin/webpack-dev-server b/bin/webpack-dev-server index 63edc01e..c79289f9 100755 --- a/bin/webpack-dev-server +++ b/bin/webpack-dev-server @@ -16,7 +16,8 @@ CONFIG_FILE = File.join(APP_PATH, "config/webpacker.yml") NODE_MODULES_PATH = File.join(APP_PATH, "node_modules") WEBPACK_CONFIG = File.join(APP_PATH, "config/webpack/#{NODE_ENV}.js") -DEFAULT_LISTEN_HOST_ADDR = NODE_ENV == "development" ? "localhost" : "0.0.0.0" +LOCALHOST = NODE_ENV == "development" || NODE_ENV == "localproduction" +DEFAULT_LISTEN_HOST_ADDR = LOCALHOST ? "localhost" : "0.0.0.0" def args(key) index = ARGV.index(key) diff --git a/config/application.rb b/config/application.rb index 1b4c391f..780d9778 100644 --- a/config/application.rb +++ b/config/application.rb @@ -53,5 +53,7 @@ class Application < Rails::Application end ReservedWords.all = [ReservedWords::BASE_WORDS + top_routes].flatten.compact.uniq end + + config.skylight.environments << 'localproduction' if Rails.env.localproduction? end end diff --git a/config/environments/localproduction.rb b/config/environments/localproduction.rb new file mode 100644 index 00000000..85ad0642 --- /dev/null +++ b/config/environments/localproduction.rb @@ -0,0 +1,107 @@ +# rubocop:disable Metrics/BlockLength + +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 = false + + # Settings specified here will take precedence over those in config/application.rb. + + # Code is not reloaded between requests. + config.cache_classes = true + + # Eager load code on boot. This eager loads most of Rails and + # your application in memory, allowing both threaded web servers + # and those relying on copy on write to perform better. + # Rake tasks automatically ignore this option for performance. + config.eager_load = true + + # Full error reports are disabled and caching is turned on. + config.consider_all_requests_local = true + + # Enable/disable caching. By default caching is disabled. + config.action_controller.perform_caching = true + + config.cache_store = :memory_store + config.public_file_server.headers = { + "Cache-Control" => "public, max-age=172800" + } + + # Compress JavaScripts and CSS. + config.assets.js_compressor = Uglifier.new(harmony: true) + # config.assets.css_compressor = :sass + + # 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 = true + + # Supress logger output for asset requests. + config.assets.quiet = true + + # Do not fallback to assets pipeline if a precompiled asset is missed. + config.assets.compile = true + + # `config.assets.precompile` and `config.assets.version` + # have moved to config/initializers/assets.rb + + # Specifies the header that your server uses for sending files. + # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache + # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX + + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. + # config.force_ssl = true + + # Use the lowest log level to ensure availability of diagnostic information + # when problems arise. + config.log_level = :debug + + # Prepend all log lines with the following tags. + config.log_tags = [:request_id] + + # Use a different logger for distributed setups. + # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) + + # 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.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" + + config.public_file_server.enabled = true + + config.file_watcher = ActiveSupport::EventedFileUpdateChecker +end + +# rubocop:enable Metrics/BlockLength diff --git a/config/initializers/airbrake.rb b/config/initializers/airbrake.rb index 0a3fffc7..6dd37705 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 localproduction] # 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..627333c9 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.localproduction? || Rails.env.test? config.storage = :file else # config.fog_provider = 'fog-aws' diff --git a/config/initializers/honeycomb.rb b/config/initializers/honeycomb.rb index 0ac4787a..7f2a0859 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.localproduction? || Rails.env.test? Libhoney::NullClient.new else Libhoney::Client.new( diff --git a/config/initializers/rack_mini_profiler.rb b/config/initializers/rack_mini_profiler.rb index 14e63a30..c8349766 100644 --- a/config/initializers/rack_mini_profiler.rb +++ b/config/initializers/rack_mini_profiler.rb @@ -1,8 +1,9 @@ # frozen_string_literal: true -if Rails.env.development? +if Rails.env.development? || Rails.env.localproduction? require "rack-mini-profiler" # The initializer was required late, so initialize it manually. Rack::MiniProfilerRails.initialize!(Rails.application) + Rack::MiniProfiler.config.authorization_mode = :allow_all end diff --git a/config/newrelic.yml b/config/newrelic.yml index c2382543..394fc4c0 100644 --- a/config/newrelic.yml +++ b/config/newrelic.yml @@ -13,7 +13,7 @@ common: &default_settings # Required license key associated with your New Relic # 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 fork + app_name: 'DEV.to fork' # To disable the agent regardless of other settings, uncomment the following: # agent_enabled: false @@ -809,7 +809,11 @@ common: &default_settings # Required license key associated with your New Relic # If your application has other named environments, configure them here. development: <<: *default_settings - app_name: DEV.to fork dev + app_name: 'DEV.to fork dev' + +localproduction: + <<: *default_settings + app_name: 'DEV.to fork local prod' test: <<: *default_settings @@ -818,7 +822,7 @@ test: staging: <<: *default_settings - app_name: DEV.to fork staging + app_name: 'DEV.to fork staging' production: <<: *default_settings diff --git a/config/secrets.yml b/config/secrets.yml index 73f5e05c..0bf176bb 100644 --- a/config/secrets.yml +++ b/config/secrets.yml @@ -13,6 +13,9 @@ development: secret_key_base: a60edc976c913b19fd9fc8118936fbe1df2b07f4eecc5ad32f975e33cd4ea36b150c1ce933b681b90874a46568041629003dcbfc07238f7dca91741bcd1ec870 +localproduction: + secret_key_base: a60edc976c913b19fd9fc8118936fbe1df2b07f4eecc5ad32f975e33cd4ea36b150c1ce933b681b90874a46568041629003dcbfc07238f7dca91741bcd1ec870 + test: secret_key_base: 42dd7834039ebbea271af22635a6782ee15e519b14629c5276bfcdd4cff841e9926994784bb43a335a8f8c9739bb254ea3afe831839d4dc65654ec7516ec25f0 diff --git a/config/webpack/localproduction.js b/config/webpack/localproduction.js new file mode 100644 index 00000000..d7346478 --- /dev/null +++ b/config/webpack/localproduction.js @@ -0,0 +1,3 @@ +const environment = require('./environment'); + +module.exports = environment.toWebpackConfig(); diff --git a/config/webpacker.yml b/config/webpacker.yml index 2dfcd170..e74e921d 100644 --- a/config/webpacker.yml +++ b/config/webpacker.yml @@ -39,6 +39,21 @@ development: hmr: false https: false +localproduction: + <<: *default + + # Production depends on precompilation of packs prior to booting for performance. + compile: false + + dev_server: + host: localhost + port: 3035 + hmr: false + https: false + + # Cache manifest.json for performance + cache_manifest: true + test: <<: *default compile: true From 82d5aeafd45632529247e973f0c859421f1a3dac Mon Sep 17 00:00:00 2001 From: Igor Arkhipov Date: Sun, 19 Nov 2023 17:18:13 +0100 Subject: [PATCH 6/6] Optimise performance --- app/views/stories/_main_stories_feed.html.erb | 4 +- case-study.md | 105 +++ config/newrelic.yml | 826 +----------------- 3 files changed, 142 insertions(+), 793 deletions(-) create mode 100644 case-study.md 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..50825406 --- /dev/null +++ b/case-study.md @@ -0,0 +1,105 @@ +# Case-study оптимизации + +## Актуальная проблема + +Нужно оптимизировать механизм загрузки главной страницы проекта `StoriesController#index`. + +Я решил исправить эту проблему, оптимизировав рендеринг шаблонов. + +## Формирование метрики + +Для того, чтобы понимать, дают ли мои изменения положительный эффект на быстродействие программы я придумал использовать такую метрику: число секунд, требуемые для прохождения нагрузочного бенчмарка `ab` с 30 запросами к главной странице проекта. + +## Вникаем в детали системы, чтобы найти главные точки роста + +Для того, чтобы найти "точки роста" для оптимизации я воспользовался инструментами rack-mini-profiler, Prometheus, Grafana. + +Вот какие проблемы удалось найти и решить + +### Ваша находка №1 + +- какой отчёт показал главную точку роста + + - rack-mini-profiler: заметное время занимает рендеринг `partial`-ов `_single_story.html.erb`, делаются 11 вызовов. Rendering: stories/\_main_stories_feed.html.erb duration 3.3ms, with children 57.1ms + - ``` + Document Path: / + Document Length: 139178 bytes + + Concurrency Level: 1 + Time taken for tests: 2.373 seconds + Complete requests: 30 + Failed requests: 0 + Total transferred: 4206630 bytes + HTML transferred: 4175340 bytes + Requests per second: 12.64 [#/sec] (mean) + Time per request: 79.097 [ms] (mean) + Time per request: 79.097 [ms] (mean, across all concurrent requests) + Transfer rate: 1731.23 [Kbytes/sec] received + + Connection Times (ms) + min mean[+/-sd] median max + Connect: 0 0 0.2 0 1 + Processing: 69 79 18.0 74 164 + Waiting: 69 79 18.0 74 164 + Total: 69 79 18.2 75 166 + + Percentage of the requests served within a certain time (ms) + 50% 75 + 66% 77 + 75% 79 + 80% 80 + 90% 89 + 95% 111 + 98% 166 + 99% 166 + 100% 166 (longest request) + ``` + + Нашей точкой роста будет число вызовов отдельных шаблонов `articles/_single_story.html.erb` + +- как вы решили её оптимизировать + - Применил кэширование в шаблоне при работе с коллекциями stories. Гипотеза состоит в том, что в случае не частых обновлений постов на главной странице кэширование снизит время изначальной загрузки за счет переиспользования данных об уже имеющихся постах. +- как изменилась метрика + + - Метрика снизилась с 2.37 сек до 1.42 сек + + ``` + Document Path: / + Document Length: Variable + + Concurrency Level: 1 + Time taken for tests: 1.423 seconds + Complete requests: 30 + Failed requests: 0 + Total transferred: 4208029 bytes + HTML transferred: 4176759 bytes + Requests per second: 21.08 [#/sec] (mean) + Time per request: 47.445 [ms] (mean) + Time per request: 47.445 [ms] (mean, across all concurrent requests) + Transfer rate: 2887.15 [Kbytes/sec] received + + Connection Times (ms) + min mean[+/-sd] median max + Connect: 0 0 0.2 0 1 + Processing: 39 47 15.7 44 120 + Waiting: 39 47 15.7 43 119 + Total: 39 47 15.9 44 121 + + Percentage of the requests served within a certain time (ms) + 50% 44 + 66% 45 + 75% 45 + 80% 47 + 90% 49 + 95% 84 + 98% 121 + 99% 121 + 100% 121 (longest request) + ``` + +- как изменился отчёт профилировщика + - Rendering: stories/\_main_stories_feed.html.erb duration 10.1ms, with children 10.2ms + +## Результаты + +В результате проделанной оптимизации удалось ускорить время рендеринга главной страницы более чем в полтора раза. diff --git a/config/newrelic.yml b/config/newrelic.yml index 394fc4c0..9c2fe75a 100644 --- a/config/newrelic.yml +++ b/config/newrelic.yml @@ -1,819 +1,61 @@ # -# This file configures the New Relic agent. New Relic monitors Ruby, Java, +# 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 <%= Time.now.strftime('%B %d, %Y') %><%= ", for version #{@agent_version}" if @agent_version %> -#<%= "\n# #{generated_for_user}\n#" if generated_for_user %> +# +# 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. +common: &default_settings + # Required license key associated with your New Relic account. license_key: <%= ENV['NEW_RELIC_API_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 + # Relic. For more details, see https://docs.newrelic.com/docs/apm/new-relic-apm/maintenance/renaming-applications app_name: 'DEV.to fork' + 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; options are error, warn, info, or - # debug. + # Logging level for log/newrelic_agent.log log_level: info - # All of the following configuration options are optional. Review them, and - # uncomment or edit them if they appear relevant to your application needs. - - # An array of ActiveSupport custom event names to subscribe to and instrument. For - # example, - # - one.custom.event - # - another.event - # - a.third.event - # active_support_custom_events_names: [] - - # If true, enables capture of all HTTP request headers for all destinations. - # allow_all_headers: false - - # Your New Relic userKey. Required when using the New Relic REST API v2 to record - # deployments using the newrelic deployments command. - # api_key: "" - - # If true, enables log decoration and the collection of log events and metrics. - # application_logging.enabled: true - - # A hash with key/value pairs to add as custom attributes to all log events - # forwarded to New Relic. If sending using an environment variable, the value must - # be formatted like: "key1=value1,key2=value2" - # application_logging.forwarding.custom_attributes: {} - - # If true, the agent captures log records emitted by your application. - # application_logging.forwarding.enabled: true - - # Sets the minimum level a log event must have to be forwarded to New Relic. - # This is based on the integer values of Ruby's Logger::Severity constants: - # https://github.com/ruby/ruby/blob/master/lib/logger/severity.rb - # The intention is to forward logs with the level given to the configuration, as - # well as any logs with a higher level of severity. - # For example, setting this value to "debug" will forward all log events to New - # Relic. Setting this value to "error" will only forward log events with the - # levels "error", "fatal", and "unknown". - # Valid values (ordered lowest to highest): - # * "debug" - # * "info" - # * "warn" - # * "error" - # * "fatal" - # * "unknown" - # application_logging.forwarding.log_level: debug - - # Defines the maximum number of log records to buffer in memory at a time. - # application_logging.forwarding.max_samples_stored: 10000 - - # If true, the agent decorates logs with metadata to link to entities, hosts, - # traces, and spans. - # application_logging.local_decorating.enabled: false - - # If true, the agent captures metrics related to logging for your application. - # application_logging.metrics.enabled: true - - # If true, enables capture of attributes for all destinations. - # attributes.enabled: true - - # Prefix of attributes to exclude from all destinations. Allows * as wildcard at - # end. - # attributes.exclude: [] - - # Prefix of attributes to include in all destinations. Allows * as wildcard at - # end. - # attributes.include: [] - - # If true, enables an audit log which logs communications with the New Relic - # collector. - # audit_log.enabled: false - - # List of allowed endpoints to include in audit log. - # audit_log.endpoints: [".*"] - - # Specifies a path to the audit log file (including the filename). - # audit_log.path: log/newrelic_audit.log - - # Specify a list of constants that should prevent the agent from starting - # automatically. Separate individual constants with a comma ,. For example, - # "Rails::Console,UninstrumentedBackgroundJob". - # autostart.denylisted_constants: Rails::Command::ConsoleCommand,Rails::Command::CredentialsCommand,Rails::Command::Db::System::ChangeCommand,Rails::Command::DbConsoleCommand,Rails::Command::DestroyCommand,Rails::Command::DevCommand,Rails::Command::EncryptedCommand,Rails::Command::GenerateCommand,Rails::Command::InitializersCommand,Rails::Command::NotesCommand,Rails::Command::RoutesCommand,Rails::Command::SecretsCommand,Rails::Console,Rails::DBConsole - - # Defines a comma-delimited list of executables that the agent should not - # instrument. For example, "rake,my_ruby_script.rb". - # autostart.denylisted_executables: irb,rspec - - # Defines a comma-delimited list of Rake tasks that the agent should not - # instrument. For example, "assets:precompile,db:migrate". - # autostart.denylisted_rake_tasks: about,assets:clean,assets:clobber,assets:environment,assets:precompile,assets:precompile:all,db:create,db:drop,db:fixtures:load,db:migrate,db:migrate:status,db:rollback,db:schema:cache:clear,db:schema:cache:dump,db:schema:dump,db:schema:load,db:seed,db:setup,db:structure:dump,db:version,doc:app,log:clear,middleware,notes,notes:custom,rails:template,rails:update,routes,secret,spec,spec:features,spec:requests,spec:controllers,spec:helpers,spec:models,spec:views,spec:routing,spec:rcov,stats,test,test:all,test:all:db,test:recent,test:single,test:uncommitted,time:zones:all,tmp:clear,tmp:create,webpacker:compile - - # Backports the faster ActiveRecord connection lookup introduced in Rails 6, which - # improves agent performance when instrumenting ActiveRecord. Note that this - # setting may not be compatible with other gems that patch ActiveRecord. - # backport_fast_active_record_connection_lookup: false - - # If true, the agent captures attributes from browser monitoring. - # browser_monitoring.attributes.enabled: false - - # Prefix of attributes to exclude from browser monitoring. Allows * as wildcard at - # end. - # browser_monitoring.attributes.exclude: [] - - # Prefix of attributes to include in browser monitoring. Allows * as wildcard at - # end. - # browser_monitoring.attributes.include: [] - - # If true, enables auto-injection of the JavaScript header for page load timing - # (sometimes referred to as real user monitoring or RUM). - # browser_monitoring.auto_instrument: true - - # Manual override for the path to your local CA bundle. This CA bundle will be - # used to validate the SSL certificate presented by New Relic's data collection - # service. - # ca_bundle_path: nil - - # Enable or disable the capture of memcache keys from transaction traces. - # capture_memcache_keys: false - - # When true, the agent captures HTTP request parameters and attaches them to - # transaction traces, traced errors, and TransactionError events. - # When using the capture_params setting, the Ruby agent will not attempt to filter - # secret information. Recommendation: To filter secret information from request - # parameters, use the attributes.include setting instead. For more information, - # see the Ruby attribute examples. - # capture_params: false - - # If true, the agent will clear Tracer::State in Agent.drop_buffered_data. - # clear_transaction_state_after_fork: false - - # If true, the agent will report source code level metrics for traced methods. - # see: - # https://docs.newrelic.com/docs/apm/agents/ruby-agent/features/ruby-codestream-integration/ - # code_level_metrics.enabled: true - - # Path to newrelic.yml. If undefined, the agent checks the following directories - # (in order): - # * config/newrelic.yml - # * newrelic.yml - # * $HOME/.newrelic/newrelic.yml - # * $HOME/newrelic.yml - # config_path: newrelic.yml - - # If false, custom attributes will not be sent on events. - # custom_attributes.enabled: true - - # If true, the agent captures custom events. - # custom_insights_events.enabled: true - - # Specify a maximum number of custom events to buffer in memory at a time. - # custom_insights_events.max_samples_stored: 3000 - - # If false, the agent will not add database_name parameter to transaction or slow - # sql traces. - # datastore_tracer.database_name_reporting.enabled: true - - # If false, the agent will not report datastore instance metrics, nor add host or - # port_path_or_id parameters to transaction or slow SQL traces. - # datastore_tracer.instance_reporting.enabled: true - - # If true, disables Action Cable instrumentation. - # disable_action_cable_instrumentation: false - - # If true, disables Action Controller instrumentation. - # disable_action_controller: false - - # If true, disables Action Mailbox instrumentation. - # disable_action_mailbox: false - - # If true, disables Action Mailer instrumentation. - # disable_action_mailer: false - - # If true, disables Active Record instrumentation. - # disable_active_record_instrumentation: false - - # If true, disables instrumentation for Active Record 4+ - # disable_active_record_notifications: false - - # If true, disables Active Storage instrumentation. - # disable_active_storage: false - - # If true, disables Active Support instrumentation. - # disable_active_support: false - - # If true, disables Active Job instrumentation. - # disable_activejob: false - - # If true, the agent won't sample the CPU usage of the host process. - # disable_cpu_sampler: false - - # If true, the agent won't measure the depth of Delayed Job queues. - # disable_delayed_job_sampler: false - - # If true, disables the use of GC::Profiler to measure time spent in garbage - # collection - # disable_gc_profiler: false - - # If true, the agent won't sample the memory usage of the host process. - # disable_memory_sampler: false - - # If true, the agent won't wrap third-party middlewares in instrumentation - # (regardless of whether they are installed via Rack::Builder or Rails). - # When middleware instrumentation is disabled, if an application is using - # middleware that could alter the response code, the HTTP status code reported on - # the transaction may not reflect the altered value. - # disable_middleware_instrumentation: false - - # If true, disables agent middleware for Roda. This middleware is responsible for - # advanced feature support such as page load timing and error collection. - # disable_roda_auto_middleware: false - - # If true, disables the collection of sampler metrics. Sampler metrics are metrics - # that are not event-based (such as CPU time or memory usage). - # disable_samplers: false - - # If true, disables Sequel instrumentation. - # disable_sequel_instrumentation: false - - # If true, disables Sidekiq instrumentation. - # disable_sidekiq: false - - # If true, disables agent middleware for Sinatra. This middleware is responsible - # for advanced feature support such as cross application tracing, page load - # timing, and error collection. - # Cross application tracing is deprecated in favor of distributed tracing. - # Distributed tracing is on by default for Ruby agent versions 8.0.0 and above. - # Middlewares are not required to support distributed tracing. - # To continue using cross application tracing, update the following options in - # your newrelic.yml configuration file: - # ``yaml - # # newrelic.yml - # cross_application_tracer: - # enabled: true - # distributed_tracing: - # enabled: false - # `` - # disable_sinatra_auto_middleware: false - - # If true, disables view instrumentation. - # disable_view_instrumentation: false - - # If true, the agent won't sample performance measurements from the Ruby VM. - # disable_vm_sampler: false - - # Distributed tracing lets you see the path that a request takes through your - # distributed system. Enabling distributed tracing changes the behavior of some - # New Relic features, so carefully consult the transition guide before you enable - # this feature. - # distributed_tracing.enabled: true - - # If true, the agent captures Elasticsearch queries in transaction traces. - # elasticsearch.capture_queries: true - - # If true, the agent obfuscates Elasticsearch queries in transaction traces. - # elasticsearch.obfuscate_queries: true - - # If true, the agent captures attributes from error collection. - # error_collector.attributes.enabled: true - - # Prefix of attributes to exclude from error collection. Allows * as wildcard at - # end. - # error_collector.attributes.exclude: [] - - # Prefix of attributes to include in error collection. Allows * as wildcard at - # end. - # error_collector.attributes.include: [] - - # If true, the agent collects TransactionError events. - # error_collector.capture_events: true - - # If true, the agent captures traced errors and error count metrics. - # error_collector.enabled: true - - # A list of error classes that the agent should treat as expected. - # This option can't be set via environment variable. - # error_collector.expected_classes: [] - - # A map of error classes to a list of messages. When an error of one of the - # classes specified here occurs, if its error message contains one of the strings - # corresponding to it here, that error will be treated as expected. - # This option can't be set via environment variable. - # error_collector.expected_messages: {} - - # A comma separated list of status codes, possibly including ranges. Errors - # associated with these status codes, where applicable, will be treated as - # expected. - # error_collector.expected_status_codes: "" - - # A list of error classes that the agent should ignore. - # This option can't be set via environment variable. - # error_collector.ignore_classes: ["ActionController::RoutingError", "Sinatra::NotFound"] - - # A map of error classes to a list of messages. When an error of one of the - # classes specified here occurs, if its error message contains one of the strings - # corresponding to it here, that error will be ignored. - # This option can't be set via environment variable. - # error_collector.ignore_messages: {} - - # A comma separated list of status codes, possibly including ranges. Errors - # associated with these status codes, where applicable, will be ignored. - # error_collector.ignore_status_codes: "" - - # Defines the maximum number of frames in an error backtrace. Backtraces over this - # amount are truncated at the beginning and end. - # error_collector.max_backtrace_frames: 50 - - # Defines the maximum number of TransactionError events reported per harvest - # cycle. - # error_collector.max_event_samples_stored: 100 - - # Allows newrelic distributed tracing headers to be suppressed on outbound - # requests. - # exclude_newrelic_header: false - - # Forces the exit handler that sends all cached data to collector before shutting - # down to be installed regardless of detecting scenarios where it generally should - # not be. Known use-case for this option is where Sinatra is running as an - # embedded service within another framework and the agent is detecting the Sinatra - # app and skipping the at_exit handler as a result. Sinatra classically runs the - # entire application in an at_exit block and would otherwise misbehave if the - # agent's at_exit handler was also installed in those circumstances. Note: - # send_data_on_exit should also be set to true in tandem with this setting. - # force_install_exit_handler: false - - # Ordinarily the agent reports dyno names with a trailing dot and process ID (for - # example, worker.3). You can remove this trailing data by specifying the prefixes - # you want to report without trailing data (for example, worker). - # heroku.dyno_name_prefixes_to_shorten: ["scheduler", "run"] - - # If true, the agent uses Heroku dyno names as the hostname. - # heroku.use_dyno_names: true - - # If true, enables high security mode. Ensure you understand the implications of - # high security mode before enabling this setting. - # high_security: false - - # If true (the default), data sent to the trace observer is batched instead of - # sending each span individually. - # infinite_tracing.batching: true - - # Configure the compression level for data sent to the trace observer. - # May be one of: :none, :low, :medium, :high. - # Set the level to :none to disable compression. - # infinite_tracing.compression_level: high - - # Configures the hostname for the trace observer Host. When configured, enables - # tail-based sampling by sending all recorded spans to a trace observer for - # further sampling decisions, irrespective of any usual agent sampling decision. - # infinite_tracing.trace_observer.host: "" - - # Configures the TCP/IP port for the trace observer Host - # infinite_tracing.trace_observer.port: 443 - - # Controls auto-instrumentation of ActiveSupport::BroadcastLogger at start up. May - # be one of: auto, prepend, chain, disabled. Used in Rails versions >= 7.1. - # instrumentation.active_support_broadcast_logger: auto - - # Controls auto-instrumentation of ActiveSupport::Logger at start up. May be one - # of: auto, prepend, chain, disabled. Used in Rails versions below 7.1. - # instrumentation.active_support_logger: auto - - # Controls auto-instrumentation of Async::HTTP at start up. May be one of: auto, - # prepend, chain, disabled. - # instrumentation.async_http: auto - - # Controls auto-instrumentation of bunny at start-up. May be one of: auto, - # prepend, chain, disabled. - # instrumentation.bunny: auto - - # Controls auto-instrumentation of the concurrent-ruby library at start-up. May be - # one of: auto, prepend, chain, disabled. - # instrumentation.concurrent_ruby: auto - - # Controls auto-instrumentation of Curb at start-up. May be one of: auto, prepend, - # chain, disabled. - # instrumentation.curb: auto - - # Controls auto-instrumentation of Delayed Job at start-up. May be one of: auto, - # prepend, chain, disabled. - # instrumentation.delayed_job: auto - - # Controls auto-instrumentation of the elasticsearch library at start-up. May be - # one of: auto, prepend, chain, disabled. - # instrumentation.elasticsearch: auto - - # Controls auto-instrumentation of ethon at start up. May be one of - # [auto|prepend|chain|disabled] - # instrumentation.ethon: auto - - # Controls auto-instrumentation of Excon at start-up. May be one of: enabled, - # disabled. - # instrumentation.excon: enabled - - # Controls auto-instrumentation of the Fiber class at start-up. May be one of: - # auto, prepend, chain, disabled. - # instrumentation.fiber: auto - - # Controls auto-instrumentation of Grape at start-up. May be one of: auto, - # prepend, chain, disabled. - # instrumentation.grape: auto - - # Specifies a list of hostname patterns separated by commas that will match gRPC - # hostnames that traffic is to be ignored by New Relic for. New Relic's gRPC - # client instrumentation will ignore traffic streamed to a host matching any of - # these patterns, and New Relic's gRPC server instrumentation will ignore traffic - # for a server running on a host whose hostname matches any of these patterns. By - # default, no traffic is ignored when gRPC instrumentation is itself enabled. For - # example, "private.com$,exception.*" - # instrumentation.grpc.host_denylist: [] - - # Controls auto-instrumentation of gRPC clients at start-up. May be one of: auto, - # prepend, chain, disabled. - # instrumentation.grpc_client: auto - - # Controls auto-instrumentation of gRPC servers at start-up. May be one of: auto, - # prepend, chain, disabled. - # instrumentation.grpc_server: auto - - # Controls auto-instrumentation of HTTPClient at start-up. May be one of: auto, - # prepend, chain, disabled. - # instrumentation.httpclient: auto - - # Controls auto-instrumentation of http.rb gem at start-up. May be one of: auto, - # prepend, chain, disabled. - # instrumentation.httprb: auto - - # Controls auto-instrumentation of httpx at start up. May be one of - # [auto|prepend|chain|disabled] - # instrumentation.httpx: auto - - # Controls auto-instrumentation of Ruby standard library Logger at start-up. May - # be one of: auto, prepend, chain, disabled. - # instrumentation.logger: auto - - # Controls auto-instrumentation of dalli gem for Memcache at start-up. May be one - # of: auto, prepend, chain, disabled. - # instrumentation.memcache: auto - - # Controls auto-instrumentation of memcache-client gem for Memcache at start-up. - # May be one of: auto, prepend, chain, disabled. - # instrumentation.memcache_client: auto - - # Controls auto-instrumentation of memcached gem for Memcache at start-up. May be - # one of: auto, prepend, chain, disabled. - # instrumentation.memcached: auto - - # Controls auto-instrumentation of Mongo at start-up. May be one of: enabled, - # disabled. - # instrumentation.mongo: enabled - - # Controls auto-instrumentation of Net::HTTP at start-up. May be one of: auto, - # prepend, chain, disabled. - # instrumentation.net_http: auto - - # Controls auto-instrumentation of Puma::Rack. When enabled, the agent hooks into - # the to_app method in Puma::Rack::Builder to find gems to instrument during - # application startup. May be one of: auto, prepend, chain, disabled. - # instrumentation.puma_rack: auto - - # Controls auto-instrumentation of Puma::Rack::URLMap at start-up. May be one of: - # auto, prepend, chain, disabled. - # instrumentation.puma_rack_urlmap: auto - - # Controls auto-instrumentation of Rack. When enabled, the agent hooks into the - # to_app method in Rack::Builder to find gems to instrument during application - # startup. May be one of: auto, prepend, chain, disabled. - # instrumentation.rack: auto - - # Controls auto-instrumentation of Rack::URLMap at start-up. May be one of: auto, - # prepend, chain, disabled. - # instrumentation.rack_urlmap: auto - - # Controls auto-instrumentation of rake at start-up. May be one of: auto, prepend, - # chain, disabled. - # instrumentation.rake: auto - - # Controls auto-instrumentation of Redis at start-up. May be one of: auto, - # prepend, chain, disabled. - # instrumentation.redis: auto - - # Controls auto-instrumentation of resque at start-up. May be one of: auto, - # prepend, chain, disabled. - # instrumentation.resque: auto - - # Controls auto-instrumentation of Roda at start-up. May be one of: auto, prepend, - # chain, disabled. - # instrumentation.roda: auto - - # Controls auto-instrumentation of Sinatra at start-up. May be one of: auto, - # prepend, chain, disabled. - # instrumentation.sinatra: auto - - # Controls auto-instrumentation of Stripe at startup. May be one of: enabled, - # disabled. - # instrumentation.stripe: enabled - - # Controls auto-instrumentation of the Thread class at start-up to allow the agent - # to correctly nest spans inside of an asynchronous transaction. This does not - # enable the agent to automatically trace all threads created (see - # instrumentation.thread.tracing). May be one of: auto, prepend, chain, disabled. - # instrumentation.thread: auto - - # Controls auto-instrumentation of the Thread class at start-up to automatically - # add tracing to all Threads created in the application. - # instrumentation.thread.tracing: true - - # Controls auto-instrumentation of the Tilt template rendering library at - # start-up. May be one of: auto, prepend, chain, disabled. - # instrumentation.tilt: auto - - # Controls auto-instrumentation of Typhoeus at start-up. May be one of: auto, - # prepend, chain, disabled. - # instrumentation.typhoeus: auto - - # A dictionary of label names and values that will be applied to the data sent - # from this agent. May also be expressed as a semicolon-delimited ; string of - # colon-separated : pairs. For example, Server:One;Data Center:Primary. - # labels: "" - - # Defines a name for the log file. - # log_file_name: newrelic_agent.log - - # Defines a path to the agent log file, excluding the filename. - # log_file_path: log/ - - # Specifies a marshaller for transmitting data to the New Relic collector. - # Currently json is the only valid value for this setting. - # marshaller: json - - # If true, the agent will collect metadata about messages and attach them as - # segment parameters. - # message_tracer.segment_parameters.enabled: true - - # If true, the agent captures Mongo queries in transaction traces. - # mongo.capture_queries: true - - # If true, the agent obfuscates Mongo queries in transaction traces. - # mongo.obfuscate_queries: true - - # When true, the agent transmits data about your app to the New Relic collector. - # monitor_mode: true - - # If true, uses Module#prepend rather than alias_method for ActiveRecord - # instrumentation. - # prepend_active_record_instrumentation: false - - # Specify a custom host name for display in the New Relic UI. - # process_host.display_name: default hostname - - # Defines a host for communicating with the New Relic collector via a proxy - # server. - # proxy_host: nil - - # Defines a password for communicating with the New Relic collector via a proxy - # server. - # proxy_pass: nil - - # Defines a port for communicating with the New Relic collector via a proxy - # server. - # proxy_port: 8080 - - # Defines a user for communicating with the New Relic collector via a proxy - # server. - # proxy_user: nil - - # Timeout for waiting on connect to complete before a rake task - # rake.connect_timeout: 10 - - # Specify an Array of Rake tasks to automatically instrument. This configuration - # option converts the Array to a RegEx list. If you'd like to allow all tasks by - # default, use rake.tasks: [.+]. No rake tasks will be instrumented unless they're - # added to this list. For more information, visit the New Relic Rake - # Instrumentation docs. - # rake.tasks: [] - - # Define transactions you want the agent to ignore, by specifying a list of - # patterns matching the URI you want to ignore. For more detail, see the docs on - # ignoring specific transactions. - # rules.ignore_url_regexes: [] - - # Applies Language Agent Security Policy settings. - # security_policies_token: "" - - # If true, enables the exit handler that sends data to the New Relic collector - # before shutting down. - # send_data_on_exit: true - - # An array of strings that will collectively serve as a denylist for filtering - # which Sidekiq job arguments get reported to New Relic. To capture any Sidekiq - # arguments, 'job.sidekiq.args.*' must be added to the separate - # :'attributes.include' configuration option. Each string in this array will be - # turned into a regular expression via Regexp.new to permit advanced matching. For - # job argument hashes, if either a key or value matches the pair will be excluded. - # All matching job argument array elements and job argument scalars will be - # excluded. - # sidekiq.args.exclude: [] - - # An array of strings that will collectively serve as an allowlist for filtering - # which Sidekiq job arguments get reported to New Relic. To capture any Sidekiq - # arguments, 'job.sidekiq.args.*' must be added to the separate - # :'attributes.include' configuration option. Each string in this array will be - # turned into a regular expression via Regexp.new to permit advanced matching. For - # job argument hashes, if either a key or value matches the pair will be included. - # All matching job argument array elements and job argument scalars will be - # included. - # sidekiq.args.include: [] - - # If true, the agent collects slow SQL queries. - # slow_sql.enabled: true - - # If true, the agent collects explain plans in slow SQL queries. If this setting - # is omitted, the transaction_tracer.explain_enabled setting will be applied as - # the default setting for explain plans in slow SQL as well. - # slow_sql.explain_enabled: true - - # Specify a threshold in seconds. The agent collects slow SQL queries and explain - # plans that exceed this threshold. - # slow_sql.explain_threshold: 0.5 - - # Defines an obfuscation level for slow SQL queries. Valid options are obfuscated, - # raw, or none. - # slow_sql.record_sql: obfuscated - - # Generate a longer sql_id for slow SQL traces. sql_id is used for aggregation of - # similar queries. - # slow_sql.use_longer_sql_id: false - - # If true, the agent captures attributes on span events. - # span_events.attributes.enabled: true - - # Prefix of attributes to exclude from span events. Allows * as wildcard at end. - # span_events.attributes.exclude: [] - - # Prefix of attributes to include on span events. Allows * as wildcard at end. - # span_events.attributes.include: [] - - # If true, enables span event sampling. - # span_events.enabled: true - - # Defines the maximum number of span events reported from a single harvest. Any - # Integer between 1 and 10000 is valid. - # span_events.max_samples_stored: 2000 - - # Sets the maximum number of span events to buffer when streaming to the trace - # observer. - # span_events.queue_size: 10000 - - # Specify a list of exceptions you do not want the agent to strip when - # strip_exception_messages is true. Separate exceptions with a comma. For example, - # "ImportantException,PreserveMessageException". - # strip_exception_messages.allowed_classes: "" - - # If true, the agent strips messages from all exceptions except those in the - # allowlist. Enabled automatically in high security mode. - # strip_exception_messages.enabled: false - - # An array of strings to specify which keys and/or values inside a Stripe event's - # user_data hash should - # not be reported to New Relic. Each string in this array will be turned into a - # regular expression via - # Regexp.new to permit advanced matching. For each hash pair, if either the key or - # value is matched the - # pair will not be reported. By default, no user_data is reported, so this option - # should only be used if - # the stripe.user_data.include option is being used. - # stripe.user_data.exclude: [] - - # An array of strings to specify which keys inside a Stripe event's user_data hash - # should be reported - # to New Relic. Each string in this array will be turned into a regular expression - # via Regexp.new to - # permit advanced matching. Setting the value to ["."] will report all user_data. - # stripe.user_data.include: [] - - # When set to true, forces a synchronous connection to the New Relic collector - # during application startup. For very short-lived processes, this helps ensure - # the New Relic agent has time to report. - # sync_startup: false - - # If true, enables use of the thread profiler. - # thread_profiler.enabled: false - - # Defines the maximum number of seconds the agent should spend attempting to - # connect to the collector. - # timeout: 120 - - # If true, the agent captures attributes from transaction events. - # transaction_events.attributes.enabled: true - - # Prefix of attributes to exclude from transaction events. Allows * as wildcard at - # end. - # transaction_events.attributes.exclude: [] - - # Prefix of attributes to include in transaction events. Allows * as wildcard at - # end. - # transaction_events.attributes.include: [] - - # If true, enables transaction event sampling. - # transaction_events.enabled: true - - # Defines the maximum number of transaction events reported from a single harvest. - # transaction_events.max_samples_stored: 1200 - - # If true, the agent captures attributes on transaction segments. - # transaction_segments.attributes.enabled: true - - # Prefix of attributes to exclude from transaction segments. Allows * as wildcard - # at end. - # transaction_segments.attributes.exclude: [] - - # Prefix of attributes to include on transaction segments. Allows * as wildcard at - # end. - # transaction_segments.attributes.include: [] - - # If true, the agent captures attributes from transaction traces. - # transaction_tracer.attributes.enabled: true - - # Prefix of attributes to exclude from transaction traces. Allows * as wildcard at - # end. - # transaction_tracer.attributes.exclude: [] - - # Prefix of attributes to include in transaction traces. Allows * as wildcard at - # end. - # transaction_tracer.attributes.include: [] - - # If true, enables collection of transaction traces. - # transaction_tracer.enabled: true - - # If true, enables the collection of explain plans in transaction traces. This - # setting will also apply to explain plans in slow SQL traces if - # slow_sql.explain_enabled is not set separately. - # transaction_tracer.explain_enabled: true - - # Threshold (in seconds) above which the agent will collect explain plans. - # Relevant only when explain_enabled is true. - # transaction_tracer.explain_threshold: 0.5 - - # Maximum number of transaction trace nodes to record in a single transaction - # trace. - # transaction_tracer.limit_segments: 4000 - - # If true, the agent records Redis command arguments in transaction traces. - # transaction_tracer.record_redis_arguments: false - - # Obfuscation level for SQL queries reported in transaction trace nodes. - # By default, this is set to obfuscated, which strips out the numeric and string - # literals. - # - If you do not want the agent to capture query information, set this to none. - # - If you want the agent to capture all query information in its original form, - # set this to raw. - # - When you enable high security mode, this is automatically set to obfuscated. - # transaction_tracer.record_sql: obfuscated - - # Specify a threshold in seconds. The agent includes stack traces in transaction - # trace nodes when the stack trace duration exceeds this threshold. - # transaction_tracer.stack_trace_threshold: 0.5 - - # Specify a threshold in seconds. Transactions with a duration longer than this - # threshold are eligible for transaction traces. Specify a float value or the - # string apdex_f. - # transaction_tracer.transaction_threshold: 1.0 - - # If true, the agent automatically detects that it is running in an AWS - # environment. - # utilization.detect_aws: true - - # If true, the agent automatically detects that it is running in an Azure - # environment. - # utilization.detect_azure: true - - # If true, the agent automatically detects that it is running in Docker. - # utilization.detect_docker: true - - # If true, the agent automatically detects that it is running in an Google Cloud - # Platform environment. - # utilization.detect_gcp: true - - # If true, the agent automatically detects that it is running in Kubernetes. - # utilization.detect_kubernetes: true - - # If true, the agent automatically detects that it is running in a Pivotal Cloud - # Foundry environment. - # utilization.detect_pcf: true + 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 fork dev' + app_name: 'DEV.to fork (Development)' localproduction: <<: *default_settings - app_name: 'DEV.to fork local prod' + app_name: 'DEV.to fork (Local Production)' test: <<: *default_settings @@ -822,7 +64,7 @@ test: staging: <<: *default_settings - app_name: 'DEV.to fork staging' + app_name: 'DEV.to fork (Staging)' production: <<: *default_settings