appsignal 4.10.4-java → 5.0.0-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 (93) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +108 -0
  3. data/Rakefile +195 -4
  4. data/appsignal.gemspec +8 -0
  5. data/build_matrix.yml +12 -0
  6. data/ext/appsignal_extension.c +14 -0
  7. data/lib/appsignal/backends.rb +55 -0
  8. data/lib/appsignal/cli/diagnose.rb +2 -10
  9. data/lib/appsignal/config.rb +377 -13
  10. data/lib/appsignal/demo.rb +12 -10
  11. data/lib/appsignal/event_formatter/action_view/render_formatter.rb +34 -22
  12. data/lib/appsignal/event_formatter/active_job/perform_formatter.rb +35 -0
  13. data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +19 -0
  14. data/lib/appsignal/event_formatter/elastic_search/search_formatter.rb +27 -0
  15. data/lib/appsignal/event_formatter/recorded_elsewhere.rb +17 -0
  16. data/lib/appsignal/event_formatter/rom/sql_formatter.rb +24 -0
  17. data/lib/appsignal/event_formatter/sequel/sql_formatter.rb +5 -0
  18. data/lib/appsignal/event_formatter/view_component/render_formatter.rb +21 -10
  19. data/lib/appsignal/event_formatter.rb +78 -0
  20. data/lib/appsignal/extension.rb +4 -0
  21. data/lib/appsignal/helpers/instrumentation.rb +324 -20
  22. data/lib/appsignal/helpers/metrics.rb +3 -24
  23. data/lib/appsignal/hooks/action_cable.rb +26 -8
  24. data/lib/appsignal/hooks/active_job.rb +184 -47
  25. data/lib/appsignal/hooks/at_exit.rb +4 -1
  26. data/lib/appsignal/hooks/excon.rb +20 -0
  27. data/lib/appsignal/hooks/faraday.rb +16 -0
  28. data/lib/appsignal/hooks/http.rb +5 -0
  29. data/lib/appsignal/hooks/resque.rb +1 -1
  30. data/lib/appsignal/hooks/sequel.rb +32 -2
  31. data/lib/appsignal/hooks/shoryuken.rb +3 -3
  32. data/lib/appsignal/hooks/sidekiq.rb +1 -1
  33. data/lib/appsignal/integrations/action_cable.rb +5 -2
  34. data/lib/appsignal/integrations/active_support_notifications.rb +59 -19
  35. data/lib/appsignal/integrations/data_mapper.rb +14 -2
  36. data/lib/appsignal/integrations/delayed_job_plugin.rb +81 -8
  37. data/lib/appsignal/integrations/dry_monitor.rb +39 -15
  38. data/lib/appsignal/integrations/excon/appsignal_middleware.rb +21 -0
  39. data/lib/appsignal/integrations/excon.rb +52 -15
  40. data/lib/appsignal/integrations/faraday.rb +47 -12
  41. data/lib/appsignal/integrations/http.rb +43 -1
  42. data/lib/appsignal/integrations/mongo_ruby_driver.rb +73 -4
  43. data/lib/appsignal/integrations/net_http.rb +31 -2
  44. data/lib/appsignal/integrations/puma.rb +4 -1
  45. data/lib/appsignal/integrations/que.rb +256 -37
  46. data/lib/appsignal/integrations/railtie.rb +4 -1
  47. data/lib/appsignal/integrations/rake.rb +9 -3
  48. data/lib/appsignal/integrations/redis.rb +22 -1
  49. data/lib/appsignal/integrations/redis_client.rb +22 -1
  50. data/lib/appsignal/integrations/resque.rb +81 -11
  51. data/lib/appsignal/integrations/shoryuken.rb +159 -12
  52. data/lib/appsignal/integrations/sidekiq.rb +94 -16
  53. data/lib/appsignal/integrations/webmachine.rb +56 -5
  54. data/lib/appsignal/loaders/padrino.rb +2 -1
  55. data/lib/appsignal/logger/extension_backend.rb +24 -0
  56. data/lib/appsignal/logger/opentelemetry_backend.rb +66 -0
  57. data/lib/appsignal/logger.rb +13 -9
  58. data/lib/appsignal/metrics/extension_backend.rb +47 -0
  59. data/lib/appsignal/metrics/opentelemetry_backend.rb +89 -0
  60. data/lib/appsignal/opentelemetry/attributes.rb +31 -0
  61. data/lib/appsignal/opentelemetry/dependencies.rb +35 -0
  62. data/lib/appsignal/opentelemetry/error_type.rb +37 -0
  63. data/lib/appsignal/opentelemetry/http_client_request.rb +83 -0
  64. data/lib/appsignal/opentelemetry/http_method.rb +59 -0
  65. data/lib/appsignal/opentelemetry/http_response.rb +30 -0
  66. data/lib/appsignal/opentelemetry/http_server_request.rb +79 -0
  67. data/lib/appsignal/opentelemetry/messaging.rb +82 -0
  68. data/lib/appsignal/opentelemetry/proxied_exporter.rb +83 -0
  69. data/lib/appsignal/opentelemetry/rendering.rb +29 -0
  70. data/lib/appsignal/opentelemetry/sql_db_system.rb +89 -0
  71. data/lib/appsignal/opentelemetry.rb +495 -0
  72. data/lib/appsignal/rack/abstract_middleware.rb +66 -4
  73. data/lib/appsignal/rack/body_wrapper.rb +18 -5
  74. data/lib/appsignal/rack/event_handler.rb +44 -4
  75. data/lib/appsignal/rack/grape_middleware.rb +1 -0
  76. data/lib/appsignal/rack/hanami_middleware.rb +2 -1
  77. data/lib/appsignal/rack/instrumentation_middleware.rb +1 -0
  78. data/lib/appsignal/rack/rails_instrumentation.rb +1 -0
  79. data/lib/appsignal/rack/sinatra_instrumentation.rb +1 -0
  80. data/lib/appsignal/rack.rb +68 -12
  81. data/lib/appsignal/sample_data.rb +4 -0
  82. data/lib/appsignal/transaction/base_backend.rb +128 -0
  83. data/lib/appsignal/transaction/extension_backend.rb +229 -0
  84. data/lib/appsignal/transaction/opentelemetry_backend.rb +847 -0
  85. data/lib/appsignal/transaction.rb +714 -164
  86. data/lib/appsignal/utils/request_headers.rb +78 -0
  87. data/lib/appsignal/utils/stdout_and_logger_message.rb +9 -0
  88. data/lib/appsignal/utils.rb +1 -0
  89. data/lib/appsignal/version.rb +1 -1
  90. data/lib/appsignal.rb +10 -0
  91. data/sig/appsignal.rbi +630 -37
  92. data/sig/appsignal.rbs +582 -27
  93. metadata +25 -1
