appsignal 3.9.3 → 3.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +22 -19
  3. data/CHANGELOG.md +92 -0
  4. data/README.md +0 -1
  5. data/Rakefile +1 -1
  6. data/build_matrix.yml +10 -12
  7. data/gemfiles/webmachine1.gemfile +5 -4
  8. data/lib/appsignal/config.rb +4 -0
  9. data/lib/appsignal/environment.rb +6 -1
  10. data/lib/appsignal/helpers/instrumentation.rb +163 -1
  11. data/lib/appsignal/hooks/active_job.rb +1 -6
  12. data/lib/appsignal/integrations/padrino.rb +21 -25
  13. data/lib/appsignal/integrations/rake.rb +46 -12
  14. data/lib/appsignal/integrations/sidekiq.rb +1 -11
  15. data/lib/appsignal/integrations/webmachine.rb +15 -9
  16. data/lib/appsignal/rack/abstract_middleware.rb +49 -12
  17. data/lib/appsignal/rack/body_wrapper.rb +143 -0
  18. data/lib/appsignal/rack/generic_instrumentation.rb +5 -4
  19. data/lib/appsignal/rack/grape_middleware.rb +1 -1
  20. data/lib/appsignal/rack/hanami_middleware.rb +1 -1
  21. data/lib/appsignal/rack/instrumentation_middleware.rb +62 -0
  22. data/lib/appsignal/rack/rails_instrumentation.rb +1 -3
  23. data/lib/appsignal/rack/sinatra_instrumentation.rb +1 -3
  24. data/lib/appsignal/rack/streaming_listener.rb +13 -59
  25. data/lib/appsignal/rack.rb +31 -0
  26. data/lib/appsignal/transaction.rb +50 -8
  27. data/lib/appsignal/version.rb +1 -1
  28. data/lib/appsignal.rb +3 -1
  29. data/spec/lib/appsignal/config_spec.rb +1 -0
  30. data/spec/lib/appsignal/hooks/rake_spec.rb +100 -17
  31. data/spec/lib/appsignal/integrations/padrino_spec.rb +181 -131
  32. data/spec/lib/appsignal/integrations/sinatra_spec.rb +10 -2
  33. data/spec/lib/appsignal/integrations/webmachine_spec.rb +65 -17
  34. data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +96 -8
  35. data/spec/lib/appsignal/rack/body_wrapper_spec.rb +263 -0
  36. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +70 -17
  37. data/spec/lib/appsignal/rack/grape_middleware_spec.rb +1 -1
  38. data/spec/lib/appsignal/rack/instrumentation_middleware_spec.rb +38 -0
  39. data/spec/lib/appsignal/rack/streaming_listener_spec.rb +43 -120
  40. data/spec/lib/appsignal/transaction_spec.rb +163 -4
  41. data/spec/lib/appsignal_spec.rb +197 -6
  42. data/spec/support/mocks/dummy_app.rb +1 -1
  43. metadata +8 -4
  44. data/support/check_versions +0 -22
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f0c44e1ac2363e7ac8079dfe5141c24243fb5841a4cf39b9844545a57543236a
4
- data.tar.gz: 7ba546cf4f4a92c2ae190ba3e697bf97e34c0bcd01592830285cfaf369503c9c
3
+ metadata.gz: 4a4767b1d66b7aa4d47b79e83265b1e2631b9733f730e392b109d9d563013c79
4
+ data.tar.gz: 231bc55dfcd8084175fb505470b266937363de1e833852dd539d2970aad36d22
5
5
  SHA512:
6
- metadata.gz: f969c4bb7ff803e02c6b6076287531712aa117b3d0bf95c2e0384ef6ed13363150cde6bb67ad92ce70022e04f4ec327bc788afe1cce3a00206ee8d73fabea0d5
7
- data.tar.gz: '0967f97eba597c995555beb7ffa930678e0f4ce7f4e26a4da02f59571313c52983b747259dd861cc602180d0bb02f238608ac095f44439f4ad6c3d1df8089b0c'
6
+ metadata.gz: 3116383c605eb524838419ca4911ad2a06ef2b2289d1b88705107c51595edcc749270fa824bc79552c6e255524409630ab477fd9fd6ab72fabf3e7a9ebd6025a
7
+ data.tar.gz: 471f59339ae58c4a45bcad29560e04397dd646efa7b9269167ed142c773c92018e2e34288d931c14c2a4ec3045f068f760e687179034464a8dda3001fb689244
@@ -15,6 +15,8 @@ name: Ruby gem CI
15
15
  - opened
16
16
  - reopened
17
17
  - synchronize
18
+ schedule:
19
+ - cron: 0 0 * * 1-5
18
20
  concurrency:
19
21
  group: "${{ github.workflow }}-${{ github.ref }}"
