Module: Appsignal

Extended by:
Helpers::Instrumentation, Helpers::Metrics
Defined in:
lib/appsignal.rb,
lib/appsignal/cli.rb,
lib/appsignal/demo.rb,
lib/appsignal/rack.rb,
lib/appsignal/span.rb,
lib/appsignal/hooks.rb,
lib/appsignal/utils.rb,
lib/appsignal/config.rb,
lib/appsignal/logger.rb,
lib/appsignal/marker.rb,
lib/appsignal/probes.rb,
lib/appsignal/system.rb,
lib/appsignal/loaders.rb,
lib/appsignal/version.rb,
lib/appsignal/check_in.rb,
lib/appsignal/cli/demo.rb,
lib/appsignal/extension.rb,
lib/appsignal/hooks/gvl.rb,
lib/appsignal/hooks/mri.rb,
lib/appsignal/hooks/que.rb,
lib/appsignal/auth_check.rb,
lib/appsignal/hooks/http.rb,
lib/appsignal/hooks/puma.rb,
lib/appsignal/hooks/rake.rb,
lib/appsignal/probes/gvl.rb,
lib/appsignal/probes/mri.rb,
lib/appsignal/utils/data.rb,
lib/appsignal/utils/json.rb,
lib/appsignal/cli/helpers.rb,
lib/appsignal/cli/install.rb,
lib/appsignal/environment.rb,
lib/appsignal/hooks/excon.rb,
lib/appsignal/hooks/redis.rb,
lib/appsignal/sample_data.rb,
lib/appsignal/transaction.rb,
lib/appsignal/transmitter.rb,
lib/appsignal/cli/diagnose.rb,
lib/appsignal/hooks/resque.rb,
lib/appsignal/hooks/sequel.rb,
lib/appsignal/utils/ndjson.rb,
lib/appsignal/check_in/cron.rb,
lib/appsignal/custom_marker.rb,
lib/appsignal/hooks/at_exit.rb,
lib/appsignal/hooks/sidekiq.rb,
lib/appsignal/hooks/unicorn.rb,
lib/appsignal/loaders/grape.rb,
lib/appsignal/check_in/event.rb,
lib/appsignal/hooks/net_http.rb,
lib/appsignal/loaders/hanami.rb,
lib/appsignal/probes/helpers.rb,
lib/appsignal/probes/sidekiq.rb,
lib/appsignal/event_formatter.rb,
lib/appsignal/extension/jruby.rb,
lib/appsignal/helpers/metrics.rb,
lib/appsignal/hooks/celluloid.rb,
lib/appsignal/hooks/ownership.rb,
lib/appsignal/hooks/passenger.rb,
lib/appsignal/hooks/shoryuken.rb,
lib/appsignal/internal_errors.rb,
lib/appsignal/loaders/padrino.rb,
lib/appsignal/loaders/sinatra.rb,
lib/appsignal/hooks/active_job.rb,
lib/appsignal/hooks/webmachine.rb,
lib/appsignal/integrations/que.rb,
lib/appsignal/hooks/data_mapper.rb,
lib/appsignal/hooks/delayed_job.rb,
lib/appsignal/hooks/dry_monitor.rb,
lib/appsignal/integrations/http.rb,
lib/appsignal/integrations/puma.rb,
lib/appsignal/integrations/rake.rb,
lib/appsignal/rack/body_wrapper.rb,
lib/appsignal/check_in/scheduler.rb,
lib/appsignal/cli/diagnose/paths.rb,
lib/appsignal/cli/diagnose/utils.rb,
lib/appsignal/garbage_collection.rb,
lib/appsignal/hooks/action_cable.rb,
lib/appsignal/hooks/redis_client.rb,
lib/appsignal/integrations/excon.rb,
lib/appsignal/integrations/redis.rb,
lib/appsignal/rack/event_handler.rb,
lib/appsignal/utils/rails_helper.rb,
lib/appsignal/hooks/action_mailer.rb,
lib/appsignal/integrations/resque.rb,
lib/appsignal/integrations/railtie.rb,
lib/appsignal/integrations/sidekiq.rb,
lib/appsignal/integrations/unicorn.rb,
lib/appsignal/integrations/net_http.rb,
lib/appsignal/rack/grape_middleware.rb,
lib/appsignal/integrations/ownership.rb,
lib/appsignal/integrations/shoryuken.rb,
lib/appsignal/rack/hanami_middleware.rb,
lib/appsignal/helpers/instrumentation.rb,
lib/appsignal/hooks/mongo_ruby_driver.rb,
lib/appsignal/integrations/webmachine.rb,
lib/appsignal/integrations/data_mapper.rb,
lib/appsignal/integrations/dry_monitor.rb,
lib/appsignal/rack/abstract_middleware.rb,
lib/appsignal/utils/integration_logger.rb,
lib/appsignal/integrations/action_cable.rb,
lib/appsignal/integrations/redis_client.rb,
lib/appsignal/rack/rails_instrumentation.rb,
lib/appsignal/utils/sample_data_sanitizer.rb,
lib/appsignal/rack/sinatra_instrumentation.rb,
lib/appsignal/utils/query_params_sanitizer.rb,
lib/appsignal/integrations/mongo_ruby_driver.rb,
lib/appsignal/integrations/delayed_job_plugin.rb,
lib/appsignal/rack/instrumentation_middleware.rb,
lib/appsignal/utils/integration_memory_logger.rb,
lib/appsignal/utils/stdout_and_logger_message.rb,
lib/appsignal/event_formatter/rom/sql_formatter.rb,
lib/appsignal/hooks/active_support_notifications.rb,
lib/appsignal/event_formatter/sequel/sql_formatter.rb,
lib/appsignal/event_formatter/faraday/request_formatter.rb,
lib/appsignal/integrations/active_support_notifications.rb,
lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb,
lib/appsignal/event_formatter/active_record/sql_formatter.rb,
lib/appsignal/event_formatter/action_view/render_formatter.rb,
lib/appsignal/event_formatter/elastic_search/search_formatter.rb,
lib/appsignal/event_formatter/view_component/render_formatter.rb,
lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter.rb,
lib/appsignal/event_formatter/active_record/instantiation_formatter.rb,
ext/appsignal_extension.c