@@ -102,6 +102,18 @@ module Appsignal
102
102
  # within the block with {#set_action}.
103
103
  # This will not update the active transaction's action if
104
104
  # {.monitor} is called when another transaction is already active.
105
+ # @param opentelemetry_kind [Symbol] In collector mode, the OpenTelemetry
106
+ # span kind: one of `:server`, `:consumer`, `:producer` or `:internal`.
107
+ # Defaults to `:server`.
108
+ # @param opentelemetry_relationship [Symbol] In collector mode, how an
109
+ # incoming `opentelemetry_context` relates to this transaction's span:
110
+ # one of `:parent`, `:link`, `:both` or `:none`. Defaults to `:parent`.
111
+ # @param opentelemetry_context In collector mode, an incoming OpenTelemetry
112
+ # trace context to relate this transaction's span to.
113
+ # @param opentelemetry_scope [Array(String, String)] In collector mode, the
114
+ # OpenTelemetry instrumentation scope to record this transaction's spans
115
+ # under, given as a `[name, version]` pair. Defaults to the AppSignal
116
+ # scope.
105
117
  # @yield [] The block to monitor.
106
118
  # @yieldreturn [Object] The return value of the block
107
119
  # @raise [Exception] Any exception that occurs within the given block is
@@ -112,7 +124,14 @@ module Appsignal
112
124
  #
113
125
  # @see https://docs.appsignal.com/ruby/instrumentation/background-jobs.html
114
126
  # Monitor guide
115
- def monitor(action:, namespace: nil)
127
+ def monitor( # rubocop:disable Metrics/ParameterLists
128
+ action:,
129
+ namespace: nil,
130
+ opentelemetry_context: nil,
131
+ opentelemetry_scope: nil,
132
+ opentelemetry_kind: nil,
133
+ opentelemetry_relationship: nil
134
+ )
116
135
  return yield unless Appsignal.active?
117
136
 
118
137
  has_parent_transaction = Appsignal::Transaction.current?
@@ -133,7 +152,13 @@ module Appsignal
133
152
  if has_parent_transaction
134
153
  Appsignal::Transaction.current
135
154
  else
136
- Appsignal::Transaction.create(namespace || Appsignal::Transaction::HTTP_REQUEST)
155
+ Appsignal::Transaction.create(
156
+ namespace || Appsignal::Transaction::HTTP_REQUEST,
157
+ :opentelemetry_context => opentelemetry_context,
158
+ :opentelemetry_scope => opentelemetry_scope,
159
+ :opentelemetry_kind => opentelemetry_kind,
160
+ :opentelemetry_relationship => opentelemetry_relationship
161
+ )
137
162
  end