20
22
  cancel-in-progress: "${{ !contains(github.ref, 'main')}}"
@@ -22,6 +24,7 @@ jobs:
22
24
  lint-git:
23
25
  name: Git linter (Lintje)
24
26
  runs-on: ubuntu-latest
27
+ if: "${{ github.event_name != 'schedule' }}"
25
28
  steps:
26
29
  - uses: actions/checkout@v4
27
30
  with:
@@ -2996,8 +2999,8 @@ jobs:
2996
2999
  JRUBY_OPTS: ''
2997
3000
  COV: '1'
2998
3001
  BUNDLE_GEMFILE: gemfiles/redis-5.gemfile
2999
- ruby_jruby-9-4-1-0:
3000
- name: Ruby jruby-9.4.1.0
3002
+ ruby_jruby-9-4-7-0:
3003
+ name: Ruby jruby-9.4.7.0
3001
3004
  needs: validation
3002
3005
  runs-on: ubuntu-latest
3003
3006
  steps:
@@ -3006,7 +3009,7 @@ jobs:
3006
3009
  - name: Install Ruby
3007
3010
  uses: ruby/setup-ruby@v1
3008
3011
  with:
3009
- ruby-version: jruby-9.4.1.0
3012
+ ruby-version: jruby-9.4.7.0
3010
3013
  bundler-cache: true
3011
3014
  - name: Install gem extension
3012
3015
  run: "./support/bundler_wrapper exec rake extension:install"
@@ -3025,9 +3028,9 @@ jobs:
3025
3028
  JRUBY_OPTS: ''
3026
3029
  COV: '1'
3027
3030
  BUNDLE_GEMFILE: gemfiles/no_dependencies.gemfile
3028
- ruby_jruby-9-4-1-0__rails-6-0:
3029
- name: Ruby jruby-9.4.1.0 - rails-6.0
3030
- needs: ruby_jruby-9-4-1-0
3031
+ ruby_jruby-9-4-7-0__rails-6-0:
3032
+ name: Ruby jruby-9.4.7.0 - rails-6.0
3033
+ needs: ruby_jruby-9-4-7-0
3031
3034
  runs-on: ubuntu-latest
3032
3035
  steps:
3033
3036
  - name: Check out repository
@@ -3035,7 +3038,7 @@ jobs:
3035
3038
  - name: Install Ruby
3036
3039
  uses: ruby/setup-ruby@v1
3037
3040
  with:
3038
- ruby-version: jruby-9.4.1.0
3041
+ ruby-version: jruby-9.4.7.0
3039
3042
  bundler-cache: true
3040
3043
  - name: Install gem extension
3041
3044
  run: "./support/bundler_wrapper exec rake extension:install"
@@ -3052,9 +3055,9 @@ jobs:
3052
3055
  JRUBY_OPTS: ''
3053
3056
  COV: '1'
3054
3057
  BUNDLE_GEMFILE: gemfiles/rails-6.0.gemfile
3055
- ruby_jruby-9-4-1-0__rails-6-1:
3056
- name: Ruby jruby-9.4.1.0 - rails-6.1
3057
- needs: ruby_jruby-9-4-1-0
3058
+ ruby_jruby-9-4-7-0__rails-6-1:
3059
+ name: Ruby jruby-9.4.7.0 - rails-6.1
3060
+ needs: ruby_jruby-9-4-7-0
3058
3061
  runs-on: ubuntu-latest
3059
3062
  steps:
3060
3063
  - name: Check out repository
@@ -3062,7 +3065,7 @@ jobs:
3062
3065
  - name: Install Ruby
3063
3066
  uses: ruby/setup-ruby@v1
3064
3067
  with:
3065
- ruby-version: jruby-9.4.1.0
3068
+ ruby-version: jruby-9.4.7.0
3066
3069
  bundler-cache: true
3067
3070
  - name: Install gem extension
3068
3071
  run: "./support/bundler_wrapper exec rake extension:install"
@@ -3079,9 +3082,9 @@ jobs:
3079
3082
  JRUBY_OPTS: ''
3080
3083
  COV: '1'
3081
3084
  BUNDLE_GEMFILE: gemfiles/rails-6.1.gemfile
3082
- ruby_jruby-9-4-1-0__rails-7-0:
3083
- name: Ruby jruby-9.4.1.0 - rails-7.0
3084
- needs: ruby_jruby-9-4-1-0
3085
+ ruby_jruby-9-4-7-0__rails-7-0:
3086
+ name: Ruby jruby-9.4.7.0 - rails-7.0
3087
+ needs: ruby_jruby-9-4-7-0
3085
3088
  runs-on: ubuntu-latest
3086
3089
  steps:
3087
3090
  - name: Check out repository
