appsignal 4.10.3-java → 5.0.0.rc.1-java

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 (94) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -50
  3. data/README.md +1 -2
  4. data/Rakefile +87 -0
  5. data/appsignal.gemspec +8 -7
  6. data/build_matrix.yml +14 -7
  7. data/ext/agent.rb +27 -27
  8. data/ext/appsignal_extension.c +14 -0
  9. data/lib/appsignal/backends.rb +55 -0
  10. data/lib/appsignal/cli/demo.rb +0 -5
  11. data/lib/appsignal/cli/diagnose.rb +38 -6
  12. data/lib/appsignal/cli/helpers.rb +0 -45
  13. data/lib/appsignal/config.rb +140 -1
  14. data/lib/appsignal/demo.rb +1 -1
  15. data/lib/appsignal/event_formatter/action_view/render_formatter.rb +34 -22
  16. data/lib/appsignal/event_formatter/active_job/perform_formatter.rb +35 -0
  17. data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +19 -0
  18. data/lib/appsignal/event_formatter/elastic_search/search_formatter.rb +27 -0
  19. data/lib/appsignal/event_formatter/recorded_elsewhere.rb +17 -0
  20. data/lib/appsignal/event_formatter/rom/sql_formatter.rb +24 -0
  21. data/lib/appsignal/event_formatter/sequel/sql_formatter.rb +5 -0
  22. data/lib/appsignal/event_formatter/view_component/render_formatter.rb +21 -10
  23. data/lib/appsignal/event_formatter.rb +78 -0
  24. data/lib/appsignal/extension.rb +4 -0
  25. data/lib/appsignal/helpers/instrumentation.rb +236 -20
  26. data/lib/appsignal/helpers/metrics.rb +3 -24
  27. data/lib/appsignal/hooks/action_cable.rb +18 -6
  28. data/lib/appsignal/hooks/active_job.rb +128 -179
  29. data/lib/appsignal/hooks/at_exit.rb +4 -1
  30. data/lib/appsignal/hooks/excon.rb +20 -0
  31. data/lib/appsignal/hooks/faraday.rb +16 -0
  32. data/lib/appsignal/hooks/http.rb +5 -0
  33. data/lib/appsignal/hooks/resque.rb +1 -1
  34. data/lib/appsignal/hooks/sequel.rb +32 -2
  35. data/lib/appsignal/hooks/shoryuken.rb +3 -3
  36. data/lib/appsignal/hooks/sidekiq.rb +1 -1
  37. data/lib/appsignal/integrations/action_cable.rb +5 -2
  38. data/lib/appsignal/integrations/active_support_notifications.rb +59 -19
  39. data/lib/appsignal/integrations/data_mapper.rb +14 -2
  40. data/lib/appsignal/integrations/delayed_job_plugin.rb +64 -131
  41. data/lib/appsignal/integrations/dry_monitor.rb +39 -15
  42. data/lib/appsignal/integrations/excon/appsignal_middleware.rb +21 -0
  43. data/lib/appsignal/integrations/excon.rb +52 -15
  44. data/lib/appsignal/integrations/faraday.rb +47 -12
  45. data/lib/appsignal/integrations/http.rb +43 -1
  46. data/lib/appsignal/integrations/mongo_ruby_driver.rb +73 -4
  47. data/lib/appsignal/integrations/net_http.rb +31 -2
  48. data/lib/appsignal/integrations/puma.rb +4 -1
  49. data/lib/appsignal/integrations/que.rb +224 -37
  50. data/lib/appsignal/integrations/railtie.rb +4 -1
  51. data/lib/appsignal/integrations/rake.rb +9 -3
  52. data/lib/appsignal/integrations/redis.rb +22 -1
  53. data/lib/appsignal/integrations/redis_client.rb +22 -1
  54. data/lib/appsignal/integrations/resque.rb +57 -10
  55. data/lib/appsignal/integrations/shoryuken.rb +140 -12
  56. data/lib/appsignal/integrations/sidekiq.rb +73 -16
  57. data/lib/appsignal/integrations/webmachine.rb +47 -4
  58. data/lib/appsignal/loaders/padrino.rb +2 -1
  59. data/lib/appsignal/logger/extension_backend.rb +24 -0
  60. data/lib/appsignal/logger/opentelemetry_backend.rb +66 -0
  61. data/lib/appsignal/logger.rb +13 -9
  62. data/lib/appsignal/metrics/extension_backend.rb +47 -0
  63. data/lib/appsignal/metrics/opentelemetry_backend.rb +89 -0
  64. data/lib/appsignal/opentelemetry/attributes.rb +31 -0
  65. data/lib/appsignal/opentelemetry/dependencies.rb +35 -0
  66. data/lib/appsignal/opentelemetry/error_type.rb +37 -0
  67. data/lib/appsignal/opentelemetry/http_client_request.rb +83 -0
  68. data/lib/appsignal/opentelemetry/http_method.rb +59 -0
  69. data/lib/appsignal/opentelemetry/http_response.rb +30 -0
  70. data/lib/appsignal/opentelemetry/http_server_request.rb +45 -0
  71. data/lib/appsignal/opentelemetry/messaging.rb +82 -0
  72. data/lib/appsignal/opentelemetry/rendering.rb +29 -0
  73. data/lib/appsignal/opentelemetry/sql_db_system.rb +89 -0
  74. data/lib/appsignal/opentelemetry.rb +337 -0
  75. data/lib/appsignal/rack/abstract_middleware.rb +63 -4
  76. data/lib/appsignal/rack/body_wrapper.rb +18 -5
  77. data/lib/appsignal/rack/event_handler.rb +36 -3
  78. data/lib/appsignal/rack/grape_middleware.rb +8 -37
  79. data/lib/appsignal/rack/hanami_middleware.rb +2 -1
  80. data/lib/appsignal/rack/instrumentation_middleware.rb +1 -0
  81. data/lib/appsignal/rack/rails_instrumentation.rb +1 -0
  82. data/lib/appsignal/rack/sinatra_instrumentation.rb +1 -0
  83. data/lib/appsignal/rack.rb +39 -11
  84. data/lib/appsignal/sample_data.rb +4 -0
  85. data/lib/appsignal/transaction/base_backend.rb +107 -0
  86. data/lib/appsignal/transaction/extension_backend.rb +203 -0
  87. data/lib/appsignal/transaction/opentelemetry_backend.rb +796 -0
  88. data/lib/appsignal/transaction.rb +537 -144
  89. data/lib/appsignal/utils/stdout_and_logger_message.rb +9 -0
  90. data/lib/appsignal/version.rb +1 -1
  91. data/lib/appsignal.rb +9 -0
  92. data/sig/appsignal.rbi +426 -37
  93. data/sig/appsignal.rbs +386 -27
  94. metadata +25 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5ec6e363600bfa6217c3811159297fb4d22484c208dcc2610a88848ac31cd16f