138
163
 
139
164
  begin
@@ -168,6 +193,18 @@ module Appsignal
168
193
  # within the block with {#set_action}.
169
194
  # This will not update the active transaction's action if
170
195
  # {.monitor} is called when another transaction is already active.
196
+ # @param opentelemetry_kind [Symbol] In collector mode, the OpenTelemetry
197
+ # span kind: one of `:server`, `:consumer`, `:producer` or `:internal`.
198
+ # Defaults to `:server`.
199
+ # @param opentelemetry_relationship [Symbol] In collector mode, how an
200
+ # incoming `opentelemetry_context` relates to this transaction's span:
201
+ # one of `:parent`, `:link`, `:both` or `:none`. Defaults to `:parent`.
202
+ # @param opentelemetry_context In collector mode, an incoming OpenTelemetry
203
+ # trace context to relate this transaction's span to.
204
+ # @param opentelemetry_scope [Array(String, String)] In collector mode, the
205
+ # OpenTelemetry instrumentation scope to record this transaction's spans
206
+ # under, given as a `[name, version]` pair. Defaults to the AppSignal
207
+ # scope.
171
208
  # @yield [] The block to monitor.
172
209
  # @yieldreturn [Object] The return value of the block
173
210
  # @raise [Exception] Any exception that occurs within the given block is
@@ -175,13 +212,29 @@ module Appsignal
175
212
  # @return [Object, nil] The value of the given block is returned.
176
213
  #
177
214
  # @see monitor
178
- def monitor_and_stop(action:, namespace: nil, &block)
215
+ def monitor_and_stop( # rubocop:disable Metrics/ParameterLists
216
+ action:,
217
+ namespace: nil,
218
+ opentelemetry_context: nil,
219
+ opentelemetry_scope: nil,
220
+ opentelemetry_kind: nil,
221
+ opentelemetry_relationship: nil,
222
+ &block
223
+ )
179
224
  Appsignal::Utils::StdoutAndLoggerMessage.warning \
180
225
  "The `Appsignal.monitor_and_stop` helper is deprecated. " \
181
226
  "Use the `Appsignal.monitor` along with our `enable_at_exit_hook` " \
182
227
  "option instead."
183
228
 
184
- monitor(:namespace => namespace, :action => action, &block)
229
+ monitor(
230
+ :namespace => namespace,
231
+ :action => action,
232
+ :opentelemetry_context => opentelemetry_context,
233
+ :opentelemetry_scope => opentelemetry_scope,
234
+ :opentelemetry_kind => opentelemetry_kind,
235
+ :opentelemetry_relationship => opentelemetry_relationship,
236
+ &block
237
+ )
185
238
  ensure
186
239
  Appsignal.stop("monitor_and_stop")
187
240
  end
@@ -218,6 +271,18 @@ module Appsignal
218
271
  #
219
272
  # @since 0.6.0
220
273
  # @param error [Exception] The error to send to AppSignal.
274
+ # @param opentelemetry_kind [Symbol] In collector mode, the OpenTelemetry
275
+ # span kind: one of `:server`, `:consumer`, `:producer` or `:internal`.
276
+ # Defaults to `:server`.
277
+ # @param opentelemetry_relationship [Symbol] In collector mode, how an
278
+ # incoming `opentelemetry_context` relates to this transaction's span:
279
+ # one of `:parent`, `:link`, `:both` or `:none`. Defaults to `:parent`.
280
+ # @param opentelemetry_context In collector mode, an incoming OpenTelemetry
281
+ # trace context to relate this transaction's span to.
282
+ # @param opentelemetry_scope [Array(String, String)] In collector mode, the
283
+ # OpenTelemetry instrumentation scope to record this transaction's spans
284
+ # under, given as a `[name, version]` pair. Defaults to the AppSignal
285
+ # scope.
221
286
  # @yield [transaction] yields block to allow modification of the
222
287
  # transaction before it's send.
223
288
  # @yieldparam transaction [Transaction] yields the AppSignal transaction
@@ -226,7 +291,14 @@ module Appsignal
226
291
  #
227
292
  # @see https://docs.appsignal.com/ruby/instrumentation/exception-handling.html
228
293
  # Exception handling guide
229
- def send_error(error, &block)
294
+ def send_error(
295
+ error,
296
+ opentelemetry_context: nil,
297
+ opentelemetry_scope: nil,
298
+ opentelemetry_kind: nil,
299
+ opentelemetry_relationship: nil,
300
+ &block
301
+ )
230
302
  return unless Appsignal.active?
