appsignal 4.5.16 → 4.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +49 -0
  3. data/CLAUDE.md +177 -0
  4. data/README.md +17 -0
  5. data/appsignal.gemspec +1 -0
  6. data/build_matrix.yml +29 -0
  7. data/lib/appsignal/auth_check.rb +3 -3
  8. data/lib/appsignal/check_in/cron.rb +1 -1
  9. data/lib/appsignal/check_in/event.rb +1 -1
  10. data/lib/appsignal/check_in/scheduler.rb +3 -1
  11. data/lib/appsignal/check_in.rb +9 -6
  12. data/lib/appsignal/cli/diagnose.rb +1 -1
  13. data/lib/appsignal/cli.rb +1 -1
  14. data/lib/appsignal/config.rb +231 -30
  15. data/lib/appsignal/custom_marker.rb +3 -3
  16. data/lib/appsignal/environment.rb +7 -1
  17. data/lib/appsignal/event_formatter/action_view/render_formatter.rb +1 -1
  18. data/lib/appsignal/event_formatter/active_record/instantiation_formatter.rb +1 -1
  19. data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +1 -1
  20. data/lib/appsignal/event_formatter/elastic_search/search_formatter.rb +1 -1
  21. data/lib/appsignal/event_formatter/faraday/request_formatter.rb +1 -1
  22. data/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter.rb +1 -1
  23. data/lib/appsignal/event_formatter/rom/sql_formatter.rb +1 -1
  24. data/lib/appsignal/event_formatter/sequel/sql_formatter.rb +1 -1
  25. data/lib/appsignal/event_formatter/view_component/render_formatter.rb +1 -1
  26. data/lib/appsignal/event_formatter.rb +41 -3
  27. data/lib/appsignal/extension.rb +1 -1
  28. data/lib/appsignal/garbage_collection.rb +1 -1
  29. data/lib/appsignal/helpers/instrumentation.rb +82 -35
  30. data/lib/appsignal/helpers/metrics.rb +12 -9
  31. data/lib/appsignal/hooks/action_cable.rb +1 -1
  32. data/lib/appsignal/hooks/action_mailer.rb +1 -0
  33. data/lib/appsignal/hooks/active_job.rb +1 -1
  34. data/lib/appsignal/hooks/active_support_notifications.rb +1 -1
  35. data/lib/appsignal/hooks/at_exit.rb +1 -1
  36. data/lib/appsignal/hooks/celluloid.rb +1 -1
  37. data/lib/appsignal/hooks/data_mapper.rb +1 -1
  38. data/lib/appsignal/hooks/delayed_job.rb +1 -1
  39. data/lib/appsignal/hooks/dry_monitor.rb +1 -1
  40. data/lib/appsignal/hooks/excon.rb +1 -1
  41. data/lib/appsignal/hooks/gvl.rb +1 -1
  42. data/lib/appsignal/hooks/http.rb +1 -1
  43. data/lib/appsignal/hooks/mongo_ruby_driver.rb +1 -1
  44. data/lib/appsignal/hooks/mri.rb +1 -1
  45. data/lib/appsignal/hooks/net_http.rb +1 -1
  46. data/lib/appsignal/hooks/ownership.rb +1 -1
  47. data/lib/appsignal/hooks/passenger.rb +1 -1
  48. data/lib/appsignal/hooks/puma.rb +1 -1
  49. data/lib/appsignal/hooks/que.rb +1 -1
  50. data/lib/appsignal/hooks/rake.rb +1 -1
  51. data/lib/appsignal/hooks/redis.rb +1 -1
  52. data/lib/appsignal/hooks/redis_client.rb +1 -1
  53. data/lib/appsignal/hooks/resque.rb +1 -1
  54. data/lib/appsignal/hooks/sequel.rb +2 -1
  55. data/lib/appsignal/hooks/shoryuken.rb +1 -1
  56. data/lib/appsignal/hooks/sidekiq.rb +1 -0
  57. data/lib/appsignal/hooks/unicorn.rb +1 -1
  58. data/lib/appsignal/hooks/webmachine.rb +1 -1
  59. data/lib/appsignal/hooks.rb +5 -3
  60. data/lib/appsignal/integrations/action_cable.rb +1 -1
  61. data/lib/appsignal/integrations/active_support_notifications.rb +1 -1
  62. data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +1 -1
  63. data/lib/appsignal/integrations/data_mapper.rb +1 -1
  64. data/lib/appsignal/integrations/delayed_job_plugin.rb +1 -1
  65. data/lib/appsignal/integrations/dry_monitor.rb +1 -1
  66. data/lib/appsignal/integrations/excon.rb +1 -1
  67. data/lib/appsignal/integrations/http.rb +1 -1
  68. data/lib/appsignal/integrations/mongo_ruby_driver.rb +1 -1
  69. data/lib/appsignal/integrations/net_http.rb +1 -1
  70. data/lib/appsignal/integrations/object.rb +18 -2
  71. data/lib/appsignal/integrations/ownership.rb +1 -1
  72. data/lib/appsignal/integrations/puma.rb +1 -1
  73. data/lib/appsignal/integrations/que.rb +1 -1
  74. data/lib/appsignal/integrations/railtie.rb +2 -2
  75. data/lib/appsignal/integrations/rake.rb +2 -2
  76. data/lib/appsignal/integrations/redis.rb +1 -1
  77. data/lib/appsignal/integrations/redis_client.rb +1 -1
  78. data/lib/appsignal/integrations/resque.rb +2 -2
  79. data/lib/appsignal/integrations/shoryuken.rb +1 -1
  80. data/lib/appsignal/integrations/sidekiq.rb +3 -3
  81. data/lib/appsignal/integrations/unicorn.rb +1 -1
  82. data/lib/appsignal/integrations/webmachine.rb +1 -1
  83. data/lib/appsignal/internal_errors.rb +2 -2
  84. data/lib/appsignal/loaders.rb +1 -1
  85. data/lib/appsignal/logger.rb +120 -79
  86. data/lib/appsignal/marker.rb +1 -1
  87. data/lib/appsignal/probes/gvl.rb +4 -3
  88. data/lib/appsignal/probes/helpers.rb +1 -1
  89. data/lib/appsignal/probes/mri.rb +3 -3
  90. data/lib/appsignal/probes/sidekiq.rb +4 -3
  91. data/lib/appsignal/probes.rb +20 -15
  92. data/lib/appsignal/rack/body_wrapper.rb +1 -1
  93. data/lib/appsignal/rack.rb +1 -1
  94. data/lib/appsignal/sample_data.rb +31 -12
  95. data/lib/appsignal/span.rb +1 -1
  96. data/lib/appsignal/system.rb +9 -8
  97. data/lib/appsignal/transaction.rb +72 -52
  98. data/lib/appsignal/transmitter.rb +1 -1
  99. data/lib/appsignal/utils.rb +1 -1
  100. data/lib/appsignal/version.rb +2 -1
  101. data/lib/appsignal.rb +22 -14
  102. data/lib/puma/plugin/appsignal.rb +1 -1
  103. data/sig/appsignal.rbi +2599 -0
  104. data/sig/appsignal.rbs +2420 -0
  105. metadata +20 -6
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  class Hooks
5
- # @api private
5
+ # @!visibility private
6
6
  class RedisHook < Appsignal::Hooks::Hook
