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.