@@ -3089,7 +3092,7 @@ jobs:
3089
3092
  - name: Install Ruby
3090
3093
  uses: ruby/setup-ruby@v1
3091
3094
  with:
3092
- ruby-version: jruby-9.4.1.0
3095
+ ruby-version: jruby-9.4.7.0
3093
3096
  bundler-cache: true
3094
3097
  - name: Install gem extension
3095
3098
  run: "./support/bundler_wrapper exec rake extension:install"
@@ -3106,9 +3109,9 @@ jobs:
3106
3109
  JRUBY_OPTS: ''
3107
3110
  COV: '1'
3108
3111
  BUNDLE_GEMFILE: gemfiles/rails-7.0.gemfile
3109
- ruby_jruby-9-4-1-0__rails-7-1:
3110
- name: Ruby jruby-9.4.1.0 - rails-7.1
3111
- needs: ruby_jruby-9-4-1-0
3112
+ ruby_jruby-9-4-7-0__rails-7-1:
3113
+ name: Ruby jruby-9.4.7.0 - rails-7.1
3114
+ needs: ruby_jruby-9-4-7-0
3112
3115
  runs-on: ubuntu-latest
3113
3116
  steps:
3114
3117
  - name: Check out repository
@@ -3116,7 +3119,7 @@ jobs:
3116
3119
  - name: Install Ruby
3117
3120
  uses: ruby/setup-ruby@v1
3118
3121
  with:
3119
- ruby-version: jruby-9.4.1.0
3122
+ ruby-version: jruby-9.4.7.0
3120
3123
  bundler-cache: true
3121
3124
  - name: Install gem extension
3122
3125
  run: "./support/bundler_wrapper exec rake extension:install"
data/CHANGELOG.md CHANGED
@@ -1,5 +1,97 @@
1
1
  # AppSignal for Ruby gem Changelog
2
2
 