231
303
 
232
304
  unless error.is_a?(Exception)
@@ -237,8 +309,14 @@ module Appsignal
237
309
  end
238
310
 
239
311
  transaction =
240
- Appsignal::Transaction.new(Appsignal::Transaction::HTTP_REQUEST)
241
- transaction.set_error(error, &block)
312
+ Appsignal::Transaction.new(
313
+ Appsignal::Transaction::HTTP_REQUEST,
314
+ :opentelemetry_context => opentelemetry_context,
315
+ :opentelemetry_scope => opentelemetry_scope,
316
+ :opentelemetry_kind => opentelemetry_kind,
317
+ :opentelemetry_relationship => opentelemetry_relationship
318
+ )
319
+ transaction.set_error(error, :source => "Appsignal.send_error", &block)
242
320
 
243
321
  transaction.complete
244
322
  end
@@ -348,6 +426,20 @@ module Appsignal
348
426
  # @since 4.0.0
349
427
  # @param exception [Exception] The error to add to the current
350
428
  # transaction.
429
+ # @param opentelemetry_kind [Symbol] In collector mode, the OpenTelemetry
430
+ # span kind: one of `:server`, `:consumer`, `:producer` or `:internal`.
431
+ # Defaults to `:server`. Only used when a new transaction is created.
432
+ # @param opentelemetry_relationship [Symbol] In collector mode, how an
433
+ # incoming `opentelemetry_context` relates to this transaction's span:
434
+ # one of `:parent`, `:link`, `:both` or `:none`. Defaults to `:parent`.
435
+ # Only used when a new transaction is created.
436
+ # @param opentelemetry_context In collector mode, an incoming OpenTelemetry
437
+ # trace context to relate this transaction's span to. Only used when a
438
+ # new transaction is created.
439
+ # @param opentelemetry_scope [Array(String, String)] In collector mode, the
440
+ # OpenTelemetry instrumentation scope to record this transaction's spans
441
+ # under, given as a `[name, version]` pair. Defaults to the AppSignal
442
+ # scope.
351
443
  # @yield [transaction] yields block to allow modification of the
352
444
  # transaction.
353
445
  # @yieldparam transaction [Transaction] yields the AppSignal transaction
@@ -356,7 +448,14 @@ module Appsignal
356
448
  #
357
449
  # @see https://docs.appsignal.com/ruby/instrumentation/exception-handling.html
358
450
  # Exception handling guide
359
- def report_error(exception, &block)
451
+ def report_error(
452
+ exception,
453
+ opentelemetry_context: nil,
454
+ opentelemetry_scope: nil,
455
+ opentelemetry_kind: nil,
456
+ opentelemetry_relationship: nil,
457
+ &block
458
+ )
360
459
  unless exception.is_a?(Exception)
361
460
  Appsignal.internal_logger.error "Appsignal.report_error: " \
362
461
  "Cannot add error. " \
@@ -370,10 +469,16 @@ module Appsignal
370
469
  if has_parent_transaction
371
470
  Appsignal::Transaction.current
372
471
  else
373
- Appsignal::Transaction.new(Appsignal::Transaction::HTTP_REQUEST)
472
+ Appsignal::Transaction.new(
473
+ Appsignal::Transaction::HTTP_REQUEST,
474
+ :opentelemetry_context => opentelemetry_context,
475
+ :opentelemetry_scope => opentelemetry_scope,
476
+ :opentelemetry_kind => opentelemetry_kind,
477
+ :opentelemetry_relationship => opentelemetry_relationship
478
+ )
374
479
  end
375
480
 
376
- transaction.add_error(exception, &block)
481
+ transaction.add_error(exception, :source => "Appsignal.report_error", &block)
377
482
 
378
483
  transaction.complete unless has_parent_transaction
379
484
  end
@@ -602,16 +707,95 @@ module Appsignal
602
707
  end
603
708
  alias set_params add_params
604
709
 