7
7
  register :redis
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  class Hooks
5
- # @api private
5
+ # @!visibility private
6
6
  class RedisClientHook < Appsignal::Hooks::Hook
7
7
  register :redis_client
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  class Hooks
5
- # @api private
5
+ # @!visibility private
6
6
  class ResqueHook < Appsignal::Hooks::Hook
7
7
  register :resque
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  class Hooks
5
- # @api private
5
+ # @!visibility private
6
6
  module SequelLogExtension
7
7
  # Add query instrumentation
8
8
  def log_yield(sql, args = nil)
@@ -19,6 +19,7 @@ module Appsignal
19
19
 
20
20
  module SequelLogConnectionExtension
21
21
  # Add query instrumentation
22
+ # @!visibility private
22
23
  def log_connection_yield(sql, conn, args = nil)
23
24
  Appsignal.instrument(
24
25
  "sql.sequel",
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  class Hooks
5
- # @api private
5
+ # @!visibility private
6
6
  class ShoryukenHook < Appsignal::Hooks::Hook
7
7
  register :shoryuken
8
8
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  class Hooks
5
+ # @!visibility private
5
6
  class SidekiqHook < Appsignal::Hooks::Hook
6
7
  register :sidekiq
7
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  class Hooks
5
- # @api private
5
+ # @!visibility private
6
6
  class UnicornHook < Appsignal::Hooks::Hook
7
7
  register :unicorn
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  class Hooks
5
- # @api private
5
+ # @!visibility private
6
6
  class WebmachineHook < Appsignal::Hooks::Hook
7
7
  register :webmachine
8
8
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Appsignal
4
- # @api private
4
+ # @!visibility private
5
5
  class Hooks
6
6
  class << self
7
7
  def register(name, hook)
@@ -38,8 +38,10 @@ module Appsignal
38
38
  @installed = true
39
39
  rescue => ex
40
40
  logger = Appsignal.internal_logger
41
- logger.error("Error while installing #{name} hook: #{ex}")
42
- logger.debug ex.backtrace.join("\n")
41
+ logger.error(
42
+ "Error while installing #{name} hook: #{ex.class}: #{ex.message}\n" \
43
+ "#{ex.backtrace.join("\n")}"
44
+ )
43
45
  end
44
46
  end
45
47
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  module Integrations
5
- # @api private
5
+ # @!visibility private
6
6
  module ActionCableIntegration
7
7
  def perform_action(*args, &block)
8
8
  # The request is only the original websocket request
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  module Integrations
5
- # @api private
5
+ # @!visibility private
6
6
  module ActiveSupportNotificationsIntegration
7
7
  BANG = "!"
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  module Integrations
5
- # @api private
5
+ # @!visibility private
6
6
  class Capistrano
7
7
  def self.tasks(config)
8
8
  config.load do
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  class Hooks
5
- # @api private
5
+ # @!visibility private
6
6
  module DataMapperLogListener
7
7
  SQL_CLASSES = [
8
8
  "DataObjects::SqlServer::Connection",
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  module Integrations
5
- # @api private
5
+ # @!visibility private
6
6
  class DelayedJobPlugin < ::Delayed::Plugin
7
7
  extend Appsignal::Hooks::Helpers
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  module Integrations
5
- # @api private
5
+ # @!visibility private
6
6
  module DryMonitorIntegration
7
7
  def instrument(event_id, payload = {}, &block)
8
8
  Appsignal::Transaction.current.start_event
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  module Integrations
5
- # @api private
5
+ # @!visibility private
6
6
  module ExconIntegration
7
7
  def self.instrument(name, data, &block)
8
8
  namespace, *event = name.split(".")
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  module Integrations
5
- # @api private
5
+ # @!visibility private
6
6
  module HttpIntegration
7
7
  def request(verb, uri, opts = {})
8
8
  uri_module = defined?(HTTP::URI) ? HTTP::URI : URI
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  class Hooks
5
- # @api private
5
+ # @!visibility private
6
6
  class MongoMonitorSubscriber
7
7
  # Called by Mongo::Monitor when query starts
8
8
  def started(event)
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  module Integrations
5
- # @api private
5
+ # @!visibility private
6
6
  module NetHttpIntegration
7
7
  def request(request, body = nil, &block)
8
8
  Appsignal.instrument(
@@ -2,7 +2,17 @@
2
2
 
3
3
  Appsignal::Environment.report_enabled("object_instrumentation") if defined?(Appsignal)
4
4
 
5
+ # Extensions to Object for AppSignal method instrumentation.
6
+ #
7
+ # @see https://docs.appsignal.com/ruby/instrumentation/method-instrumentation.html
8
+ # Method instrumentation documentation.
5
9
  class Object
10
+ # Instruments a class method with AppSignal monitoring.
11
+ #
12
+ # @param method_name [Symbol] The name of the class method to instrument.
13
+ # @param options [Hash<Symbol, String>] Options for instrumentation.
14
+ # @option options [String] :name Custom event name for the instrumentation.
15
+ # @return [Symbol]
6
16
  # @see https://docs.appsignal.com/ruby/instrumentation/method-instrumentation.html
7
17
  # Method instrumentation documentation.
8
18
  def self.appsignal_instrument_class_method(method_name, options = {})
@@ -22,6 +32,12 @@ class Object
22
32
  end
23
33
  end
24
34
 
35
+ # Instruments an instance method with AppSignal monitoring.
36
+ #
37
+ # @param method_name [Symbol] The name of the instance method to instrument.
38
+ # @param options [Hash<Symbol, String>] Options for instrumentation.
39
+ # @option options [String] :name Custom event name for the instrumentation.
40
+ # @return [Symbol]
25
41
  # @see https://docs.appsignal.com/ruby/instrumentation/method-instrumentation.html
26
42
  # Method instrumentation documentation.
27
43
  def self.appsignal_instrument_method(method_name, options = {})
@@ -37,14 +53,14 @@ class Object
37
53
  ruby2_keywords method_name if respond_to?(:ruby2_keywords, true)
38
54
  end
39
55
 
40
- # @api private
56
+ # @!visibility private
41
57
  def self.appsignal_reverse_class_name
42
58
  return "AnonymousClass" unless name
43
59
 
44
60
  name.split("::").reverse.join(".")
45
61
  end
46
62
 
47
- # @api private
63
+ # @!visibility private
48
64
  def appsignal_reverse_class_name
49
65
  self.class.appsignal_reverse_class_name
50
66
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  module Integrations
5
- # @api private
5
+ # @!visibility private
6
6
  module OwnershipIntegration
7
7
  # Implement the `around_change` logic by monkey-patching the reader,
8
8
  # instead of by using the `around_change=` writer. This allows customers
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  module Integrations
5
- # @api private
5
+ # @!visibility private
6
6
  module PumaServer
7
7
  def lowlevel_error(error, env, response_status = 500)
8
8
  response =
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  module Integrations
5
- # @api private
5
+ # @!visibility private
6
6
  module QuePlugin
7
7
  def _run(*args)
8
8
  transaction =
@@ -7,7 +7,7 @@ require "appsignal/rack/rails_instrumentation"
7
7
 
8
8
  module Appsignal
9
9
  module Integrations
10
- # @api private
10
+ # @!visibility private
11
11
  class Railtie < ::Rails::Railtie
12
12
  config.appsignal = ActiveSupport::OrderedOptions.new
13
13
  config.appsignal.start_at = :on_load
@@ -77,7 +77,7 @@ module Appsignal
77
77
 
78
78
  # Report errors reported by the Rails error reporter using {Appsignal.report_error}.
79
79
  #
80
- # @api private
80
+ # @!visibility private
81
81
  class RailsErrorReporterSubscriber
82
82
  class << self
83
83
  def report(error, handled:, severity:, context: {}, source: nil) # rubocop:disable Lint/UnusedMethodArgument
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  module Integrations
5
- # @api private
5
+ # @!visibility private
6
6
  module RakeIntegration
7
7
  IGNORED_ERRORS = [
8
8
  # Normal exits from the application we do not need to report
@@ -49,7 +49,7 @@ module Appsignal
49
49
  end
50
50
  end
51
51
 
52
- # @api private
52
+ # @!visibility private
53
53
  module RakeIntegrationHelper
54
54
  # Register an `at_exit` hook when a task is executed. This will stop
55
55
  # AppSignal when _all_ tasks are executed and Rake exits.
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  module Integrations
5
- # @api private
5
+ # @!visibility private
6
6
  module RedisIntegration
7
7
  def write(command)
8
8
  sanitized_command =
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  module Integrations
5
- # @api private
5
+ # @!visibility private
6
6
  module RedisClientIntegration
7
7
  def write(command)
8
8
  sanitized_command =
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  module Integrations
5
- # @api private
5
+ # @!visibility private
6
6
  module ResqueIntegration
7
7
  def perform
8
8
  transaction = Appsignal::Transaction.create(Appsignal::Transaction::BACKGROUND_JOB)
@@ -25,7 +25,7 @@ module Appsignal
25
25
  end
26
26
  end
27
27
 
28
- # @api private
28
+ # @!visibility private
29
29
  class ResqueHelpers
30
30
  def self.arguments(payload)
31
31
  case payload["class"]
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  module Integrations
5
- # @api private
5
+ # @!visibility private
6
6
  class ShoryukenMiddleware
7
7
  def call(worker_instance, queue, sqs_msg, body, &block)
8
8
  transaction = Appsignal::Transaction.create(Appsignal::Transaction::BACKGROUND_JOB)
@@ -11,7 +11,7 @@ module Appsignal
11
11
  # about completing the transaction.
12
12
  #
13
13
  # Introduced in Sidekiq 5.1.
14
- # @api private
14
+ # @!visibility private
15
15
  class SidekiqDeathHandler
16
16
  def call(_job_context, exception)
17
17
  return unless Appsignal.config[:sidekiq_report_errors] == "discard"
@@ -24,7 +24,7 @@ module Appsignal
24
24
  # Error handler for Sidekiq to report errors from jobs and internal Sidekiq
25
25
  # errors.
26
26
  #
27
- # @api private
27
+ # @!visibility private
28
28
  class SidekiqErrorHandler
29
29
  # Sidekiq 7.1.5 introduced the third sidekiq_config argument. It is not
30
30
  # given on older Sidekiq versions.
@@ -49,7 +49,7 @@ module Appsignal
49
49
  end
50
50
  end
51
51
 
52
- # @api private
52
+ # @!visibility private
53
53
  class SidekiqMiddleware
54
54
  include Appsignal::Hooks::Helpers
55
55
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  module Integrations
5
- # @api private
5
+ # @!visibility private
6
6
  module UnicornIntegration
7
7
  # Make sure that appsignal is started and the last transaction
8
8
  # in a worker gets flushed.
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Appsignal
4
4
  module Integrations
5
- # @api private
5
+ # @!visibility private
6
6
  module WebmachineIntegration
7
7
  def run
8
8
  has_parent_transaction = Appsignal::Transaction.current?
@@ -1,17 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Appsignal
4
- # @api private
5
4
  class InternalError < StandardError; end
6
5
 
7
- # @api private
8
6
  class NotStartedError < InternalError
7
+ # @!visibility private
9
8
  MESSAGE = <<~MESSAGE
10
9
  The AppSignal Ruby gem was not started!
11
10
 
12
11
  This error was raised by calling `Appsignal.check_if_started!`
13
12
  MESSAGE
14
13
 
14
+ # @return [String]
15
15
  def message
16
16
  MESSAGE
17
17
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Appsignal
4
- # @api private
4
+ # @!visibility private
5
5
  module Loaders
6
6
  class << self
7
7
  def loaders