3
+ ## 3.10.0
4
+
5
+ _Published on 2024-07-08._
6
+
7
+ ### Added
8
+
9
+ - Add our new recommended Rack instrumentation middleware. If an app is using the `Appsignal::Rack::GenericInstrumentation` middleware, please update it to use `Appsignal::Rack::InstrumentationMiddleware` instead.
10
+
11
+ This new middleware will not report all requests under the "unknown" action if no action name is set. To set an action name, call the `Appsignal.set_action` helper from the app.
12
+
13
+ ```ruby
14
+ # config.ru
15
+
16
+ # Setup AppSignal
17
+
18
+ use Appsignal::Rack::InstrumentationMiddleware
19
+
20
+ # Run app
21
+ ```
22
+
23
+ (minor [f2596781](https://github.com/appsignal/appsignal-ruby/commit/f259678111067bd3d7cf60552201f4d4f95a99d6))
24
+ - Add Rake task performance instrumentation. Configure the `enable_rake_performance_instrumentation` option to `true` to enable Rake task instrumentation for both error and performance monitoring. To ignore specific Rake tasks, configure `ignore_actions` to include the name of the Rake task. (minor [63c9aeed](https://github.com/appsignal/appsignal-ruby/commit/63c9aeed978fcd0942238772c2e441b33e12e16a))
25
+ - Add instrumentation to Rack responses, including streaming responses. New `process_response_body.rack` and `close_response_body.rack` events will be shown in the event timeline. These events show how long it takes to complete responses, depending on the response implementation, and when the response is closed.
26
+
27
+ This Sinatra route with a streaming response will be better instrumented, for example:
28
+
29
+ ```ruby
30
+ get "/stream" do
31
+ stream do |out|
32
+ sleep 1
33
+ out << "1"
34
+ sleep 1
35
+ out << "2"
36
+ sleep 1
37
+ out << "3"
38
+ end
39
+ end
40
+ ```
41
+
42
+ (minor [bd2f037b](https://github.com/appsignal/appsignal-ruby/commit/bd2f037ba4840f4606373ee2fc11553f098d5436))
43
+ - Add the `Appsignal.report_error` helper to report errors. If you unsure whether to use the `Appsignal.set_error` or `Appsignal.send_error` helpers in what context, use `Appsignal.report_error` to always report the error. (minor [1502ea14](https://github.com/appsignal/appsignal-ruby/commit/1502ea147210d77dd4ee9d301c52ace30c2a6700))
44
+ - Support nested webmachine apps. If webmachine apps are nested in other AppSignal instrumentation it will now report the webmachine instrumentation as part of the parent transaction, reporting more runtime of the request. (patch [243d20ac](https://github.com/appsignal/appsignal-ruby/commit/243d20acd68a9e59a01d74e17abb910691667b25))
45
+ - Report the response status for Padrino requests as the `response_status` tag on samples, e.g. 200, 301, 500. This tag is visible on the sample detail page.
46
+ Report the response status for Padrino requests as the `response_status` metric.
47
+
48
+ (patch [9239c26b](https://github.com/appsignal/appsignal-ruby/commit/9239c26beb144b9d8bf094bc58030cd618633c38))
49
+ - Add support for nested Padrino apps. When a Padrino app is nested in another Padrino app, or another framework like Sinatra or Rails, it will now report the entire request. (patch [9239c26b](https://github.com/appsignal/appsignal-ruby/commit/9239c26beb144b9d8bf094bc58030cd618633c38))
50
+ - Add `Appsignal.set_params` helper. Set custom parameters on the current transaction with the `Appsignal.set_params` helper. Note that this will overwrite any request parameters that would be set automatically on the transaction. When this method is called multiple times, it will overwrite the previously set value.
51
+
52
+ ```ruby
53
+ Appsignal.set_params("param1" => "value1", "param2" => "value2")
54
+ ```
55
+
56
+ (patch [e8d73e8d](https://github.com/appsignal/appsignal-ruby/commit/e8d73e8d31264c44dd5db5d769be6b599b0ded48))
57
+ - Add `Appsignal.set_custom_data` helper to set custom data on the transaction. Previously, this could only be set with `Appsignal::Transaction.current.set_custom_data("custom_data", ...)`. This helper makes setting the custom data more convenient. (patch [875e4435](https://github.com/appsignal/appsignal-ruby/commit/875e4435ba97838f79a02ff456d3418bc012634a))
58
+ - Add `Appsignal.set_tags` helper as an alias for `Appsignal.tag_request`. This is a context independent named alias available on the Transaction class as well. (patch [1502ea14](https://github.com/appsignal/appsignal-ruby/commit/1502ea147210d77dd4ee9d301c52ace30c2a6700))
59
+ - Add a block argument to the `Appsignal.set_params` and `Appsignal::Transaction#set_params` helpers. When `set_params` is called with a block argument, the block is executed when the parameters are stored on the Transaction. This block is only called when the Transaction is sampled. Use this block argument to avoid having to parse parameters for every transaction, to speed things up when the transaction is not sampled.
60
+
61
+ ```ruby
62
+ Appsignal.set_params do
63
+ # Some slow code to parse parameters
64
+ JSON.parse('{"param1": "value1"}')
65
+ end
66
+ ```
67
+
68
+ (patch [1502ea14](https://github.com/appsignal/appsignal-ruby/commit/1502ea147210d77dd4ee9d301c52ace30c2a6700))
69
+
70
+ ### Deprecated
71
+
72
+ - Deprecate the `appsignal.action` and `appsignal.route` request env methods to set the transaction action name. Use the `Appsignal.set_action` helper instead.
73
+
74
+ ```ruby
75
+ # Before
76
+ env["appsignal.action"] = "POST /my-action"
77
+ env["appsignal.route"] = "POST /my-action"
78
+
79
+ # After
80
+ Appsignal.set_action("POST /my-action")
81
+ ```
82
+
83
+ (patch [1e6d0b31](https://github.com/appsignal/appsignal-ruby/commit/1e6d0b315577176d4dd37db0a8f5fde89c66e8a4))
84
+ - Deprecate the `Appsignal::Rack::StreamingListener` middleware. Use the `Appsignal::Rack::InstrumentationMiddleware` middleware instead. (patch [57d6fa33](https://github.com/appsignal/appsignal-ruby/commit/57d6fa3386d9a9720da76c7b899a332952d472e0))
85
+ - Deprecate the `Appsignal::Rack::GenericInstrumentation` middleware. Use the `Appsignal::Rack::InstrumentationMiddleware` middleware instead. See also the changelog entry about the `InstrumentationMiddleware`. (patch [1502ea14](https://github.com/appsignal/appsignal-ruby/commit/1502ea147210d77dd4ee9d301c52ace30c2a6700))
86
+
87
+ ### Fixed
88
+
89
+ - Fix issue with AppSignal getting stuck in a boot loop when loading the Padrino integration with: `require "appsignal/integrations/padrino"`
90
+ This could happen in nested applications, like a Padrino app in a Rails app. AppSignal will now use the first config AppSignal starts with.
91
+
92
+ (patch [10722b60](https://github.com/appsignal/appsignal-ruby/commit/10722b60d0ad9dc63b2c7add7d5ee8703190b8f0))
93
+ - Fix the deprecation warning of `Bundler.rubygems.all_specs` usage. (patch [1502ea14](https://github.com/appsignal/appsignal-ruby/commit/1502ea147210d77dd4ee9d301c52ace30c2a6700))
94
+
3
95
  ## 3.9.3
4
96
 
5
97
  _Published on 2024-07-02._
data/README.md CHANGED
@@ -9,7 +9,6 @@ issues.
9
9
  - [Ruby code documentation][ruby-doc]
10
10
  - [Support][contact]
11
11
 
12
- [![Build status](https://appsignal.semaphoreci.com/badges/appsignal-ruby/branches/main.svg)](https://appsignal.semaphoreci.com/projects/appsignal-ruby)
13
12
  [![Gem Version](https://badge.fury.io/rb/appsignal.svg)](http://badge.fury.io/rb/appsignal)
14
13
  [![Code Climate](https://codeclimate.com/github/appsignal/appsignal.png)](https://codeclimate.com/github/appsignal/appsignal)
15
14
 
data/Rakefile CHANGED
@@ -127,7 +127,7 @@ namespace :build_matrix do
127
127
  output = `git status`
128
128
  if output.include? GITHUB_ACTION_WORKFLOW_FILE
129
129
  puts "The `#{GITHUB_ACTION_WORKFLOW_FILE}` is modified. The changes were not committed."
130
- puts "Please run `rake build_matrix:semaphore:generate` and commit the changes."
130
+ puts "Please run `rake build_matrix:github:generate` and commit the changes."
131
131
  exit 1
132
132
  end
133
133
  end
data/build_matrix.yml CHANGED
@@ -2,14 +2,11 @@ github:
2
2
  name: Ruby gem CI
3
3
  "on":
4
4
  push:
5
- branches:
6
- - "main"
7
- - "develop"
5
+ branches: ["main", "develop"]
8
6
  pull_request:
9
- types:
10
- - opened
11
- - reopened
12
- - synchronize
7
+ types: [opened, reopened, synchronize]
8
+ schedule:
9
+ - cron: "0 0 * * 1-5"
13
10
 
14
11
  concurrency:
15
12
  group: ${{ github.workflow }}-${{ github.ref }}
@@ -19,6 +16,7 @@ github:
19
16
  lint-git:
20
17
  name: "Git linter (Lintje)"
21
18
  runs-on: ubuntu-latest
19
+ if: ${{ github.event_name != 'schedule' }}
22
20
  steps:
23
21
  - uses: actions/checkout@v4
24
22
  with:
@@ -93,7 +91,7 @@ matrix:
93
91
  - ruby: "3.1.3"
94
92
  - ruby: "3.0.5"
95
93
  - ruby: "2.7.8"
96
- - ruby: "jruby-9.4.1.0"
94
+ - ruby: "jruby-9.4.7.0"
97
95
  gems: "minimal"
98
96
  gems:
99
97
  - gem: "no_dependencies"
@@ -146,7 +144,7 @@ matrix:
146
144
  ruby:
147
145
  - "3.0.5"
148
146
  - "2.7.8"
149
- - "jruby-9.4.1.0"
147
+ - "jruby-9.4.7.0"
150
148
  - gem: "rails-6.1"
151
149
  only:
152
150
  ruby:
@@ -155,7 +153,7 @@ matrix:
155
153
  - "3.1.3"
156
154
  - "3.0.5"
157
155
  - "2.7.8"
158
- - "jruby-9.4.1.0"
156
+ - "jruby-9.4.7.0"
159
157
  - gem: "rails-7.0"
160
158
  only:
161
159
  ruby:
@@ -164,7 +162,7 @@ matrix:
164
162
  - "3.1.3"
165
163
  - "3.0.5"
166
164
  - "2.7.8"
167
- - "jruby-9.4.1.0"
165
+ - "jruby-9.4.7.0"
168
166
  - gem: "rails-7.1"
169
167
  only:
170
168
  ruby:
@@ -172,7 +170,7 @@ matrix:
172
170
  - "3.2.1"
173
171
  - "3.1.3"
174
172
  - "3.0.5"
175
- - "jruby-9.4.1.0"
173
+ - "jruby-9.4.7.0"
176
174
  - gem: "sequel"
177
175
  - gem: "sinatra"
178
176
  - gem: "webmachine1"
@@ -1,6 +1,7 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
- gem 'webmachine', '~> 1.6'
4
- gem 'webrick'
3
+ gem "i18n", "~> 0.0" # Lock to pre 1.x version as it's not compatible
4
+ gem "webmachine", "~> 1.6"
5
+ gem "webrick"
5
6
 
6
- gemspec :path => '../'
7
+ gemspec :path => "../"
@@ -23,6 +23,7 @@ module Appsignal
23
23
  :enable_gvl_global_timer => true,
24
24
  :enable_gvl_waiting_threads => true,
25
25
  :enable_rails_error_reporter => true,
26
+ :enable_rake_performance_instrumentation => false,
26
27
  :endpoint => "https://push.appsignal.com",
27
28
  :files_world_accessible => true,
28
29
  :filter_metadata => [],
@@ -83,6 +84,8 @@ module Appsignal
83
84
  "APPSIGNAL_ENABLE_GVL_GLOBAL_TIMER" => :enable_gvl_global_timer,
84
85
  "APPSIGNAL_ENABLE_GVL_WAITING_THREADS" => :enable_gvl_waiting_threads,
85
86
  "APPSIGNAL_ENABLE_RAILS_ERROR_REPORTER" => :enable_rails_error_reporter,
87
+ "APPSIGNAL_ENABLE_RAKE_PERFORMANCE_INSTRUMENTATION" =>
88
+ :enable_rake_performance_instrumentation,
86
89
  "APPSIGNAL_FILES_WORLD_ACCESSIBLE" => :files_world_accessible,
87
90
  "APPSIGNAL_FILTER_METADATA" => :filter_metadata,
88
91
  "APPSIGNAL_FILTER_PARAMETERS" => :filter_parameters,
@@ -150,6 +153,7 @@ module Appsignal
150
153
  APPSIGNAL_ENABLE_GVL_GLOBAL_TIMER
151
154
  APPSIGNAL_ENABLE_GVL_WAITING_THREADS
152
155
  APPSIGNAL_ENABLE_RAILS_ERROR_REPORTER
156
+ APPSIGNAL_ENABLE_RAKE_PERFORMANCE_INSTRUMENTATION
153
157
  APPSIGNAL_FILES_WORLD_ACCESSIBLE
154
158
  APPSIGNAL_INSTRUMENT_HTTP_RB
155
159
  APPSIGNAL_INSTRUMENT_NET_HTTP
@@ -121,7 +121,12 @@ module Appsignal
121
121
  def self.report_supported_gems
122
122
  return unless defined?(Bundler) # Do nothing if Bundler is not present
123
123
 
124
- bundle_gem_specs = ::Bundler.rubygems.all_specs
124
+ bundle_gem_specs =
125
+ if ::Bundler.rubygems.respond_to?(:installed_specs)
126
+ ::Bundler.rubygems.installed_specs
127
+ else
128
+ ::Bundler.rubygems.all_specs
129
+ end
125
130
  SUPPORTED_GEMS.each do |gem_name|
126
131
  gem_spec = bundle_gem_specs.find { |spec| spec.name == gem_name }
127
132
  next unless gem_spec
@@ -195,6 +195,7 @@ module Appsignal
195
195
  # used to send the error.
196
196
  # @return [void]
197
197
  #
198
+ # @see Transaction#report_error
198
199
  # @see https://docs.appsignal.com/ruby/instrumentation/exception-handling.html
199
200
  # Exception handling guide
200
201
  # @see https://docs.appsignal.com/ruby/instrumentation/tagging.html
@@ -294,6 +295,7 @@ module Appsignal
294
295
  # @return [void]
295
296
  #
296
297
  # @see Transaction#set_error
298
+ # @see Transaction#report_error
297
299
  # @see https://docs.appsignal.com/ruby/instrumentation/exception-handling.html
298
300
  # Exception handling guide
299
301
  # @since 0.6.6
@@ -334,6 +336,74 @@ module Appsignal
334
336
  alias :set_exception :set_error
335
337
  alias :add_exception :set_error
336
338
 
339
+ # Report an error.
340
+ #
341
+ # If a transaction is currently active, it will report the error on the
342
+ # current transaction. If no transaction is active, it will report the
343
+ # error on a new transaction.
344
+ #
345
+ # **Note**: If AppSignal is not active, no error is reported.
346
+ #
347
+ # **Note**: If the given exception argument is not an Exception subclass,
348
+ # it will not be reported.
349
+ #
350
+ # @example
351
+ # class SomeController < ApplicationController
352
+ # def create
353
+ # # Do something that breaks
354
+ # rescue => error
355
+ # Appsignal.report_error(error)
356
+ # end
357
+ # end
358
+ #
359
+ # @example Add more metadata to transaction
360
+ # Appsignal.report_error(error) do |transaction|
361
+ # transaction.set_namespace("my_namespace")
362
+ # transaction.set_action("my_action_name")
363
+ # transaction.set_params(:search_query => params[:search_query])
364
+ # transaction.set_tags(:key => "value")
365
+ # end
366
+ #
367
+ # @param exception [Exception] The error to add to the current
368
+ # transaction.
369
+ # @yield [transaction] yields block to allow modification of the
370
+ # transaction.
371
+ # @yieldparam transaction [Transaction] yields the AppSignal transaction
372
+ # used to report the error.
373
+ # @return [void]
374
+ #
375
+ # @see https://docs.appsignal.com/ruby/instrumentation/exception-handling.html
376
+ # Exception handling guide
377
+ # @since 3.10.0
378
+ def report_error(exception)
379
+ unless exception.is_a?(Exception)
380
+ internal_logger.error "Appsignal.report_error: Cannot set error. " \
381
+ "The given value is not an exception: #{exception.inspect}"
382
+ return
383
+ end
384
+ return unless active?
385
+
386
+ has_parent_transaction = Appsignal::Transaction.current?
387
+ transaction =
388
+ if has_parent_transaction
389
+ Appsignal::Transaction.current
390
+ else
391
+ Appsignal::Transaction.new(
392
+ SecureRandom.uuid,
393
+ Appsignal::Transaction::HTTP_REQUEST,
394
+ Appsignal::Transaction::GenericRequest.new({})
395
+ )
396
+ end
397
+
398
+ transaction.set_error(exception)
399
+ yield transaction if block_given?
400
+
401
+ return if has_parent_transaction
402
+
403
+ transaction.complete
404
+ end
405
+ alias :report_exception :report_error
406
+
337
407
  # Set a custom action name for the current transaction.
338
408
  #
339
409
  # When using an integration such as the Rails or Sinatra AppSignal will
@@ -404,13 +474,44 @@ module Appsignal
404
474
  Appsignal::Transaction.current.set_namespace(namespace)
405
475
  end
406
476
 
477
+ # Set custom data on the current transaction.
478
+ #
479
+ # Add extra information about the request or background that cannot be
480
+ # expressed in tags, like nested data structures.
481
+ #
482
+ # When this method is called multiple times, it will overwrite the
483
+ # previously set value.
484
+ #
485
+ # @example
486
+ # Appsignal.set_custom_data(:user => { :locale => "en" })
487
+ # Appsignal.set_custom_data([
488
+ # "array with data",
489
+ # :options => { :verbose => true }
490
+ # ])
491
+ #
492
+ # @since 3.10.0
493
+ # @see Transaction#set_custom_data
494
+ # @see https://docs.appsignal.com/guides/custom-data/sample-data.html
495
+ # Sample data guide
496
+ # @param data [Hash/Array]
497
+ # @return [void]
498
+ def set_custom_data(data)
499
+ return unless active?
500
+ return unless Appsignal::Transaction.current?
501
+
502
+ transaction = Appsignal::Transaction.current
503
+ transaction.set_custom_data(data)
504
+ end
505
+
407
506
  # Set tags on the current transaction.
408
507
  #
409
508
  # Tags are extra bits of information that are added to transaction and
410
509
  # appear on sample details pages on AppSignal.com.
411
510
  #
511
+ # When this method is called multiple times, it will merge the tags.
512
+ #
412
513
  # @example
413
- # Appsignal.tag_request(:locale => "en")
514
+ # Appsignal.tag_request(:locale => "en", :user_id => 1)
414
515
  # Appsignal.tag_request("locale" => "en")
415
516
  # Appsignal.tag_request("user_id" => 1)
416
517
  #
@@ -445,6 +546,67 @@ module Appsignal
445
546
  transaction.set_tags(tags)
446
547
  end
447
548
  alias :tag_job :tag_request
549
+ alias :set_tags :tag_request
550
+
551
+ # Set parameters on the current transaction.
552
+ #
553
+ # Parameters are automatically set by most of our integrations. It should
554
+ # not be necessary to call this method unless you want to report
555
+ # different parameters.
556
+ #
557
+ # To filter parameters, see our parameter filtering guide.
558
+ #
559
+ # When this method is called multiple times, it will overwrite the
560
+ # previously set value.
561
+ #
562
+ # When no parameters are set this way, the transaction will look for
563
+ # parameters in its request environment.
564
+ #
565
+ # A block can be given to this method to defer the fetching and parsing
566
+ # of the parameters until and only when the transaction is sampled.
567
+ #
568
+ # When both the `params` and a block is given to this method, the
569
+ # `params` argument is leading and the block will _not_ be called.
570
+ #
571
+ # @example Set parameters
572
+ # Appsignal.set_params("param1" => "value1")
573
+ #
574
+ # @example Calling `set_params` multiple times will only keep the last call
575
+ # Appsignal.set_params("param1" => "value1")
576
+ # Appsignal.set_params("param2" => "value2")
577
+ # # The parameters are: { "param2" => "value2" }
578
+ #
579
+ # @example Calling `set_params` with a block
580
+ # Appsignal.set_params do
581
+ # # Some slow code to parse parameters
582
+ # JSON.parse('{"param1": "value1"}')
583
+ # end
584
+ # # The parameters are: { "param1" => "value1" }
585
+ #
586
+ # @example Calling `set_params` with a parameter and a block
587
+ # Appsignal.set_params("argument" => "argument value") do
588
+ # # Some slow code to parse parameters
589
+ # JSON.parse('{"param1": "value1"}')
590
+ # end
591
+ # # The parameters are: { "argument" => "argument value" }
592
+ #
593
+ # @since 3.10.0
594
+ # @param params [Hash] The parameters to set on the transaction.
595
+ # @yield This block is called when the transaction is sampled. The block's
596
+ # return value will become the new parameters.
597
+ # @see https://docs.appsignal.com/guides/custom-data/sample-data.html
598
+ # Sample data guide
599
+ # @see https://docs.appsignal.com/guides/filter-data/filter-parameters.html
600
+ # Parameter filtering guide
601
+ # @see Transaction#set_params
602
+ # @return [void]
603
+ def set_params(params = nil, &block)
604
+ return unless active?
605
+ return unless Appsignal::Transaction.current?
606
+
607
+ transaction = Appsignal::Transaction.current
608
+ transaction.set_params(params, &block)
609
+ end
448
610
 
449
611
  # Add breadcrumbs to the transaction.
450
612
  #
@@ -62,12 +62,7 @@ module Appsignal
62
62
  end
63
63
 
64
64
  if transaction
65
- transaction.set_params_if_nil(
66
- Appsignal::Utils::HashSanitizer.sanitize(
67
- job["arguments"],
68
- Appsignal.config[:filter_parameters]
69
- )
70
- )
65
+ transaction.set_params_if_nil(job["arguments"])
71
66
 
72
67
  transaction_tags = ActiveJobHelpers.transaction_tags_for(job)
73
68
  transaction_tags["active_job_id"] = job["job_id"]
@@ -1,18 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "appsignal"
4
+ require "appsignal/rack/sinatra_instrumentation"
4
5
 
5
6
  module Appsignal
6
7
  module Integrations
7
8
  # @api private
8
9
  module PadrinoPlugin
9
10
  def self.init
10
- Appsignal.internal_logger.debug("Loading Padrino (#{Padrino::VERSION}) integration")
11
+ Padrino::Application.prepend Appsignal::Integrations::PadrinoIntegration
11
12
 
12
- root = Padrino.mounted_root
13
- Appsignal.config = Appsignal::Config.new(root, Padrino.env)
13
+ Padrino.before_load do
14
+ Appsignal.internal_logger.debug("Loading Padrino (#{Padrino::VERSION}) integration")
14
15
 
15
- Appsignal.start
16
+ unless Appsignal.active?
17
+ root = Padrino.mounted_root
18
+ Appsignal.config = Appsignal::Config.new(root, Padrino.env)
19
+ Appsignal.start
20
+ end
21
+
22
+ next unless Appsignal.active?
23
+
24
+ Padrino.use ::Rack::Events, [Appsignal::Rack::EventHandler.new]
25
+ Padrino.use Appsignal::Rack::SinatraBaseInstrumentation,
26
+ :instrument_event_name => "process_action.padrino"
27
+ end
16
28
  end
17
29
  end
18
30
  end
@@ -20,35 +32,23 @@ end
20
32
 
21
33
  module Appsignal
22
34
  module Integrations
35
+ # @api private
23
36
  module PadrinoIntegration
24
37
  def route!(base = settings, pass_block = nil)
25
38
  return super if !Appsignal.active? || env["sinatra.static_file"]
26
39
 
27
- transaction = Appsignal::Transaction.create(
28
- SecureRandom.uuid,
29
- Appsignal::Transaction::HTTP_REQUEST,
30
- request
31
- )
32
40
  begin
33
- Appsignal.instrument("process_action.padrino") do
34
- super
35
- end
36
- rescue Exception => error # rubocop:disable Lint/RescueException
37
- transaction.set_error(error)
38
- raise error
41
+ super
39
42
  ensure
43
+ transaction = Appsignal::Transaction.current
40
44
  transaction.set_action_if_nil(get_payload_action(request))
41
- transaction.set_metadata("path", request.path)
42
- transaction.set_metadata("method", request.request_method)
43
- transaction.set_http_or_background_queue_start
44
- Appsignal::Transaction.complete_current!
45
45
  end
46
46
  end
47
47
 
48
48
  private
49
49
 
50
50
  def get_payload_action(request)
51
- # Short-circut is there's no request object to obtain information from
51
+ # Short-circuit is there's no request object to obtain information from
52
52
  return settings.name.to_s unless request
53
53
 
54
54
  # Newer versions expose the action / controller on the request class.
@@ -75,8 +75,4 @@ module Appsignal
75
75
  end
76
76
  end
77
77
 
78
- Padrino::Application.prepend Appsignal::Integrations::PadrinoIntegration
79
-
80
- Padrino.after_load do
81
- Appsignal::Integrations::PadrinoPlugin.init
82
- end
78
+ Appsignal::Integrations::PadrinoPlugin.init