Overview

AppSignal for Ruby gem’s main module.

Provides method to control the AppSignal instrumentation and the system agent. Also provides direct access to instrumentation helpers (from Helpers::Instrumentation) and metrics helpers (from Helpers::Metrics) for ease of use.

Defined Under Namespace

Modules: CheckIn, GarbageCollection, Helpers, Integrations, Loaders, Probes, Rack, System, Utils Classes: AuthCheck, CLI, Config, CustomMarker, Demo, Environment, EventFormatter, Extension, Hooks, InternalError, Logger, Marker, NotStartedError, SampleData, Span, Transaction, Transmitter

Constant Summary collapse

VERSION =
"4.5.9"

Class Attribute Summary collapse

Class Method Summary collapse

Methods included from Helpers::Metrics

add_distribution_value, increment_counter, set_gauge

Methods included from Helpers::Instrumentation

add_breadcrumb, add_custom_data, add_headers, add_params, add_session_data, add_tags, ignore_instrumentation_events, instrument, instrument_sql, monitor, monitor_and_stop, report_error, send_error, set_action, set_empty_params!, set_error, set_namespace

Class Attribute Details

.configConfig? (readonly)

The loaded AppSignal configuration. Returns the current AppSignal configuration.

Can return ‘nil` if no configuration has been set or automatically loaded by an automatic integration or by calling start.

Examples:

Appsignal.config

Returns:

See Also:



35
36
37
# File 'lib/appsignal.rb', line 35

def config
  @config
end

.config_errorNilClass/Exception (readonly) Also known as: config_error?

Returns the error that was encountered while loading the ‘appsignal.rb` config file.

It does not include any error that occurred while loading the ‘appsignal.yml` file.

If the value is ‘nil`, no error was encountered or AppSignal wasn’t started yet.

Returns:

  • (NilClass/Exception)


75
76
77
# File 'lib/appsignal.rb', line 75

def config_error
  @config_error
end

.extension_loadedBoolean?

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Accessor for toggle if the AppSignal C-extension is loaded.

