module ScoutApm
This is different than other BackgroundJobIntegrations
and must be prepended manually in each job.
class MyWorker
prepend ScoutApm::BackgroundJobIntegrations::LegacySneakers def work(msg) ... end
end
Provide a background thread queue to do the processing of TrackedRequest
objects, to remove it from the hot-path of returning a web response
Used to run a given task every 60 seconds.
Valid Config
Options:
This list is complete, but some are old and unused, or for developers of scout_apm itself. See the documentation at docs.scoutapm.com for customer-focused documentation.
application_root - override the detected directory of the application collect_remote_ip - automatically capture user’s IP into a Trace’s Context
compress_payload - true/false to enable gzipping of payload data_file - override the default temporary storage location. Must be a location in a writable directory dev_trace - true or false. Enables always-on tracing in development environmen only direct_host - override the default “direct” host. The direct_host bypasses the ingestion pipeline and goes directly to the webserver, and is primarily used for features under development. enable_background_jobs - true or false host - configuration used in development hostname - override the default hostname detection. Default varies by environment - either system hostname, or PAAS hostname key - the account key with Scout APM. Found in Settings in the Web UI log_file_path - either a directory or “STDOUT”. log_level - DEBUG / INFO / WARN as usual max_traces - Internal: An experiment in trace quality, this requires a server-side setting as well. Setting this to a higher value will make your app server work harder for no benefit. monitor - true or false. False prevents any instrumentation from starting name - override the name reported to APM. This is the name that shows in the Web UI profile - turn on/off scoutprof (only applicable in Gem versions including scoutprof) proxy - an http proxy report_format - ‘json’ or ‘marshal’. Marshal is legacy and will be removed. scm_subdirectory - if the app root lives in source management in a subdirectory. E.g. #{SCM_ROOT}/src uri_reporting - ‘path’ or ‘full_path’ default is ‘full_path’, which reports URL params as well as the path. record_queue_time - true/false to enable recording of queuetime. remote_agent_host - Internal: What host to bind to, and also send messages to for remote. Default: 127.0.0.1. remote_agent_port - What port to bind the remote webserver to start_resque_server_instrument - Used in special situations with certain Resque installs timeline_traces - true/false to enable sending of of the timeline trace format. auto_instruments - true/false whether to install autoinstruments. Only installed if on a supported Ruby version. auto_instruments_ignore - An array of file names to exclude from autoinstruments (Ex: [‘application_controller’]). use_prepend - Whether to apply instrumentation using Module#Prepend instead
of Module#alias_method (Default: false)
alias_method_instruments - If ‘use_prepend` is true, continue to use Module#alias_method for
any instruments listed in this array. Default: []
prepend_instruments - If ‘use_prepend` is false, force using Module#prepend for any
instruments listed in this array. Default: []
ignore_endpoints - An array of endpoints to ignore. These are matched as regular expressions. (supercedes ‘ignore’) ignore_jobs - An array of job names to ignore. sample_rate - Rate to sample entire application. An integer between 0 and 100. 0 means no traces are sent, 100 means all traces are sent. sample_endpoints - An array of endpoints to sample. These are matched as regular expressions with individual sample rate of 0 to 100. sample_jobs - An array of job names with individual sample rate of 0 to 100. endpoint_sample_rate - Rate to sample all endpoints. An integer between 0 and 100. 0 means no traces are sent, 100 means all traces are sent. (supercedes ‘sample_rate’) job_sample_rate - Rate to sample all jobs. An integer between 0 and 100. 0 means no traces are sent, 100 means all traces are sent. (supercedes ‘sample_rate’)
Any of these config settings can be set with an environment variable prefixed by SCOUT_ and uppercasing the key: SCOUT_LOG_LEVEL for instance.
Encapsulates adding context to requests. Context
is stored via a simple Hash.
There are 2 types of context: User and Extra. For user-specific context, use @Context#add_user@. For misc context, use @Context#add@.
Note, this class must be Marshal Dumpable
Used to retrieve environment information for this application.
Public API for the Scout Error
Monitoring service
See-Also ScoutApm::Transaction
and ScoutApm::Tracing for APM related APIs
Holds onto exceptions, and moves them forward to shipping when appropriate
Encapsulates the management and checking of ignored exceptions. Allows using string matches on the class name, or arbitrary matching with a callback
Note, this class must be Marshal Dumpable
A stand-in for Store
. This one does not accumulate data, it just throws it away. Methods in here are the minimal set needed to fool calling objects
On first run, caches the regexes made by the ‘ignored` configuration setting
InstantReporting
is used when a specially flagged request hits the application. The agent traces the request regardless of its performance characteristics, and reports it immediately to our servers, for instant feedback. The request is detected in the ActionController instrumentation, and flagged in TrackedRequest
. The trace is prepped here, and handed off to a Reporter
for the actual POST.
Note, this instrument has the same logic in both Tracer
and Module Prepend versions. If you update, be sure you update in both spots.
The prepend version was added for Rails 6 support - ActiveRecord prepends on top of PartialRenderer#collection_with_template, which can (and does) cause infinite loops with our alias_method approach.
Even though Rails 6 forced us to use a prepend version, it is now used for all Rubies that support it.
Inserts a new middleware between each actual middleware in the application, so as to trace the time for each one.
Currently disabled by default due to the overhead of this approach (~10-15ms per request in practice). Instead, middleware as a whole are instrumented via the MiddlewareSummary class.
Turn this on with the configuration setting ‘detailed_middleware` set to true
Inserts a single middleware at the outer edge of the stack (the first middleware called, before passing to the rest of the stack) to trace the total time spent between all middlewares. This instrument does not attempt to allocate time to specific middlewares. (see MiddlewareDetailed)
XXX: Is this file used?
Records details about all runs of a given job.
Contains:
Queue Name Job Name Job Runtime - histogram Metrics collected during the run (Database, HTTP, View, etc)
Stores StoreReportingPeriod
objects in a per-process file before sending them to the server. Coordinates a single process to collect up all individual files, merge them, then send.
Each layaway file is named basedir/scout_#{timestamp}_#{pid}.data
Where timestamp is in the format: And PID is the process id of the running process
A single layaway file. See Layaway
for the management of the group of files.
This doesn’t cache the negative result when searching for a controller / job, so that we can ask again later after more of the request has occurred and correctly find it.
Queue/Critical (implicit count)
Job/PasswordResetJob Scope=Queue/Critical (implicit count, & total time) JobMetric/Latency 10 Scope=Job/PasswordResetJob ActiveRecord/User/find Scope=Job/PasswordResetJob ActiveRecord/Message/find Scope=Job/PasswordResetJob HTTP/request Scope=Job/PasswordResetJob View/message/text Scope=Job/PasswordResetJob ActiveRecord/Config/find Scope=View/message/text
Full metrics from this request. These get aggregated in Store
for the overview metrics, or stored permanently in a SlowTransaction
Some merging of metrics will happen here, so if a request calls the same ActiveRecord or View repeatedly, it’ll get merged.
Uses a different workflow than normal metrics. We ignore the shared walk of the layer tree, and instead wait until we’re sure we even want to do any work. Only then do we go realize all the SlowJobRecord
& metrics associated.
Pass in the "root" of the application you're using. - Rails.root - `Dir.pwd` Currently Valid opts: :force => Boolean - used to reinitialize logger. :log_file_path => String - explicitly set what file to send the log to :stdout => true - explicitly force the log to write to stdout (if set, ignore log_file_path) :stderr => true - explicitly force the log to write to stderr (if set, ignore log_file_path) :logger_class => Class or String - a class to use as the underlying logger. Defaults to Ruby's Logger. See notes :log_level => symbol, string, or integer - defaults to INFO level The :logger_class option - allows any class to be used as the underlying logger. Currently requires to respond to: - debug, info, warn, error, fatal in both string and block form. - debug?, info?, warn?, error?, fatal? - #level= with a number (0 = debug, 1 = info, 2= warn, 3=error, 4=fatal) - #formatter= that takes a Ruby Logger::Formatter class. This method must be here, but the value may be ignored
config.value(‘log_level’).downcase
Contains the meta information associated with a metric. Used to lookup Metrics in to Store’s metric_hash.
Stats that are associated with each instrumented method.
Classic hosting where you rent a server, then put your app on it. Used as fallback
Web Server bound to localhost that listens for remote agent reports. Forwards onto the router
Methods related to sending metrics to scoutapp.com.
Request manager handles the threadlocal variable that holds the current request. If there isn’t one, then create one
Attempts to keep the highest score.
Each item must respond to:
#call to get the storable item #name to get a unique identifier of the storable #score to get a numeric score, where higher is better
Serialize & deserialize commands from the APM server to the instrumented app
Serialize & deserialize commands from the APM server to the instrumented app
Serialize & deserialize data from the instrumented app up to the APM server
A lack of app server to integrate with. Null Object
pattern
Long running class that determines if, and in how much detail a potentially slow transaction should be recorded in
Stores one or more minute’s worth of Metrics/SlowTransactions in local ram. When informed to by the background worker, it pushes the in-ram metrics off to the layaway file for cross-process aggregation.
Provide a synchronous approach to recording TrackedRequests Doesn’t attempt to background the work, or do it elsewhere. It happens inline, in the caller thread right when record! is called
Provides helpers to wrap sections of code in instrumentation
The manual approach is to wrap your code in a call like:
`instrument("View", "users/index") do ... end`
The monkey-patching approach does this for you:
`instrument_method(:my_render, :type => "View", :name => "users/index)`
A TrackedRequest
is a stack of layers, where completed layers (go into, then come out of a layer) are forgotten as they finish. Layers are attached to their children as the process goes, building a tree structure within the layer objects. When the last layer is finished (hence the whole request is finished) it hands the root layer off to be recorded.
Given a call stack Array, grabs the first APP_FRAMES
callers within the application root directory.
Module for helping to deal with Source Code Management settings
Removes actual values from SQL. Used to both obfuscate the SQL and group similar queries in the UI.
Constants
- HistogramBin
- VERSION
Public Class Methods
Source
# File lib/scout_apm/auto_instrument/layer.rb, line 3 def self.AutoInstrument(name, backtrace) request = ScoutApm::RequestManager.lookup file_name, _ = backtrace.first.split(":", 2) begin layer = ScoutApm::Layer.new('AutoInstrument', name) layer.backtrace = backtrace layer.file_name = file_name request.start_layer(layer) started_layer = true result = yield ensure request.stop_layer if started_layer end return result end