4
- data.tar.gz: bf8d8ac65009cf0d1d4d72f5e6543028e1251816522d7a5fdd3d9638a717ce1a
3
+ metadata.gz: 77d0e22fb5459d6180f21e04d33c74b67fccf48bd536f9d421f2360803336edd
4
+ data.tar.gz: 4080ad48951daa435a0798951a5f36d98e62fe3b9cc62a0a94b04043e0b02b23
5
5
  SHA512:
6
- metadata.gz: 3813b645102746900b4768ad5913509a4f223be9242000db3ca8a87133aa4e38c8301fa692d291c6d6146fe209b52fe0236a9d44faa16436e875e75503f2fb50
7
- data.tar.gz: dbcb1e1affec1bd33584528e00b779e21c4c77e91c48c354477167bf45b76e38c61c32f04a8f1bea58e62e85c992030cde8414f3234e6a28192b3460baa4b050
6
+ metadata.gz: 3dcc132106477e0181cff58f8bbed8ed1db7d6c3cebb81dac5b2cc9fc1a8e8b96cfcaf768bf1bfc4fff9c2529ddf6aa920ac30b9fc8367c7687f477f948ab048
7
+ data.tar.gz: e053bcbe1bb2ec6ad4e09efb80cbd86593ab9342acfe16bda373f596bc96e507920a611cff9802fd46a8219851feaf909a59b2e35b5d9e7bce60c4f2eb1716e2
data/CHANGELOG.md CHANGED
@@ -1,64 +1,23 @@
1
1
  # AppSignal for Ruby gem Changelog
2
2
 
3
- ## 4.10.3
3
+ ## 5.0.0.rc.1
4
4
 