Can be ‘nil` if extension has not been loaded yet. See extension_loaded? for a boolean return value.

Returns:

  • (Boolean, nil)

See Also:



46
47
48
# File 'lib/appsignal.rb', line 46

def extension_loaded
  @extension_loaded
end

.internal_loggerObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



63
# File 'lib/appsignal.rb', line 63

attr_writer :internal_logger

Class Method Details

._load_config!(env_param = nil, &block) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

PRIVATE METHOD. DO NOT USE.

Parameters:

  • env_param (String, NilClass) (defaults to: nil)

    Used by diagnose CLI to pass through the environment CLI option value.



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/appsignal.rb', line 169

def _load_config!(env_param = nil, &block)
  # Ensure it's not an empty string if it's a value
  proper_env_param = env_param&.to_s&.strip
  # Unset it if it's an empty string
  proper_env_param = nil if proper_env_param&.empty?

  context = Appsignal::Config::Context.new(
    :env => Config.determine_env(env_param),
    :root_path => Config.determine_root_path
  )
  # If there's a config/appsignal.rb file
  if context.dsl_config_file?
    if config
      # When calling `Appsignal.configure` from an app, not the
      # `config/appsignal.rb` file, with also a Ruby config file present.
      message = "The `Appsignal.configure` helper is called from within an " \
        "app while a `#{context.dsl_config_file}` file is present. " \
        "The `config/appsignal.rb` file is ignored when the " \
        "config is loaded with `Appsignal.configure` from within an app. " \
        "We recommend moving all config to the `config/appsignal.rb` file " \
        "or the `Appsignal.configure` helper in the app."
      Appsignal::Utils::StdoutAndLoggerMessage.warning(message)
    else
      # Load it when no config is present
      #
      # We don't pass the `env_var` or `context.env` here so that the
      # `Appsignal.configure` or `Appsignal.start` can figure out the
      # environment themselves if it was not explicitly set.
      # This way we prevent forcing an environment that's auto loaded on
      # the to-be-loaded config file.
      #
      # The `(proper)_env_param` is only set when it's explicitly set,
      # which means it needs to override any auto detected environment.
      load_dsl_config_file(context.dsl_config_file, proper_env_param)
    end
  else
    # Load config if no config file was found and no config is present yet
    # This will load the config/appsignal.yml file automatically
    @config ||= Config.new(context.root_path, context.env)
  end
  # Allow a block to be given to customize the config and override any
  # loaded config before it's validated.
  block.call(config) if block_given?
  # Validate the config, if present
  config&.validate
end

._start_loggervoid

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Start the AppSignal internal logger.

Sets the log level and sets the logger. Uses a file-based logger or the STDOUT-based logger. See the ‘:log` configuration option.



426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
# File 'lib/appsignal.rb', line 426

def _start_logger
  if config && config[:log] == "file" && config.log_file_path
    start_internal_file_logger(config.log_file_path)
  else
    start_internal_stdout_logger
  end

  internal_logger.level =
    if config
      config.log_level
    else
      Appsignal::Config::DEFAULT_LOG_LEVEL
    end
  return unless @in_memory_logger

  messages = @in_memory_logger.messages_for_level(internal_logger.level)
  internal_logger << messages.join
  @in_memory_logger = nil
end

.active?Boolean

Returns the active state of the AppSignal integration.

Conditions apply for AppSignal to be marked as active:

This logic is used within instrument helper such as instrument so it’s not necessary to wrap instrument calls with this method.

Examples:

Do this

Appsignal.instrument(..) do
  # Do this
end

Don’t do this

if Appsignal.active?
  Appsignal.instrument(..) do
    # Don't do this
  end
end

Returns:

  • (Boolean)

Since:

  • 0.2.7



490
491
492
# File 'lib/appsignal.rb', line 490

def active?
  config&.active? && extension_loaded?
end

.check_if_started!void

This method returns an undefined value.

Check if the AppSignal Ruby gem has started successfully.

If it has not (yet) started or encountered an error in the ‘config/appsignal.rb` config file during start up that prevented it from starting, it will raise a NotStartedError.

If there an error raised from the config file, it will include it as the error cause of the raised error.



510
511
512
513
514
515
516
517
518
519
520
521
522
# File 'lib/appsignal.rb', line 510

def check_if_started!
  return if started?

  begin
    raise config_error if config_error?
  rescue
    # Raise the NotStartedError and make the config error the error cause
    raise NotStartedError, config_error
  end

  # Raise the NotStartedError as normal
  raise NotStartedError
end

.configure(env_param = nil, root_path: nil) {|Config| ... } ⇒ void

This method returns an undefined value.

Configure the AppSignal Ruby gem using a DSL.

Pass a block to the configure method to configure the Ruby gem.

Each config option defined in our docs can be fetched, set and modified via a helper method in the given block.

After AppSignal has started using start, the configuration can not be modified. Any calls to this helper will be ignored.

This helper should not be used to configure multiple environments, like done in the YAML file. Configure the environment you want active when the application starts.

Examples:

Configure AppSignal for the application