710
+ # Add the request payload to the current transaction.
711
+ #
712
+ # The request payload is the parameters of an incoming request, such as
713
+ # the query string and the request body. In collector mode it maps to its
714
+ # own attribute, separate from the function parameters.
715
+ #
716
+ # Behaves like {#add_params}: merges when called multiple times, and a
717
+ # block takes precedence over the argument.
718
+ #
719
+ # @param params [Hash<String, Object>, Array<Object>] The request payload to add to the
720
+ # transaction.
721
+ # @yield This block is called when the transaction is sampled. The block's
722
+ # return value will become the new request payload.
723
+ # @yieldreturn [Hash<String, Object>, Array<Object>]
724
+ # @return [void]
725
+ #
726
+ # @see #add_function_parameters
727
+ def add_request_payload(params = nil, &block)
728
+ return unless Appsignal.active?
729
+ return unless Appsignal::Transaction.current?
730
+
731
+ transaction = Appsignal::Transaction.current
732
+ transaction.add_request_payload(params, &block)
733
+ end
734
+
735
+ # Add the function parameters to the current transaction.
736
+ #
737
+ # The function parameters are the arguments a background job or function
738
+ # was called with. In collector mode they map to their own attribute,
739
+ # separate from the request payload.
740
+ #
741
+ # Behaves like {#add_params}: merges when called multiple times, and a
742
+ # block takes precedence over the argument.
743
+ #
744
+ # @param params [Hash<String, Object>, Array<Object>] The function parameters to add to
745
+ # the transaction.
746
+ # @yield This block is called when the transaction is sampled. The block's
747
+ # return value will become the new function parameters.
748
+ # @yieldreturn [Hash<String, Object>, Array<Object>]
749
+ # @return [void]
750
+ #
751
+ # @see #add_request_payload
752
+ def add_function_parameters(params = nil, &block)
753
+ return unless Appsignal.active?
754
+ return unless Appsignal::Transaction.current?
755
+
756
+ transaction = Appsignal::Transaction.current
757
+ transaction.add_function_parameters(params, &block)
758
+ end
759
+
760
+ # Add the query parameters to the current transaction.
761
+ #
762
+ # The query parameters are the parameters parsed from an incoming
763
+ # request's query string. In collector mode they map to their own
764
+ # attribute, separate from the request payload and the function
765
+ # parameters.
766
+ #
767
+ # Behaves like {#add_params}: merges when called multiple times, and a
768
+ # block takes precedence over the argument.
769
+ #
770
+ # @param params [Hash<String, Object>, Array<Object>] The query parameters to add to the
771
+ # transaction.
772
+ # @yield This block is called when the transaction is sampled. The block's
773
+ # return value will become the new query parameters.
774
+ # @yieldreturn [Hash<String, Object>, Array<Object>]
775
+ # @return [void]
776
+ #
777
+ # @see #add_request_payload
778
+ def add_query_parameters(params = nil, &block)
779
+ return unless Appsignal.active?
780
+ return unless Appsignal::Transaction.current?
781
+
782
+ transaction = Appsignal::Transaction.current
783
+ transaction.add_query_parameters(params, &block)
784
+ end
785
+
605
786
  # Mark the parameters sample data to be set as an empty value.
606
787
  #
607
- # Use this helper to unset request parameters / background job arguments
608
- # and not report any for this transaction.
788
+ # Use this helper to report no parameters for this transaction, whatever
789
+ # their source.
609
790
  #
610
- # If parameters would normally be added by AppSignal instrumentations of
611
- # libraries, these parameters will not be added to the Transaction.
791
+ # This suppresses every params channel. In collector mode, where the
792
+ # request payload and the function parameters (a background job's
793
+ # arguments) are tracked as separate attributes, it suppresses both, not
794
+ # only the request payload. Parameters that an AppSignal integration would
795
+ # otherwise add are not added.
612
796
  #
613
- # Calling {#add_params} after this helper will add new parameters to the
614
- # transaction.
797
+ # Calling {#add_params}, {#add_request_payload} or
798
+ # {#add_function_parameters} after this helper adds parameters again.
615
799
  #
616
800
  # @since 4.2.0
617
801
  # @return [void]
@@ -690,6 +874,10 @@ module Appsignal
690
874
  # # The request headers will include:
691
875
  # # { "PATH_INFO" => "/some-path", "HTTP_USER_AGENT" => "Firefox" }
692
876
  #
877
+ # @deprecated Use {#add_request_headers} for request headers and
878
+ # {#add_request_environment} for the values a Rack environment holds
879
+ # that are not request headers. This method takes both kinds at once,
880
+ # so it has to work out which of them each value is.
693
881
  # @since 4.0.0
694
882
  # @param headers [Hash<String, Object>] The request headers to add to the transaction.
695
883
  # @yield This block is called when the transaction is sampled. The block's
@@ -697,6 +885,8 @@ module Appsignal
697
885
  # @yieldreturn [Hash<String, Object>]
698
886
  # @return [void]
699
887
  #
888
+ # @see #add_request_headers
889
+ # @see #add_request_environment
700
890
  # @see https://docs.appsignal.com/guides/custom-data/sample-data.html
701
891
  # Sample data guide
702
892
  # @see https://docs.appsignal.com/guides/filter-data/filter-headers.html
