module Mmtrix::Agent
This module contains most of the public API methods for the Ruby Agent
.
For adding custom instrumentation to method invocations, see the docs for {Mmtrix::Agent::MethodTracer} and {Mmtrix::Agent::MethodTracer::ClassMethods}.
For information on how to trace transactions in non-Rack contexts, see {Mmtrix::Agent::Instrumentation::ControllerInstrumentation}.
For general documentation about the Ruby agent, see: docs.mmtrix.com/docs/agents/ruby-agent
@api public
This file is distributed under Mmtrix’s license terms.
Constants
- ADD_CUSTOM_ATTRIBUTES
- ADD_CUSTOM_PARAMETERS
- ADD_REQUEST_PARAMETERS
- SET_USER_ATTRIBUTES
- SUPPORTED_VERSIONS
- UNKNOWN_METRIC
placeholder name used when we cannot determine a transaction’s name
Attributes
Public Instance Methods
Cancel the collection of the current transaction in progress, if any. Only affects the transaction started on this thread once it has started and before it has completed.
This method has been deprecated in favor of ignore_transaction
, which does what people expect this method to do.
@api public @deprecated
# File lib/mmtrix/agent.rb, line 701 def abort_transaction! Transaction.abort_transaction! end
Add attributes to the transaction trace, Insights Transaction
event, and any traced errors recorded for the current transaction.
If Browser Monitoring is enabled, and the browser_monitoring.attributes.enabled configuration setting is true, these custom attributes will also be present in the script injected into the response body, making them available on Insights PageView events.
@api public
# File lib/mmtrix/agent.rb, line 506 def add_custom_attributes(params) #THREAD_LOCAL_ACCESS if params.is_a? Hash txn = Transaction.tl_current txn.add_custom_attributes(params) if txn else ::Mmtrix::Agent.logger.warn("Bad argument passed to #add_custom_attributes. Expected Hash but got #{params.class}") end end
Deprecated. Use add_custom_attributes
instead.
@deprecated @api public
# File lib/mmtrix/agent.rb, line 638 def add_custom_parameters(*args) Mmtrix::Agent::Deprecator.deprecate(ADD_CUSTOM_PARAMETERS, ADD_CUSTOM_ATTRIBUTES) add_custom_attributes(*args) end
Add instrumentation files to the agent. The argument should be a glob matching ruby scripts which will be executed at the time instrumentation is loaded. Since instrumentation is not loaded when the agent is not running it’s better to use this method to register instrumentation than just loading the files directly, although that probably also works.
@api public
# File lib/mmtrix/agent.rb, line 352 def add_instrumentation(file_pattern) Mmtrix::Control.instance.add_instrumentation file_pattern end
Deprecated. Use add_custom_attributes
instead.
@deprecated @api public
# File lib/mmtrix/agent.rb, line 648 def add_request_parameters(*args) Mmtrix::Agent::Deprecator.deprecate(ADD_REQUEST_PARAMETERS, ADD_CUSTOM_ATTRIBUTES) add_custom_attributes(*args) end
Register this method as a callback for processes that fork jobs.
If the master/parent connects to the agent prior to forking the agent in the forked process will use that agent_run. Otherwise the forked process will establish a new connection with the server.
Use this especially when you fork the process to run background jobs or other work. If you are doing this with a web dispatcher that forks worker processes then you will need to force the agent to reconnect, which it won’t do by default. Passenger and Rainbows and Unicorn are already handled, nothing special needed for them.
Options:
-
:force_reconnect => true
to force the spawned process to establish a new connection, such as when forking a long running process. The default is false–it will only connect to the server if the parent had not connected. -
:keep_retrying => false
if we try to initiate a new connection, this tells me to only try it once so this method returns quickly if there is some kind of latency with the server.
@api public
# File lib/mmtrix/agent.rb, line 320 def after_fork(options={}) agent.after_fork(options) if agent end
This method returns a string suitable for inclusion in a page - known as ‘manual instrumentation’ for Real User Monitoring. Can return either a script tag with associated javascript, or in the case of disabled Real User Monitoring, an empty string
This is the header string - it should be placed as high in the page as is reasonably possible - that is, before any style or javascript inclusions, but after any header-related meta tags
In previous agents there was a corresponding footer required, but all the work is now done by this single method.
@api public
# File lib/mmtrix/agent.rb, line 608 def browser_timing_header return "" unless agent agent.javascript_instrumentor.browser_timing_header end
Yield to the block without collecting any metrics or traces in any of the subsequent calls. If executed recursively, will keep track of the first entry point and turn on tracing again after leaving that block. This uses the thread local TransactionState
.
@api public
# File lib/mmtrix/agent.rb, line 426 def disable_all_tracing return yield unless agent begin agent.push_trace_execution_flag(false) yield ensure agent.pop_trace_execution_flag end end
This method sets the state of sql recording in the transaction sampler feature. Within the given block, no sql will be recorded
usage:
Mmtrix::Agent.disable_sql_recording do ... end
@api public
# File lib/mmtrix/agent.rb, line 464 def disable_sql_recording return yield unless agent state = agent.set_record_sql(false) begin yield ensure agent.set_record_sql(state) end end
This method disables the recording of transaction traces in the given block. See also disable_all_tracing
@api public
# File lib/mmtrix/agent.rb, line 442 def disable_transaction_tracing return yield unless agent state = agent.set_record_tt(false) begin yield ensure agent.set_record_tt(state) end end
Clear out any data the agent has buffered but has not yet transmitted to the collector.
@api public
# File lib/mmtrix/agent.rb, line 339 def drop_buffered_data agent.drop_buffered_data if agent end
Get or create a statistics gatherer that will aggregate numerical data under a metric name.
metric_name
should follow a slash separated path convention. Application specific metrics should begin with “Custom/”.
Return a Mmtrix::Agent::Stats
that accepts data via calls to add_data_point(value).
This method is deprecated in favor of record_metric
and increment_metric
, and is not thread-safe.
@api public @deprecated
# File lib/mmtrix/agent.rb, line 678 def get_stats(metric_name, use_scope=false) return unless agent agent.stats_engine.get_stats(metric_name, use_scope) end
Get the name of the current running transaction. This is useful if you want to modify the default name.
@api public
# File lib/mmtrix/agent.rb, line 551 def get_transaction_name #THREAD_LOCAL_ACCESS txn = Transaction.tl_current if txn namer = Instrumentation::ControllerInstrumentation::TransactionNamer txn.best_name.sub(Regexp.new("\\A#{Regexp.escape(namer.prefix_for_category(txn))}"), '') end end
This method disables the recording of Apdex metrics in the current transaction.
@api public
# File lib/mmtrix/agent.rb, line 404 def ignore_apdex txn = Mmtrix::Agent::Transaction.tl_current txn.ignore_apdex! if txn end
This method disables browser monitoring javascript injection in the current transaction.
@api public
# File lib/mmtrix/agent.rb, line 414 def ignore_enduser txn = Mmtrix::Agent::Transaction.tl_current txn.ignore_enduser! if txn end
Set a filter to be applied to errors that the Ruby Agent
will track. The block should evalute to the exception to track (which could be different from the original exception) or nil to ignore this exception.
The block is yielded to with the exception to filter.
Return the new block or the existing filter Proc if no block is passed.
@api public
# File lib/mmtrix/agent.rb, line 205 def ignore_error_filter(&block) if block Mmtrix::Agent::ErrorCollector.ignore_error_filter = block else Mmtrix::Agent::ErrorCollector.ignore_error_filter end end
This method disables the recording of the current transaction. No metrics, traced errors, transaction traces, Insights events, slow SQL traces, or RUM injection will happen for this transaction.
@api public
# File lib/mmtrix/agent.rb, line 394 def ignore_transaction txn = Mmtrix::Agent::Transaction.tl_current txn.ignore! if txn end
Increment a simple counter metric.
metric_name
should follow a slash separated path convention. Application specific metrics should begin with “Custom/”.
This method is safe to use from any thread.
@api public
# File lib/mmtrix/agent.rb, line 182 def increment_metric(metric_name, amount=1) #THREAD_LOCAL_ACCESS return unless agent agent.stats_engine.tl_record_unscoped_metrics(metric_name) do |stats| stats.increment_count(amount) end end
Primary interface to logging is fronted by this accessor Access via ::Mmtrix::Agent.logger
# File lib/mmtrix/agent.rb, line 118 def logger @logger || StartupLogger.instance end
# File lib/mmtrix/agent.rb, line 122 def logger=(log) @logger = log end
Call this to manually start the Agent
in situations where the Agent
does not auto-start.
When the app environment loads, so does the Agent
. However, the Agent
will only connect to the service if a web front-end is found. If you want to selectively monitor ruby processes that don’t use web plugins, then call this method in your code and the Agent
will fire up and start reporting to the service.
Options are passed in as overrides for values in the mmtrix.yml, such as app_name. In addition, the option log
will take a logger that will be used instead of the standard file logger. The setting for the mmtrix.yml section to use (ie, RAILS_ENV) can be overridden with an :env argument.
@api public
# File lib/mmtrix/agent.rb, line 287 def manual_start(options={}) raise "Options must be a hash" unless Hash === options if options[:start_channel_listener] Mmtrix::Agent::PipeChannelManager.listener.start end Mmtrix::Control.instance.init_plugin({ :agent_enabled => true, :sync_startup => true }.merge(options)) end
Notice the error with the given available options:
-
:uri
=> Request path, minus request params or query string -
:metric
=> The metric name associated with the transaction -
:custom_params
=> Custom parameters
Previous versions of the agent allowed passing :request_params but those are now ignored. Associate the request with the enclosing transaction, or record additional information as custom attributes. Anything left over is treated as custom params.
@api public
# File lib/mmtrix/agent.rb, line 226 def notice_error(exception, options={}) Transaction.notice_error(exception, options) nil # don't return a noticed error datastructure. it can only hurt. end
Fire an event of the specified event_type
, passing it an the given args
to any registered handlers.
# File lib/mmtrix/agent.rb, line 586 def notify(event_type, *args) agent.events.notify( event_type, *args ) rescue Mmtrix::Agent.logger.debug "Ignoring exception during %p event notification" % [event_type] end
Record a custom event to be sent to Mmtrix
Insights. The recorded event will be buffered in memory until the next time the agent sends data to Mmtrix’s servers.
If you want to be able to tie the information recorded via this call back to the web request or background job that it happened in, you may want to instead use the add_custom_attributes
API call to attach attributes to the Transaction
event that will automatically be generated for the request.
A timestamp will be automatically added to the recorded event when this method is called.
@param [Symbol or String] event_type The name of the event type to record. Event
types must consist of only alphanumeric characters, '_', ':', or ' '.
@param [Hash] event_attrs A Hash of attributes to be attached to the event.
Keys should be strings or symbols, and values may be strings, symbols, numeric values or booleans.
@api public
# File lib/mmtrix/agent.rb, line 259 def record_custom_event(event_type, event_attrs) if agent && Mmtrix::Agent.config[:'custom_insights_events.enabled'] agent.custom_event_aggregator.record(event_type, event_attrs) end nil end
Record a value for the given metric name.
This method should be used to record event-based metrics such as method calls that are associated with a specific duration or magnitude.
metric_name
should follow a slash separated path convention. Application specific metrics should begin with “Custom/”.
value
should be either a single Numeric value representing the duration/ magnitude of the event being recorded, or a Hash containing :count, :total, :min, :max, and :sum_of_squares keys. The latter form is useful for recording pre-aggregated metrics collected externally.
This method is safe to use from any thread.
@api public
# File lib/mmtrix/agent.rb, line 157 def record_metric(metric_name, value) #THREAD_LOCAL_ACCESS return unless agent if value.is_a?(Hash) stats = Mmtrix::Agent::Stats.new stats.call_count = value[:count] if value[:count] stats.total_call_time = value[:total] if value[:total] stats.total_exclusive_time = value[:total] if value[:total] stats.min_call_time = value[:min] if value[:min] stats.max_call_time = value[:max] if value[:max] stats.sum_of_squares = value[:sum_of_squares] if value[:sum_of_squares] value = stats end agent.stats_engine.tl_record_unscoped_metrics(metric_name, value) end
Remove after 5/9/15
# File lib/mmtrix/agent.rb, line 706 def record_transaction(*args) Mmtrix::Agent.logger.warn('This method has been deprecated, please see https://docs.mmtrix.com/docs/ruby/ruby-agent-api for current API documentation.') end
Require agent testing helper methods
@api public
# File lib/mmtrix/agent.rb, line 359 def require_test_helper path = File.join(__FILE__, '..', '..', '..', 'test', 'agent_helper') require File.expand_path(path) end
For testing Important that we don’t change the instance or we orphan callbacks
# File lib/mmtrix/agent.rb, line 135 def reset_config @config.reset_to_defaults end
Deprecated in favor of drop_buffered_data
@api public @deprecated
# File lib/mmtrix/agent.rb, line 689 def reset_stats; drop_buffered_data; end
This method sets the block sent to this method as a sql obfuscator. The block will be called with a single String SQL statement to obfuscate. The method must return the obfuscated String SQL. If chaining of obfuscators is required, use type = :before or :after
type = :before, :replace, :after
Example:
Mmtrix::Agent.set_sql_obfuscator(:replace) do |sql| my_obfuscator(sql) end
@api public
# File lib/mmtrix/agent.rb, line 380 def set_sql_obfuscator(type = :replace, &block) Mmtrix::Agent::Database.set_sql_obfuscator(type, &block) end
Set the name of the current running transaction. The agent will apply a reasonable default based on framework routing, but in cases where this is insufficient, this can be used to manually control the name of the transaction. The category of transaction can be specified via the :category
option:
-
:category => :controller
indicates that this is a controller action and will appear with all the other actions. -
:category => :task
indicates that this is a background task and will show up inMmtrix
with other background tasks instead of in the controllers list -
:category => :middleware
if you are instrumenting a rack middleware call. The:name
is optional, useful if you have more than one potential transaction in the call. -
:category => :uri
indicates that this is a web transaction whose name is a normalized URI, where ‘normalized’ means the URI does not have any elements with data in them such as in many REST URIs.
The default category is the same as the running transaction.
@api public
# File lib/mmtrix/agent.rb, line 542 def set_transaction_name(name, options={}) Transaction.set_overriding_transaction_name(name, options[:category]) end
Deprecated. Use add_custom_attributes
instead.
@deprecated @api public
# File lib/mmtrix/agent.rb, line 658 def set_user_attributes(*args) Mmtrix::Agent::Deprecator.deprecate(SET_USER_ATTRIBUTES, ADD_CUSTOM_ATTRIBUTES) add_custom_attributes(*args) end
Shutdown the agent. Call this before exiting. Sends any queued data and kills the background thread.
@param options [Hash] Unused options Hash, for back compatibility only
@api public
# File lib/mmtrix/agent.rb, line 331 def shutdown(options={}) agent.shutdown if agent end
Subscribe to events of event_type
, calling the given handler
when one is sent.
# File lib/mmtrix/agent.rb, line 580 def subscribe(event_type, &handler) agent.events.subscribe( event_type, &handler ) end
Check to see if we are capturing metrics currently on this thread.
# File lib/mmtrix/agent.rb, line 478 def tl_is_execution_traced? Mmtrix::Agent::TransactionState.tl_get.is_execution_traced? end
helper method to check the thread local to determine whether sql is being recorded or not
# File lib/mmtrix/agent.rb, line 490 def tl_is_sql_recorded? Mmtrix::Agent::TransactionState.tl_get.is_sql_recorded? end
helper method to check the thread local to determine whether the transaction in progress is traced or not
# File lib/mmtrix/agent.rb, line 484 def tl_is_transaction_traced? Mmtrix::Agent::TransactionState.tl_get.is_transaction_traced? end
Yield to a block that is run with a database metric name context. This means the Database
instrumentation will use this for the metric name if it does not otherwise know about a model. This is re-entrant.
@param [String,Class,#to_s] model the DB model class
@param [String] method the name of the finder method or other method to identify the operation with.
# File lib/mmtrix/agent.rb, line 570 def with_database_metric_name(model, method = nil, product = nil, &block) #THREAD_LOCAL_ACCESS if txn = Transaction.tl_current txn.with_database_metric_name(model, method, product, &block) else yield end end