5
- _Published on 2026-09-10._
6
-
7
- ### Fixed
8
-
9
- - Fix the sanitization of function arguments in SQL statements.
10
-
11
- Before this release, SQL sanitization of function arguments stripped out parts of the SQL statement after the function argument list.
12
-
13
- (patch [74f509b0](https://github.com/appsignal/appsignal-ruby/commit/74f509b0e8438140bab79a5189c2ed421bbbdf6d))
14
-
15
- ## 4.10.2
16
-
17
- _Published on 2026-09-09._
5
+ _Published on 2026-08-21._
18
6
 
19
7
  ### Added
20
8
 
21
- - Add support for Grape 4. On Grape 4, every request through a Grape API raised a `NoMethodError`. Applications on Grape 3 and below were not affected.
22
-
23
- On Grape 4, the action name and the reported path now describe the endpoint's full route, so they include the API prefix, the path version and the mount point. They also no longer end in a trailing slash when the endpoint declares no path of its own, so an endpoint reported as `GET::My::Api#/users/:id/` is now reported as `GET::My::Api#/users/:id`. Action names on Grape 3 and below do not change.
24
-
25
- (patch [bdea5c1b](https://github.com/appsignal/appsignal-ruby/commit/bdea5c1b6f02c902d0ba195eff3544545bee2547))
26
-
27
- ### Changed
28
-
29
- - Update the agent to handle high traffic apps. On high-traffic apps that would exceed the maximum accepted internal payload size, send data to the Push API more frequently. (patch [a1c3033e](https://github.com/appsignal/appsignal-ruby/commit/a1c3033e1b255371a2d71d4519506a67dbfa2b82))
30
-
31
- ### Fixed
32
-
33
- - Load the host Rails application before the `appsignal demo` command reads the
34
- AppSignal configuration. This matches the behavior of `appsignal diagnose`.
35
-
36
- Thanks [@Guflly](https://github.com/Guflly) for your contribution!
9
+ - Add a `collector_endpoint` configuration option (`APPSIGNAL_COLLECTOR_ENDPOINT` environment variable) that puts the integration in _collector mode_. In collector mode AppSignal reports traces, metrics and logs to an AppSignal Collector, over OTLP/HTTP.
37
10
 
38
- (patch [3249a376](https://github.com/appsignal/appsignal-ruby/commit/3249a376a6fb7a10c990e0f49f7907dc40b03a12))
39
- - Fix events showing as unknown in long-running applications. An application process that kept running for thirty days without restarting could lose the names and queries of the events it recorded, both in slow traces and in the "Slow events" panel. (patch [a1c3033e](https://github.com/appsignal/appsignal-ruby/commit/a1c3033e1b255371a2d71d4519506a67dbfa2b82))
40
- - Prevent `gc` events from appearing in the "Slow events" panel. (patch [a1c3033e](https://github.com/appsignal/appsignal-ruby/commit/a1c3033e1b255371a2d71d4519506a67dbfa2b82))
41
- - Report Delayed Job jobs that fail to load. Before this change, a job whose
42
- payload could not be deserialized was not reported to AppSignal at all.
11
+ Collector mode requires Ruby 3.1 or newer, and the OpenTelemetry gems, which are not installed by default. Add the `appsignal-opentelemetry` gem alongside `appsignal` to install them. When they are missing or too old, AppSignal logs a warning and keeps reporting through its agent.
43
12
 
44
- This can happen when a deploy removes or renames a job class while jobs of that
45
- class are still queued. Those jobs are now reported as failed, with the
46
- `Delayed::DeserializationError` they raised, and are named after the class
47
- recorded in the job's handler. When even that cannot be read, they are named
48
- `DelayedJobInternal`.
13
+ (major [84d83b65](https://github.com/appsignal/appsignal-ruby/commit/84d83b657d65a93859ba73f295216a3b0ee9cab1), [90768626](https://github.com/appsignal/appsignal-ruby/commit/9076862677444c7772e6f8fbe1e3d5a646a4849d))
14
+ - Add configuration options that map to OpenTelemetry resource attributes in collector mode: `service_name`, `filter_attributes`, `filter_function_parameters`, `filter_request_query_parameters`, `filter_request_payload`, `response_headers`, `send_function_parameters`, `send_request_query_parameters` and `send_request_payload`.
49
15
 
50
- (patch [ea294440](https://github.com/appsignal/appsignal-ruby/commit/ea29444069ef78347ad1e8266869b7d9aa2caa50))
51
- - Record a single event for a bulk enqueue of Active Job jobs. Before this change,
52
- enqueuing jobs with `ActiveJob.perform_all_later` would record an event for the
53
- batch and, if the adapter was instrumented with AppSignal, another event for each
54
- job in it. A job that slices a large collection and enqueues it in batches was
55
- therefore reported with an event per job enqueued, where before version 4.9.0 it
56
- had one event per batch.
16
+ In collector mode, existing options are passed to the collector as resource attributes as well: `name`, environment, `hostname`, `revision`, `ignore_actions`, `ignore_errors`, `ignore_namespaces`, `request_headers`, `filter_session_data` and `send_session_data`.
57
17
 
58
- A bulk enqueue is now recorded as a single `enqueue_all.active_job` event, named
59
- after the job class when every job in the batch shares one.
18
+ Setting any of these without `collector_endpoint`, or setting `filter_parameters`, `filter_metadata` or `send_params` with it, logs a warning at startup.
60
19
 
61
- (patch [fe82dc60](https://github.com/appsignal/appsignal-ruby/commit/fe82dc60bc8b52d466c0c9b673adbae29f79449e))
20
+ (minor [84d83b65](https://github.com/appsignal/appsignal-ruby/commit/84d83b657d65a93859ba73f295216a3b0ee9cab1), [90768626](https://github.com/appsignal/appsignal-ruby/commit/9076862677444c7772e6f8fbe1e3d5a646a4849d))
62
21
 
63
22
  ## 4.10.1
64
23
 
data/README.md CHANGED
@@ -240,8 +240,7 @@ configurations you need to run the spec suite with a specific Gemfile.
240
240
  BUNDLE_GEMFILE=gemfiles/capistrano2.gemfile bundle exec rspec
241
241
  BUNDLE_GEMFILE=gemfiles/capistrano3.gemfile bundle exec rspec
242
242
  BUNDLE_GEMFILE=gemfiles/dry-monitor.gemfile bundle exec rspec
243
- BUNDLE_GEMFILE=gemfiles/grape-3.gemfile bundle exec rspec
244
- BUNDLE_GEMFILE=gemfiles/grape-4.gemfile bundle exec rspec
243
+ BUNDLE_GEMFILE=gemfiles/grape.gemfile bundle exec rspec
245
244
  BUNDLE_GEMFILE=gemfiles/hanami.gemfile bundle exec rspec
246
245
  BUNDLE_GEMFILE=gemfiles/http5.gemfile bundle exec rspec
247
246
  BUNDLE_GEMFILE=gemfiles/no_dependencies.gemfile bundle exec rspec
data/Rakefile CHANGED
@@ -72,7 +72,50 @@ GITHUB_ACTION_WORKFLOW_FILE = ".github/workflows/ci.yml"
72
72
  PRIMARY_JOB_GEMSET = "no_dependencies"
73
73
  DEFAULT_RUNS_ON = "ubuntu-latest"
74
74
 
75
+ COLLECTOR_GEMFILE_PARTIAL = "collector.rb"
76
+
75
77
  namespace :build_matrix do
78
+ namespace :gemfiles do
79
+ # Generates a `<base>-collector.gemfile` next to each base gemfile. The
80
+ # variant layers the optional OpenTelemetry gems (`gemfiles/collector.rb`)
81
+ # on top of the base, so collector-mode test runs resolve them while the
82
+ # base gemfiles (and the gemspec) stay OpenTelemetry-free. Regenerate
83
+ # whenever a base gemfile is added or removed.
84
+ task :generate do
85
+ base_gemfiles =
86
+ Dir["gemfiles/*.gemfile"]
87
+ .map { |path| File.basename(path) }
88
+ .reject { |name| name.end_with?("-collector.gemfile") }
89
+ .sort
90
+
91
+ base_gemfiles.each do |base|
92
+ name = base.sub(/\.gemfile\z/, "")
93
+ contents =
94
+ "# DO NOT EDIT\n" \
95
+ "# This is a generated file by the " \
96
+ "`rake build_matrix:gemfiles:generate` task.\n" \
97
+ "# It layers the optional OpenTelemetry gems (gemfiles/" \
98
+ "#{COLLECTOR_GEMFILE_PARTIAL}) on top of #{base}.\n" \
99
+ "\n" \
100
+ "eval_gemfile File.expand_path(#{base.inspect}, __dir__)\n" \
101
+ "eval_gemfile File.expand_path(" \
102
+ "#{COLLECTOR_GEMFILE_PARTIAL.inspect}, __dir__)\n"
103
+ File.write("gemfiles/#{name}-collector.gemfile", contents)
104
+ end
105
+
106
+ puts "Generated #{base_gemfiles.count} `-collector` gemfiles."
107
+ end
108
+
109
+ task :validate => :generate do
110
+ output = `git status --porcelain gemfiles`
111
+ if output.include?("-collector.gemfile")
112
+ puts "The `-collector` gemfiles are out of date. The changes were not committed."
113
+ puts "Please run `rake build_matrix:gemfiles:generate` and commit the changes."
114
+ exit 1
115
+ end
116
+ end
117
+ end
118
+
76
119
  namespace :github do
77
120
  task :generate do
78
121
  yaml = YAML.load_file("build_matrix.yml")
@@ -113,6 +156,21 @@ namespace :build_matrix do
113
156
  job["steps"] << test_step
114
157
  builds[build_matrix_key(ruby["ruby"], :ruby_gem => ruby_gem["gem"])] = job
115
158
  end
159
+
160
+ # On collector-capable Rubies, additionally run the gem's
161
+ # `-collector` gemfile (base gems + optional OpenTelemetry gems) so
162
+ # collector-mode specs are exercised. These always depend on the
163
+ # primary job for the Ruby version and run on Ubuntu only.
164
+ next unless collector_ruby?(matrix, ruby_version)
165
+
166
+ collector_gem = "#{ruby_gem["gem"]}-collector"
167
+ collector_job = build_job(ruby_version, :ruby_gem => collector_gem)
168
+ collector_job["env"] = matrix["env"]
169
+ .merge("BUNDLE_GEMFILE" => "gemfiles/#{collector_gem}.gemfile")
170
+ collector_job["needs"] = build_matrix_key(ruby["ruby"])
171
+ collector_job["steps"] << test_step
172
+ builds[build_matrix_key(ruby["ruby"], :ruby_gem => collector_gem)] =
173
+ collector_job
116
174
  end
117
175
 
118
176
  # Add build for macOS
@@ -191,6 +249,14 @@ namespace :build_matrix do
191
249
  out << "#{bundler_version} #{gemfile_env} ./script/bundler_wrapper install --quiet || { echo 'Bundling failed'; exit 1; }"
192
250
  out << "echo 'Running #{gemfile} in #{ruby_version}'"
193
251
  out << "#{bundler_version} #{gemfile_env} ./script/bundler_wrapper exec rspec || { echo 'Running specs failed'; exit 1; }"
252
+
253
+ next unless collector_ruby?(matrix, ruby_version)
254
+
255
+ collector_env = "env BUNDLE_GEMFILE=gemfiles/#{gemfile}-collector.gemfile"
256
+ out << "echo 'Bundling #{gemfile}-collector in #{ruby_version}'"
257
+ out << "#{bundler_version} #{collector_env} ./script/bundler_wrapper install --quiet || { echo 'Bundling failed'; exit 1; }"
258
+ out << "echo 'Running #{gemfile}-collector in #{ruby_version}'"
259
+ out << "#{bundler_version} #{collector_env} ./script/bundler_wrapper exec rspec || { echo 'Running specs failed'; exit 1; }"
194
260
  end
195
261
  # rubocop:enable Layout/LineLength
196
262
  out << ""
@@ -207,6 +273,10 @@ namespace :build_matrix do
207
273
  end
208
274
  end
209
275
 
276
+ def collector_ruby?(matrix, ruby_version)
277
+ Array(matrix.dig("collector", "ruby")).include?(ruby_version)
278
+ end
279
+
210
280
  def gemset_for_ruby(ruby, matrix)
211
281
  gems = matrix["gems"]
212
282
  if ruby["gems"]
@@ -288,6 +358,23 @@ namespace :build do
288
358
  desc "Build all gem versions"
289
359
  task :all => ["ruby:gem", "jruby:gem"]
290
360
 
361
+ desc "Build every package in this repository"
362
+ task :packages => :all do
363
+ # Build the companion gem by delegating to its own Rakefile rather than
364
+ # duplicating its build logic here. mono builds each package directly, so
365
+ # this task is only a convenience for developers building from the root.
366
+ #
367
+ # Clear the Bundler environment first so the sub-build resolves against the
368
+ # package's own Gemfile instead of inheriting this repository's
369
+ # BUNDLE_GEMFILE. Install its dependencies first, then build it.
370
+ Bundler.with_unbundled_env do
371
+ Dir.chdir("packages/opentelemetry") do
372
+ sh "bundle install"
373
+ sh "bundle exec rake build:all"
374
+ end
375
+ end
376
+ end
377
+
291
378
  desc "Clean up all gem build artifacts"
292
379
  task :clean do
293
380
  FileUtils.rm_rf File.expand_path("pkg", __dir__)
data/appsignal.gemspec CHANGED
@@ -7,6 +7,7 @@ IGNORED_PATHS = [
7
7
  ".changesets/",
8
8
  ".github/",
9
9
  "gemfiles/",
10
+ "packages/",
10
11
  "script/",
11
12
  "spec/",
12
13
 
@@ -60,14 +61,14 @@ Gem::Specification.new do |gem|
60
61
  # Needs 2.0+ because we rely on Rack::Events
61
62
  gem.add_dependency "rack", ">= 2.0.0"
62
63
 
64
+ # The OpenTelemetry SDK and OTLP exporters are *optional* and intentionally
65
+ # not declared here: they're only needed in collector mode (Ruby 3.1+), so
66
+ # bundling them would break Ruby 2.7 and burden non-collector users. Apps
67
+ # that enable collector mode add them to their own Gemfile; the minimum
68
+ # versions live in `lib/appsignal/opentelemetry/dependencies.rb` and are
69
+ # enforced at boot by `Appsignal::OpenTelemetry.configure`.
70
+
63
71
  gem.add_development_dependency "pry"
64
- # Reached through webmock's addressable. Version 7 requires Ruby 3.2 and
65
- # version 6 requires 3.0, so an older Ruby cannot resolve the development
66
- # dependencies unless this is held back. The cop guards the requirements of
67
- # the released gem, which a development dependency is not part of.
68
- # rubocop:disable Gemspec/RubyVersionGlobalsUsage
69
- gem.add_development_dependency "public_suffix", "< 6" if RUBY_VERSION < "3.2"
70
- # rubocop:enable Gemspec/RubyVersionGlobalsUsage
71
72
  gem.add_development_dependency "rake", ">= 12"
72
73
  gem.add_development_dependency "rspec", "~> 3.8"
73
74
  gem.add_development_dependency "rubocop", "~> 1.87.0"
data/build_matrix.yml CHANGED
@@ -107,6 +107,18 @@ matrix:
107
107
  JRUBY_OPTS: ""
108
108
  COV: "1"
109
109
 
110
+ # Ruby versions that additionally run each gem's `-collector` gemfile (the
111
+ # optional OpenTelemetry gems layered on top). Collector mode requires Ruby
112
+ # 3.1+ (the OTel metrics SDK's fork hooks rely on `Process._fork`) and does
113
+ # not support JRuby's forking model, so only these versions are listed.
114
+ collector:
115
+ ruby:
116
+ - "4.0.0"
117
+ - "3.4.1"
118
+ - "3.3.4"
119
+ - "3.2.5"
120
+ - "3.1.6"
121
+
110
122
  gemsets: # By default all gems are tested
111
123
  none:
112
124
  - "no_dependencies"
@@ -162,13 +174,7 @@ matrix:
162
174
  - "3.2.5"
163
175
  - "3.1.6"
164
176
  - "3.0.7"
165
- - gem: "grape-3"
166
- - gem: "grape-4"
167
- only:
168
- ruby:
169
- - "4.0.0"
170
- - "3.4.1"
171
- - "3.3.4"
177
+ - gem: "grape"
172
178
  - gem: "hanami-2.0"
173
179
  only:
174
180
  ruby:
@@ -287,6 +293,7 @@ matrix:
287
293
  - "3.4.1"
288
294
  - "3.3.4"
289
295
  - "3.2.5"
296
+ - gem: "mongo"
290
297
  - gem: "resque-2"
291
298
  - gem: "resque-3"
292
299
  only:
data/ext/agent.rb CHANGED
@@ -6,7 +6,7 @@
6
6
  # Modifications to this file will be overwritten with the next agent release.
7
7
 
8
8
  APPSIGNAL_AGENT_CONFIG = {
9
- "version" => "0.37.1",
9
+ "version" => "0.36.12",
10
10
  "mirrors" => [
11
11
  "https://d135dj0rjqvssy.cloudfront.net",
12
12
  "https://appsignal-agent-releases.global.ssl.fastly.net"
@@ -14,131 +14,131 @@ APPSIGNAL_AGENT_CONFIG = {
14
14
  "triples" => {
15
15
  "x86_64-darwin" => {
16
16
  "static" => {
17
- "checksum" => "a29834f6a305a0baedbf5bd3f25c28feca45b3a175029d655ece7224515c206a",
17
+ "checksum" => "a63189a2ba6b500e038e5658f97478ceae27a956baa2f89a4e79ee5a1dadace6",
18
18
  "filename" => "appsignal-x86_64-darwin-all-static.tar.gz"
19
19
  },
20
20
  "dynamic" => {
21
- "checksum" => "7450ed4679d7ca425d7fb7563931a9ca73365ac03ac62ace1880d0a5de2fe06d",
21
+ "checksum" => "ecfb108dcc4d10f442415debaceed6d2e568b44ab938cf0ed6fee3ccfbdc5379",
22
22
  "filename" => "appsignal-x86_64-darwin-all-dynamic.tar.gz"
23
23
  }
24
24
  },
25
25
  "universal-darwin" => {
26
26
  "static" => {
27
- "checksum" => "a29834f6a305a0baedbf5bd3f25c28feca45b3a175029d655ece7224515c206a",
27
+ "checksum" => "a63189a2ba6b500e038e5658f97478ceae27a956baa2f89a4e79ee5a1dadace6",
28
28
  "filename" => "appsignal-x86_64-darwin-all-static.tar.gz"
29
29
  },
30
30
  "dynamic" => {
31
- "checksum" => "7450ed4679d7ca425d7fb7563931a9ca73365ac03ac62ace1880d0a5de2fe06d",
31
+ "checksum" => "ecfb108dcc4d10f442415debaceed6d2e568b44ab938cf0ed6fee3ccfbdc5379",
32
32
  "filename" => "appsignal-x86_64-darwin-all-dynamic.tar.gz"
33
33
  }
34
34
  },
35
35
  "aarch64-darwin" => {
36
36
  "static" => {
37
- "checksum" => "53198c2f10fb56565ceece6632ec0cd38f30e7fef3df79094f11381f4b07f8a6",
37
+ "checksum" => "d23d6cc15e7df1c810b55dc33905002c5a1d6bc3f7cb10690d7e21398aabdac0",
38
38
  "filename" => "appsignal-aarch64-darwin-all-static.tar.gz"
39
39
  },
40
40
  "dynamic" => {
41
- "checksum" => "18fd2861c72fdb1ed5261cad90667923d0b2299ebd3511114d10416ecbd9998c",
41
+ "checksum" => "b4f9bf20f87fc7ddd8cc307646a956f734a2153323cc01487ced322263f32c2b",
42
42
  "filename" => "appsignal-aarch64-darwin-all-dynamic.tar.gz"
43
43
  }
44
44
  },
45
45
  "arm64-darwin" => {
46
46
  "static" => {
47
- "checksum" => "53198c2f10fb56565ceece6632ec0cd38f30e7fef3df79094f11381f4b07f8a6",
47
+ "checksum" => "d23d6cc15e7df1c810b55dc33905002c5a1d6bc3f7cb10690d7e21398aabdac0",
48
48
  "filename" => "appsignal-aarch64-darwin-all-static.tar.gz"
49
49
  },
50
50
  "dynamic" => {
51
- "checksum" => "18fd2861c72fdb1ed5261cad90667923d0b2299ebd3511114d10416ecbd9998c",
51
+ "checksum" => "b4f9bf20f87fc7ddd8cc307646a956f734a2153323cc01487ced322263f32c2b",
52
52
  "filename" => "appsignal-aarch64-darwin-all-dynamic.tar.gz"
53
53
  }
54
54
  },
55
55
  "arm-darwin" => {
56
56
  "static" => {
57
- "checksum" => "53198c2f10fb56565ceece6632ec0cd38f30e7fef3df79094f11381f4b07f8a6",
57
+ "checksum" => "d23d6cc15e7df1c810b55dc33905002c5a1d6bc3f7cb10690d7e21398aabdac0",
58
58
  "filename" => "appsignal-aarch64-darwin-all-static.tar.gz"
59
59
  },
60
60
  "dynamic" => {
61
- "checksum" => "18fd2861c72fdb1ed5261cad90667923d0b2299ebd3511114d10416ecbd9998c",
61
+ "checksum" => "b4f9bf20f87fc7ddd8cc307646a956f734a2153323cc01487ced322263f32c2b",
62
62
  "filename" => "appsignal-aarch64-darwin-all-dynamic.tar.gz"
63
63
  }
64
64
  },
65
65
  "aarch64-linux" => {
66
66
  "static" => {
67
- "checksum" => "64fc4b0b48d780eb6721421a4d2ef3e4b94ee763266ad5a2768acdf3d9feadd7",
67
+ "checksum" => "0a277e682f1568fbc54df849a46f21f155643b40c285a5bd30294c9d046e49c2",
68
68
  "filename" => "appsignal-aarch64-linux-all-static.tar.gz"
69
69
  },
70
70
  "dynamic" => {
71
- "checksum" => "816c9b77f8782074fd04c71d094d6c8b6127ab3f501303cb80e22a31334b876c",
71
+ "checksum" => "94e0193908955e7a3a274a37947e234c5b038aa26c0ea9b371a08fd63441a940",
72
72
  "filename" => "appsignal-aarch64-linux-all-dynamic.tar.gz"
73
73
  }
74
74
  },
75
75
  "i686-linux" => {
76
76
  "static" => {
77
- "checksum" => "ea6544e43502d0ec49a708343483244a5ec457ae4c89752a295b238c3e62440c",
77
+ "checksum" => "0d4536a2b1c9b6915f0f8597bd858988e284e7dbc4a14488332ffa7e401a1134",
78
78
  "filename" => "appsignal-i686-linux-all-static.tar.gz"
79
79
  },
80
80
  "dynamic" => {
81
- "checksum" => "8e40de0254d822f58610c00a047fdd34753d71c2c2f9c9e75afb228c4768857a",
81
+ "checksum" => "c5df66876e4611d5ef8798013f0188469cbdea6753a9b9d6cf54bd858e6331e9",
82
82
  "filename" => "appsignal-i686-linux-all-dynamic.tar.gz"
83
83
  }
84
84
  },
85
85
  "x86-linux" => {
86
86
  "static" => {
87
- "checksum" => "ea6544e43502d0ec49a708343483244a5ec457ae4c89752a295b238c3e62440c",
87
+ "checksum" => "0d4536a2b1c9b6915f0f8597bd858988e284e7dbc4a14488332ffa7e401a1134",
88
88
  "filename" => "appsignal-i686-linux-all-static.tar.gz"
89
89
  },
90
90
  "dynamic" => {
91
- "checksum" => "8e40de0254d822f58610c00a047fdd34753d71c2c2f9c9e75afb228c4768857a",
91
+ "checksum" => "c5df66876e4611d5ef8798013f0188469cbdea6753a9b9d6cf54bd858e6331e9",
92
92
  "filename" => "appsignal-i686-linux-all-dynamic.tar.gz"
93
93
  }
94
94
  },
95
95
  "x86_64-linux" => {
96
96
  "static" => {
97
- "checksum" => "bc04fc8691b8950d20776646117fd7a217a3267d4eac14b2c5f446ed8f9fcf99",
97
+ "checksum" => "eec59a3e46dd5d5baff044465b4e314f21edf6270500bf24e3bc50afcee5f2e2",
98
98
  "filename" => "appsignal-x86_64-linux-all-static.tar.gz"
99
99
  },
100
100
  "dynamic" => {
101
- "checksum" => "fe86688bd2ea0ad5cf6df1c71d7b041c375e5192c572b4bac540c7c36576ba1a",
101
+ "checksum" => "37471e17c5cb9f252d039cfbc0c01d570698c2245f6c8783fd2778e640b59a54",
102
102
  "filename" => "appsignal-x86_64-linux-all-dynamic.tar.gz"
103
103
  }
104
104
  },
105
105
  "x86_64-linux-musl" => {
106
106
  "static" => {
107
- "checksum" => "5cd6d3f106d6e34ad6558d5191241860345dfd3e0ad9daaa798c0781e17c142a",
107
+ "checksum" => "4454ec095ad14813bedea20a110a26235dbc6e8e33538219fad325792c0d888e",
108
108
  "filename" => "appsignal-x86_64-linux-musl-all-static.tar.gz"
109
109
  },
110
110
  "dynamic" => {
111
- "checksum" => "3fa17e5a1e325842f89f14ddfbc48dd7286724a765859c073475633726364f4e",
111
+ "checksum" => "4c21039b077b0c292d530210e077d942694f4c533d3761ed11e27ca932215131",
112
112
  "filename" => "appsignal-x86_64-linux-musl-all-dynamic.tar.gz"
113
113
  }
114
114
  },
115
115
  "aarch64-linux-musl" => {
116
116
  "static" => {
117
- "checksum" => "86c3c6356cac89c4030e427915c3aad7ea804278835bd4a5cc75ebbdd18f5dbd",
117
+ "checksum" => "048a55f0f10087e7954559d6cd09b371a0b532673f7ca769bcfde5729e297a72",
118
118
  "filename" => "appsignal-aarch64-linux-musl-all-static.tar.gz"
119
119
  },
120
120
  "dynamic" => {
121
- "checksum" => "66c5e30dad3f804261953c9a0ad7c15ef183163fe863894f524ea9bb34b6c9a0",
121
+ "checksum" => "8dc336cffcb2cffe85daa8c70b02b0af7e626ed81c8873cdbb627216a411d59a",
122
122
  "filename" => "appsignal-aarch64-linux-musl-all-dynamic.tar.gz"
123
123
  }
124
124
  },
125
125
  "x86_64-freebsd" => {
126
126
  "static" => {
127
- "checksum" => "0428134ff69b924900b4cda8d16b181870ef4eced5cb501e9ac2a952f9c52580",
127
+ "checksum" => "d81d039a3c1936bd393a6140b46f48092da31600b0311eab819acd777521a588",
128
128
  "filename" => "appsignal-x86_64-freebsd-all-static.tar.gz"
129
129
  },
130
130
  "dynamic" => {
131
- "checksum" => "90869b3bfe783dfcccef58814d7cd8785161ad9b6b552fd2de9a43ce8bd2bae5",
131
+ "checksum" => "cc345d4a791200e5af53c533e7ad83d278e98ee0becb5b54e502ba8934094372",
132
132
  "filename" => "appsignal-x86_64-freebsd-all-dynamic.tar.gz"
133
133
  }
134
134
  },
135
135
  "amd64-freebsd" => {
136
136
  "static" => {
137
- "checksum" => "0428134ff69b924900b4cda8d16b181870ef4eced5cb501e9ac2a952f9c52580",
137
+ "checksum" => "d81d039a3c1936bd393a6140b46f48092da31600b0311eab819acd777521a588",
138
138
  "filename" => "appsignal-x86_64-freebsd-all-static.tar.gz"
139
139
  },
140
140
  "dynamic" => {
141
- "checksum" => "90869b3bfe783dfcccef58814d7cd8785161ad9b6b552fd2de9a43ce8bd2bae5",
141
+ "checksum" => "cc345d4a791200e5af53c533e7ad83d278e98ee0becb5b54e502ba8934094372",
142
142
  "filename" => "appsignal-x86_64-freebsd-all-dynamic.tar.gz"
143
143
  }
144
144
  }
@@ -834,10 +834,23 @@ static VALUE add_distribution_value(VALUE self, VALUE key, VALUE value, VALUE ta
834
834
  return Qnil;
835
835
  }
836
836
 
837
+ // Per-thread running total of object allocations, incremented on every Ruby
838
+ // NEWOBJ event. Thread-local because MRI maps each Ruby thread to its own OS
839
+ // thread, so this attributes allocations to the thread doing the work, which is
840
+ // the thread the transaction runs on. Collector mode reads it through
841
+ // Appsignal::Extension.allocation_count and diffs two snapshots to get the
842
+ // allocations made during a transaction or an event.
843
+ static __thread unsigned long long appsignal_thread_allocation_count = 0;
844
+
837
845
  static void track_allocation(rb_event_flag_t flag, VALUE arg1, VALUE arg2, ID arg3, VALUE arg4) {
846
+ appsignal_thread_allocation_count++;
838
847
  appsignal_track_allocation();
839
848
  }
840
849
 
850
+ static VALUE allocation_count(VALUE self) {
851
+ return ULL2NUM(appsignal_thread_allocation_count);
852
+ }
853
+
841
854
  static VALUE install_allocation_event_hook(VALUE self) {
842
855
  // This event hook is only available on Ruby 2.1 and 2.2
843
856
  #if defined(RUBY_INTERNAL_EVENT_NEWOBJ)
@@ -956,6 +969,7 @@ void Init_appsignal_extension(void) {
956
969
 
957
970
  // Other helper methods
958
971
  rb_define_singleton_method(Extension, "install_allocation_event_hook", install_allocation_event_hook, 0);
972
+ rb_define_singleton_method(Extension, "allocation_count", allocation_count, 0);
959
973
  rb_define_singleton_method(Extension, "running_in_container?", running_in_container, 0);
960
974
  rb_define_singleton_method(Extension, "set_environment_metadata", set_environment_metadata, 2);
961
975
 
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "appsignal/metrics/extension_backend"
4
+ require "appsignal/metrics/opentelemetry_backend"
5
+ require "appsignal/logger/extension_backend"
6
+ require "appsignal/logger/opentelemetry_backend"
7
+ require "appsignal/transaction/base_backend"
8
+ require "appsignal/transaction/extension_backend"
9
+ require "appsignal/transaction/opentelemetry_backend"
10
+
11
+ module Appsignal
12
+ # @!visibility private
13
+ #
14
+ # Looks up the active backend for each AppSignal subsystem. In normal
15
+ # operation, subsystems route through the C-extension (and its agent).
16
+ # When collector mode is configured and the OpenTelemetry SDK has booted
17
+ # successfully, supported subsystems route through OTel instead.
18
+ #
19
+ # Centralizes the mode-check so per-subsystem call sites don't repeat the
20
+ # "if collector? then OTel else Extension" branch. Future subsystems plug
21
+ # in by adding one more lookup method here.
22
+ module Backends
23
+ class << self
24
+ def metrics
25
+ if collector?
26
+ Appsignal::Metrics::OpenTelemetryBackend
27
+ else
28
+ Appsignal::Metrics::ExtensionBackend
29
+ end
30
+ end
31
+
32
+ def logger
33
+ if collector?
34
+ Appsignal::Logger::OpenTelemetryBackend
35
+ else
36
+ Appsignal::Logger::ExtensionBackend
37
+ end
38
+ end
39
+
40
+ def transaction
41
+ if collector?
42
+ Appsignal::Transaction::OpenTelemetryBackend
43
+ else
44
+ Appsignal::Transaction::ExtensionBackend
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ def collector?
51
+ Appsignal.config&.collector_mode? || false
52
+ end
53
+ end
54
+ end
55
+ end
@@ -40,8 +40,6 @@ module Appsignal
40
40
  # @see https://docs.appsignal.com/support/debugging.html
41
41
  # Debugging AppSignal guide
42
42
  class Demo
43
- extend CLI::Helpers
44
-
45
43
  class << self
46
44
  # @param options [Hash]
47
45
  # @option options :environment [String] environment to load
@@ -49,9 +47,6 @@ module Appsignal
49
47
  # @return [void]
50
48
  def run(options = {})
51
49
  ENV["APPSIGNAL_APP_ENV"] = options[:environment] if options[:environment]
52
- # Load the host Rails app, if any, so that the AppSignal config file
53
- # can use the application when it is read.
54
- require_rails_app_if_present(options[:environment])
55
50
 
56
51
  puts "Sending demonstration sample data..."
57
52
  if Appsignal::Demo.transmit
@@ -189,15 +189,10 @@ module Appsignal
189
189
 
190
190
  def configure_appsignal(options)
191
191
  env_option = options.fetch(:environment, nil)
192
- # Mark app as Rails app
193
- data[:app][:rails] = true if rails_present?
194
192
  # Try and load the Rails app, if any.
195
193
  # This will configure AppSignal through the config file or an
196
194
  # initializer.
197
- require_rails_app_if_present(env_option) do |error|
198
- data[:app][:load_error] =
199
- "#{error.class}: #{error.message}\n#{error.backtrace.join("\n")}"
200
- end
195
+ require_rails_app_if_present(env_option)
201
196
 
202
197
  # No config loaded yet, try loading as normal
203
198
  Appsignal._load_config!(env_option) unless Appsignal.config
@@ -632,6 +627,43 @@ module Appsignal
632
627
  puts " Read error: #{path[:read_error]}"
633
628
  print_empty_line
634
629
  end
630
+
631
+ def print_empty_line
632
+ puts "\n"
633
+ end
634
+
635
+ def require_rails_app_if_present(env_option)
636
+ return unless rails_present?
637
+
638
+ # Set the environment given as an option to the diagnose CLI so the
639
+ # Rails app uses it when loaded.
640
+ ENV["_APPSIGNAL_CONFIG_FILE_ENV"] = env_option
641
+ # Mark app as Rails app
642
+ data[:app][:rails] = true
643
+ # Manually require the railtie, because it wasn't loaded when the CLI
644
+ # started and AppSignal loaded, because the `Rails` constant wasn't
645
+ # present.
646
+ require "appsignal/integrations/railtie"
647
+ # Start the Rails app, including railties and initializers.
648
+ require Appsignal::Utils::RailsHelper.environment_config_path
649
+ rescue LoadError, StandardError => error
650
+ print_empty_line
651
+ puts "ERROR: Error encountered while loading the Rails app"
652
+ puts "#{error.class}: #{error.message}"
653
+ puts error.backtrace
654
+ data[:app][:load_error] =
655
+ "#{error.class}: #{error.message}\n#{error.backtrace.join("\n")}"
656
+ ensure
657
+ ENV.delete("_APPSIGNAL_CONFIG_FILE_ENV")
658
+ end
659
+
660
+ def rails_present?
661
+ # Try and load the Rails gem
662
+ require "rails"
663
+ true
664
+ rescue LoadError
665
+ false
666
+ end
635
667
  end
636
668
  end
637
669
  end