Appsignal.configure do |config|
  config.path = "/the/app/path"
  config.active = ENV["APP_ACTIVE"] == "true"
  config.push_api_key = File.read("appsignal_key.txt").chomp
  config.ignore_actions = ENDPOINTS.select { |e| e.public? }.map(&:name)
  config.request_headers << "MY_CUSTOM_HEADER"
end

Configure AppSignal for the application and select the environment

Appsignal.configure(:production) do |config|
  config.active = true
end

Automatically detects the app environment

# Tries to determine the app environment automatically from the
# environment and the libraries it integrates with.
ENV["RACK_ENV"] = "production"

Appsignal.configure do |config|
  config.env # => "production"
end

Calling configure multiple times for different environments resets the configuration

Appsignal.configure(:development) do |config|
  config.ignore_actions = ["My action"]
end

Appsignal.configure(:production) do |config|
  config.ignore_actions # => []
end

Load config without a block

# This will require either ENV vars being set
# or the config/appsignal.yml being present
Appsignal.configure
# Or for the environment given as an argument
Appsignal.configure(:production)

Parameters:

  • env_param (String, Symbol) (defaults to: nil)

    The environment to load.

  • root_path (String) (defaults to: nil)

    The path to look the ‘config/appsignal.yml` config file in. Defaults to the current working directory.

Yields:

See Also:



306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
# File 'lib/appsignal.rb', line 306

def configure(env_param = nil, root_path: nil)
  if Appsignal.started?
    Appsignal.internal_logger
      .warn("AppSignal is already started. Ignoring `Appsignal.configure` call.")
    return
  end

  root_path_param = root_path
  if params_match_loaded_config?(env_param, root_path_param)
    config
  else
    @config = Config.new(
      root_path_param || Config.determine_root_path,
      Config.determine_env(env_param),
      # If in the context of an `config/appsignal.rb` config file, do not
      # load the `config/appsignal.yml` file.
      # The `.rb` file is a replacement for the `.yml` file so it shouldn't
      # load both.
      :load_yaml_file => !config_file_context?
    )
  end

  # When calling `Appsignal.configure` from a Rails initializer and a YAML
  # file is present. We will not load the YAML file in the future.
  if !config_file_context? && config.yml_config_file?
    message = "The `Appsignal.configure` helper is called while a " \
      "`config/appsignal.yml` file is present. In future versions the " \
      "`config/appsignal.yml` file will be ignored when loading the " \
      "config. We recommend moving all config to the " \
      "`config/appsignal.rb` file, or the `Appsignal.configure` helper " \
      "in Rails initializer file, and remove the " \
      "`config/appsignal.yml` file."
    Appsignal::Utils::StdoutAndLoggerMessage.warning(message)
  end

  config_dsl = Appsignal::Config::ConfigDSL.new(config)
  return unless block_given?

  yield config_dsl
  config.merge_dsl_options(config_dsl.dsl_options)
  nil
end

.dsl_config_file_loaded?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)


495
496
497
# File 'lib/appsignal.rb', line 495

def dsl_config_file_loaded?
  defined?(@dsl_config_file_loaded) ? true : false
end

.extension_loaded?Boolean

Returns if the C-extension was loaded properly.

Returns:

  • (Boolean)

See Also:

Since:

  • 1.0.0



451
452
453
# File 'lib/appsignal.rb', line 451

def extension_loaded?
  !!extension_loaded
end

.forkedvoid

This method returns an undefined value.



350
351
352
353
354
355
356
357
# File 'lib/appsignal.rb', line 350

def forked
  return unless active?

  Appsignal._start_logger
  internal_logger.debug("Forked process, resubscribing and restarting extension")
  Appsignal::Extension.start
  nil
end

.get_server_state(key) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



393
394
395
# File 'lib/appsignal.rb', line 393

def get_server_state(key)
  Appsignal::Extension.get_server_state(key)
end

.in_memory_loggerObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



398
399
400
401
402
403
# File 'lib/appsignal.rb', line 398

def in_memory_logger
  @in_memory_logger ||=
    Appsignal::Utils::IntegrationMemoryLogger.new.tap do |l|
      l.formatter = log_formatter("appsignal")
    end
end

.load(integration_name) ⇒ void

This method returns an undefined value.

Load an AppSignal integration.

Load one of the supported integrations via our loader system. This will set config defaults and integratie with the library if AppSignal is active upon start.

Examples:

Load Sinatra integrations

# First load the integration
Appsignal.load(:sinatra)
# Start AppSignal
Appsignal.start

Load Sinatra integrations and define custom config

# First load the integration
Appsignal.load(:sinatra)

# Customize config
Appsignal.configure do |config|
  config.ignore_actions = ["GET /ping"]
end

# Start AppSignal
Appsignal.start

Parameters:

  • integration_name (String, Symbol)

    Name of the integration to load.

Since:

  • 3.12.0



387
388
389
390
# File 'lib/appsignal.rb', line 387

def load(integration_name)
  Loaders.load(integration_name)
  nil
end

.log_formatter(prefix = nil) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



411
412
413
414
415
416
417
# File 'lib/appsignal.rb', line 411

def log_formatter(prefix = nil)
  pre = "#{prefix}: " if prefix
  proc do |severity, datetime, _progname, msg|
    "[#{datetime.strftime("%Y-%m-%dT%H:%M:%S")} (process) " \
      "##{Process.pid}][#{severity}] #{pre}#{msg}\n"
  end
end

.startvoid

This method returns an undefined value.

Start the AppSignal integration.

Starts AppSignal with the given configuration. If no configuration is set yet it will try to automatically load the configuration using the environment loaded from environment variables and the currently working directory.

This is not required for the automatic integrations AppSignal offers, but this is required for all non-automatic integrations and pure Ruby applications. For more information, see our [integrations list](docs.appsignal.com/ruby/integrations/) and our [Integrating AppSignal](docs.appsignal.com/ruby/instrumentation/integrating-appsignal.html) guide.

Examples:

Appsignal.start

with custom loaded configuration

Appsignal.configure(:production) do |config|
  config.ignore_actions = ["My action"]
end
Appsignal.start

Since:

  • 0.7.0



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/appsignal.rb', line 108

def start # rubocop:disable Metrics/AbcSize
  if ENV.fetch("_APPSIGNAL_DIAGNOSE", false)
    internal_logger.info("Skipping start in diagnose context")
    return
  end

  if started?
    internal_logger.warn("Ignoring call to Appsignal.start after AppSignal has started")
    return
  end

  if config_file_context?
    internal_logger.warn(
      "Ignoring call to Appsignal.start in config file context."
    )
    return
  end

  unless extension_loaded?
    internal_logger.info("Not starting AppSignal, extension is not loaded")
    return
  end

  internal_logger.debug("Loading AppSignal gem")

  _load_config!
  _start_logger

  if config.valid?
    if config.active?
      @started = true
      internal_logger.info "Starting AppSignal #{Appsignal::VERSION} " \
        "(#{$PROGRAM_NAME}, Ruby #{RUBY_VERSION}, #{RUBY_PLATFORM})"
      config.write_to_environment
      Appsignal::Extension.start
      Appsignal::Hooks.load_hooks
      Appsignal::Loaders.start

      if config[:enable_allocation_tracking] && !Appsignal::System.jruby?
        Appsignal::Extension.install_allocation_event_hook
        Appsignal::Environment.report_enabled("allocation_tracking")
      end

      Appsignal::Probes.start if config[:enable_minutely_probes]

      
      @config.freeze
    else
      internal_logger.info("Not starting, not active for #{config.env}")
    end
  else
    internal_logger.error("Not starting, no valid config for this environment")
  end
  nil
end

.started?Boolean

Returns if start has been called before with a valid config to start AppSignal.

Returns:

  • (Boolean)

See Also:

Since:

  • 3.12.0



461
462
463
# File 'lib/appsignal.rb', line 461

def started?
  defined?(@started) ? @started : false
end

.stop(called_by = nil) ⇒ void

This method returns an undefined value.

Stop AppSignal’s agent.

Stops the AppSignal agent. Call this before the end of your program to make sure the agent is stopped as well.

Examples:

Appsignal.start
# Run your application
Appsignal.stop

Parameters:

  • called_by (String) (defaults to: nil)

    Name of the thing that requested the agent to be stopped. Will be used in the AppSignal log file.

Since:

  • 1.0.0



230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/appsignal.rb', line 230

def stop(called_by = nil)
  Thread.new do
    if called_by
      internal_logger.info("Stopping AppSignal (#{called_by})")
    else
      internal_logger.info("Stopping AppSignal")
    end
    Appsignal::Extension.stop
    Appsignal::Probes.stop
    Appsignal::CheckIn.stop
  end.join
  nil
end

.testing?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)


79
80
81
# File 'lib/appsignal.rb', line 79

def testing?
  false
end