@@ -710,12 +900,94 @@ module Appsignal
710
900
  end
711
901
  alias set_headers add_headers
712
902
 
903
+ # Add request headers to the current transaction.
904
+ #
905
+ # Request headers are automatically added by most of our integrations. It
906
+ # should not be necessary to call this method unless you want to also
907
+ # report different request headers.
908
+ #
909
+ # Name each header the way OpenTelemetry names it, in lowercase and with
910
+ # dashes. In agent mode the names are converted to the Rack spellings the
911
+ # environment uses, so `accept` is reported as `HTTP_ACCEPT`.
912
+ #
913
+ # To filter request headers, see our request header filtering guide.
914
+ #
915
+ # When both the `headers` argument and a block is given to this method,
916
+ # the block is leading and the argument will _not_ be used.
917
+ #
918
+ # @example Add request headers
919
+ # Appsignal.add_request_headers("accept" => "text/html")
920
+ # # The request headers will include:
921
+ # # { "accept" => "text/html" }
922
+ #
923
+ # @example Calling `add_request_headers` multiple times merges the values
924
+ # Appsignal.add_request_headers("accept" => "text/html")
925
+ # Appsignal.add_request_headers("user-agent" => "Firefox")
926
+ # # The request headers will include:
927
+ # # { "accept" => "text/html", "user-agent" => "Firefox" }
928
+ #
929
+ # @param headers [Hash<String, Object>] The request headers to add to the
930
+ # transaction.
931
+ # @yield This block is called when the transaction is sampled. The block's
932
+ # return value will become the new request headers.
933
+ # @yieldreturn [Hash<String, Object>]
934
+ # @return [void]
935
+ #
936
+ # @see #add_request_environment
937
+ # @see https://docs.appsignal.com/guides/custom-data/sample-data.html
938
+ # Sample data guide
939
+ # @see https://docs.appsignal.com/guides/filter-data/filter-headers.html
940
+ # Request headers filtering guide
941
+ def add_request_headers(headers = nil, &block)
942
+ return unless Appsignal.active?
943
+ return unless Appsignal::Transaction.current?
944
+
945
+ transaction = Appsignal::Transaction.current
946
+ transaction.add_request_headers(headers, &block)
947
+ end
948
+
949
+ # Add values from the request environment to the current transaction.
950
+ #
951
+ # These are the values a Rack environment holds that are not request
952
+ # headers, such as `REMOTE_ADDR` and `QUERY_STRING`. Name each one the
953
+ # way Rack names it. Use {#add_request_headers} for the request headers.
954
+ #
955
+ # The request environment is automatically added by most of our
956
+ # integrations. It should not be necessary to call this method unless you
957
+ # want to also report different values.
958
+ #
959
+ # When both the `environment` argument and a block is given to this
960
+ # method, the block is leading and the argument will _not_ be used.
961
+ #
962
+ # @example Add request environment values
963
+ # Appsignal.add_request_environment("REMOTE_ADDR" => "127.0.0.1")
964
+ # # The request environment will include:
965
+ # # { "REMOTE_ADDR" => "127.0.0.1" }
966
+ #
967
+ # @param environment [Hash<String, Object>] The request environment
968
+ # values to add to the transaction.
969
+ # @yield This block is called when the transaction is sampled. The block's
970
+ # return value will become the new request environment.
971
+ # @yieldreturn [Hash<String, Object>]
972
+ # @return [void]
973
+ #
974
+ # @see #add_request_headers
975
+ # @see https://docs.appsignal.com/guides/custom-data/sample-data.html
976
+ # Sample data guide
977
+ def add_request_environment(environment = nil, &block)
978
+ return unless Appsignal.active?
979
+ return unless Appsignal::Transaction.current?
980
+
981
+ transaction = Appsignal::Transaction.current
982
+ transaction.add_request_environment(environment, &block)
983
+ end
984
+
713
985
  # Add breadcrumbs to the transaction.
714
986
  #
715
987
  # Breadcrumbs can be used to trace what path a user has taken
716
988
  # before encountering an error.
717
989
  #
718
- # Only the last 20 added breadcrumbs will be saved.
990
+ # At most 20 of the added breadcrumbs will be saved.
719
991
  #
720
992
  # @example
721
993
  # Appsignal.add_breadcrumb(
@@ -786,6 +1058,12 @@ module Appsignal
786
1058
  # instrumented. Accepted values are {EventFormatter::DEFAULT} and
787
1059
  # {EventFormatter::SQL_BODY_FORMAT}, but we recommend you use
788
1060
  # {.instrument_sql} instead of {EventFormatter::SQL_BODY_FORMAT}.
1061
+ # @param opentelemetry_kind [Symbol] In collector mode, the OpenTelemetry
1062
+ # span kind for the event's span, such as `:client` for an outgoing HTTP
1063
+ # request. Defaults to the OpenTelemetry default of `:internal`.
1064
+ # @param opentelemetry_scope [Array(String, String)] In collector mode, the
1065
+ # OpenTelemetry instrumentation scope to record the event's span under,
1066
+ # given as a `[name, version]` pair. Defaults to the AppSignal scope.
789
1067
  # @yield [] yields the given block of code instrumented in an AppSignal
790
1068
  # event.
791
1069
  # @return [Object] Returns the block's return value.
@@ -795,15 +1073,25 @@ module Appsignal
795
1073
  # AppSignal custom instrumentation guide
796
1074
  # @see https://docs.appsignal.com/api/event-names.html
797
1075
  # AppSignal event naming guide
798
- def instrument(
1076
+ def instrument( # rubocop:disable Metrics/ParameterLists
799
1077
  name,
800
1078
  title = nil,
801
1079
  body = nil,
802
1080
  body_format = Appsignal::EventFormatter::DEFAULT,
1081
+ opentelemetry_kind: nil,
1082
+ opentelemetry_scope: nil,
803
1083
  &block
804
1084
  )
805
1085
  Appsignal::Transaction.current
806
- .instrument(name, title, body, body_format, &block)
1086
+ .instrument(
1087
+ name,
1088
+ title,
1089
+ body,
1090
+ body_format,
1091
+ :opentelemetry_kind => opentelemetry_kind,
1092
+ :opentelemetry_scope => opentelemetry_scope,
1093
+ &block
1094
+ )
807
1095
  end
808
1096
 
809
1097
  # Instrumentation helper for SQL queries.
@@ -827,6 +1115,13 @@ module Appsignal
827
1115
  # naming guide listed under "See also".
828
1116
  # @param title [String, nil] Human readable name of the event.
829
1117
  # @param body [String, nil] SQL query that's being executed.
1118
+ # @param opentelemetry_kind [Symbol] In collector mode, the OpenTelemetry
1119
+ # span kind for the event's span. Defaults to `:client`, because a query
1120
+ # is an outgoing call to a datastore. Pass `:internal` for a query that
1121
+ # is not an outgoing call.
1122
+ # @param opentelemetry_scope [Array(String, String)] In collector mode, the
1123
+ # OpenTelemetry instrumentation scope to record the event's span under,
1124
+ # given as a `[name, version]` pair. Defaults to the AppSignal scope.
830
1125
  # @yield [] yields the given block of code instrumented in an AppSignal
831
1126
  # event.
832
1127
  # @return [Object] Returns the block's return value.
@@ -836,12 +1131,21 @@ module Appsignal
836
1131
  # AppSignal custom instrumentation guide
837
1132
  # @see https://docs.appsignal.com/api/event-names.html
838
1133
  # AppSignal event naming guide
839
- def instrument_sql(name, title = nil, body = nil, &block)
1134
+ def instrument_sql(
1135
+ name,
1136
+ title = nil,
1137
+ body = nil,
1138
+ opentelemetry_kind: :client,
1139
+ opentelemetry_scope: nil,
1140
+ &block
1141
+ )
840
1142
  instrument(
841
1143
  name,
842
1144
  title,
843
1145
  body,
844
1146
  Appsignal::EventFormatter::SQL_BODY_FORMAT,
1147
+ :opentelemetry_kind => opentelemetry_kind,
1148
+ :opentelemetry_scope => opentelemetry_scope,
845
1149
  &block
846
1150
  )
847
1151
  end
@@ -16,14 +16,7 @@ module Appsignal
16
16
  # @see https://docs.appsignal.com/metrics/custom.html
17
17
  # Metrics documentation
18
18
  def set_gauge(name, value, tags = {})
19
- Appsignal::Extension.set_gauge(
20
- name.to_s,
21
- value.to_f,
22
- Appsignal::Utils::Data.generate(tags)
23
- )
24
- rescue RangeError
25
- Appsignal.internal_logger
26
- .warn("The gauge value '#{value}' for metric '#{name}' is too big")
19
+ Appsignal::Backends.metrics.set_gauge(name, value, tags)
27
20
  end
28
21
 
29
22
  # Report a counter metric.
@@ -39,14 +32,7 @@ module Appsignal
39
32
  # @see https://docs.appsignal.com/metrics/custom.html
40
33
  # Metrics documentation
41
34
  def increment_counter(name, value = 1.0, tags = {})
42
- Appsignal::Extension.increment_counter(
43
- name.to_s,
44
- value.to_f,
45
- Appsignal::Utils::Data.generate(tags)
46
- )
47
- rescue RangeError
48
- Appsignal.internal_logger
49
- .warn("The counter value '#{value}' for metric '#{name}' is too big")
35
+ Appsignal::Backends.metrics.increment_counter(name, value, tags)
50
36
  end
51
37
 
52
38
  # Report a distribution metric.
@@ -62,14 +48,7 @@ module Appsignal
62
48
  # @see https://docs.appsignal.com/metrics/custom.html
63
49
  # Metrics documentation
64
50
  def add_distribution_value(name, value, tags = {})
65
- Appsignal::Extension.add_distribution_value(
66
- name.to_s,
67
- value.to_f,
68
- Appsignal::Utils::Data.generate(tags)
69
- )
70
- rescue RangeError
71
- Appsignal.internal_logger
72
- .warn("The distribution value '#{value}' for metric '#{name}' is too big")
51
+ Appsignal::Backends.metrics.add_distribution_value(name, value, tags)
73
52
  end
74
53
  end
75
54
  end
@@ -37,10 +37,16 @@ module Appsignal
37
37
  env[Appsignal::Hooks::ActionCableHook::REQUEST_ID] ||= request_id
38
38
 
39
39
  transaction =
40
- Appsignal::Transaction.create(Appsignal::Transaction::ACTION_CABLE)
40
+ Appsignal::Transaction.create(
41
+ Appsignal::Transaction::ACTION_CABLE,
42
+ :opentelemetry_scope => ["appsignal-ruby/action_cable", Appsignal::VERSION]
43
+ )
41
44
 
42
45
  begin
43
- Appsignal.instrument "subscribed.action_cable" do
46
+ Appsignal.instrument(
47
+ "subscribed.action_cable",
48
+ :opentelemetry_scope => ["appsignal-ruby/action_cable", Appsignal::VERSION]
49
+ ) do
44
50
  inner.call
45
51
  end
46
52
  rescue Exception => exception
@@ -50,8 +56,11 @@ module Appsignal
50
56
  transaction.set_action_if_nil("#{channel.class}#subscribed")
51
57
  transaction.set_metadata("path", request.path)
52
58
  transaction.set_metadata("method", "websocket")
53
- transaction.add_params_if_nil { request.params }
54
- transaction.add_headers_if_nil { request.env }
59
+ transaction.add_request_payload_if_nil { request.params }
60
+ headers, environment =
61
+ Appsignal::Utils::RequestHeaders.split_lazily { request.env }
62
+ transaction.add_request_headers_if_nil(&headers)
63
+ transaction.add_request_environment_if_nil(&environment)
55
64
  transaction.add_session_data { request.session.to_h if request.respond_to? :session }
56
65
  transaction.add_tags(:request_id => request_id) if request_id
57
66
  Appsignal::Transaction.complete_current!
@@ -73,10 +82,16 @@ module Appsignal
73
82
  env[Appsignal::Hooks::ActionCableHook::REQUEST_ID] ||= request_id
74
83
 
75
84
  transaction =
76
- Appsignal::Transaction.create(Appsignal::Transaction::ACTION_CABLE)
85
+ Appsignal::Transaction.create(
86
+ Appsignal::Transaction::ACTION_CABLE,
87
+ :opentelemetry_scope => ["appsignal-ruby/action_cable", Appsignal::VERSION]
88
+ )
77
89
 
78
90
  begin
79
- Appsignal.instrument "unsubscribed.action_cable" do
91
+ Appsignal.instrument(
92
+ "unsubscribed.action_cable",
93
+ :opentelemetry_scope => ["appsignal-ruby/action_cable", Appsignal::VERSION]
94
+ ) do
80
95
  inner.call
81
96
  end
82
97
  rescue Exception => exception
@@ -86,8 +101,11 @@ module Appsignal
86
101
  transaction.set_action_if_nil("#{channel.class}#unsubscribed")
87
102
  transaction.set_metadata("path", request.path)
88
103
  transaction.set_metadata("method", "websocket")
89
- transaction.add_params_if_nil { request.params }
90
- transaction.add_headers_if_nil { request.env }
104
+ transaction.add_request_payload_if_nil { request.params }
105
+ headers, environment =
106
+ Appsignal::Utils::RequestHeaders.split_lazily { request.env }
107
+ transaction.add_request_headers_if_nil(&headers)
108
+ transaction.add_request_environment_if_nil(&environment)
91
109
  transaction.add_session_data { request.session.to_h if request.respond_to? :session }
92
110
  transaction.add_tags(:request_id => request_id) if request_id
93
111
  Appsignal::Transaction.complete_current!