appsignal 4.10.1-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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -0
- data/Rakefile +87 -0
- data/appsignal.gemspec +8 -0
- data/build_matrix.yml +14 -1
- data/ext/appsignal_extension.c +14 -0
- data/lib/appsignal/backends.rb +55 -0
- data/lib/appsignal/config.rb +140 -1
- data/lib/appsignal/demo.rb +1 -1
- data/lib/appsignal/event_formatter/action_view/render_formatter.rb +34 -22
- data/lib/appsignal/event_formatter/active_job/perform_formatter.rb +35 -0
- data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +19 -0
- data/lib/appsignal/event_formatter/elastic_search/search_formatter.rb +27 -0
- data/lib/appsignal/event_formatter/recorded_elsewhere.rb +17 -0
- data/lib/appsignal/event_formatter/rom/sql_formatter.rb +24 -0
- data/lib/appsignal/event_formatter/sequel/sql_formatter.rb +5 -0
- data/lib/appsignal/event_formatter/view_component/render_formatter.rb +21 -10
- data/lib/appsignal/event_formatter.rb +78 -0
- data/lib/appsignal/extension.rb +4 -0
- data/lib/appsignal/helpers/instrumentation.rb +236 -20
- data/lib/appsignal/helpers/metrics.rb +3 -24
- data/lib/appsignal/hooks/action_cable.rb +18 -6
- data/lib/appsignal/hooks/active_job.rb +128 -39
- data/lib/appsignal/hooks/at_exit.rb +4 -1
- data/lib/appsignal/hooks/excon.rb +20 -0
- data/lib/appsignal/hooks/faraday.rb +16 -0
- data/lib/appsignal/hooks/http.rb +5 -0
- data/lib/appsignal/hooks/resque.rb +1 -1
- data/lib/appsignal/hooks/sequel.rb +32 -2
- data/lib/appsignal/hooks/shoryuken.rb +3 -3
- data/lib/appsignal/hooks/sidekiq.rb +1 -1
- data/lib/appsignal/integrations/action_cable.rb +5 -2
- data/lib/appsignal/integrations/active_support_notifications.rb +59 -14
- data/lib/appsignal/integrations/data_mapper.rb +14 -2
- data/lib/appsignal/integrations/delayed_job_plugin.rb +45 -5
- data/lib/appsignal/integrations/dry_monitor.rb +39 -15
- data/lib/appsignal/integrations/excon/appsignal_middleware.rb +21 -0
- data/lib/appsignal/integrations/excon.rb +52 -15
- data/lib/appsignal/integrations/faraday.rb +47 -12
- data/lib/appsignal/integrations/http.rb +43 -1
- data/lib/appsignal/integrations/mongo_ruby_driver.rb +73 -4
- data/lib/appsignal/integrations/net_http.rb +31 -2
- data/lib/appsignal/integrations/puma.rb +4 -1
- data/lib/appsignal/integrations/que.rb +224 -37
- data/lib/appsignal/integrations/railtie.rb +4 -1
- data/lib/appsignal/integrations/rake.rb +9 -3
- data/lib/appsignal/integrations/redis.rb +22 -1
- data/lib/appsignal/integrations/redis_client.rb +22 -1
- data/lib/appsignal/integrations/resque.rb +57 -10
- data/lib/appsignal/integrations/shoryuken.rb +140 -12
- data/lib/appsignal/integrations/sidekiq.rb +73 -16
- data/lib/appsignal/integrations/webmachine.rb +47 -4
- data/lib/appsignal/loaders/padrino.rb +2 -1
- data/lib/appsignal/logger/extension_backend.rb +24 -0
- data/lib/appsignal/logger/opentelemetry_backend.rb +66 -0
- data/lib/appsignal/logger.rb +13 -9
- data/lib/appsignal/metrics/extension_backend.rb +47 -0
- data/lib/appsignal/metrics/opentelemetry_backend.rb +89 -0
- data/lib/appsignal/opentelemetry/attributes.rb +31 -0
- data/lib/appsignal/opentelemetry/dependencies.rb +35 -0
- data/lib/appsignal/opentelemetry/error_type.rb +37 -0
- data/lib/appsignal/opentelemetry/http_client_request.rb +83 -0
- data/lib/appsignal/opentelemetry/http_method.rb +59 -0
- data/lib/appsignal/opentelemetry/http_response.rb +30 -0
- data/lib/appsignal/opentelemetry/http_server_request.rb +45 -0
- data/lib/appsignal/opentelemetry/messaging.rb +82 -0
- data/lib/appsignal/opentelemetry/rendering.rb +29 -0
- data/lib/appsignal/opentelemetry/sql_db_system.rb +89 -0
- data/lib/appsignal/opentelemetry.rb +337 -0
- data/lib/appsignal/rack/abstract_middleware.rb +63 -4
- data/lib/appsignal/rack/body_wrapper.rb +18 -5
- data/lib/appsignal/rack/event_handler.rb +36 -3
- data/lib/appsignal/rack/grape_middleware.rb +1 -0
- data/lib/appsignal/rack/hanami_middleware.rb +2 -1
- data/lib/appsignal/rack/instrumentation_middleware.rb +1 -0
- data/lib/appsignal/rack/rails_instrumentation.rb +1 -0
- data/lib/appsignal/rack/sinatra_instrumentation.rb +1 -0
- data/lib/appsignal/rack.rb +39 -11
- data/lib/appsignal/sample_data.rb +4 -0
- data/lib/appsignal/transaction/base_backend.rb +107 -0
- data/lib/appsignal/transaction/extension_backend.rb +203 -0
- data/lib/appsignal/transaction/opentelemetry_backend.rb +796 -0
- data/lib/appsignal/transaction.rb +537 -144
- data/lib/appsignal/utils/stdout_and_logger_message.rb +9 -0
- data/lib/appsignal/version.rb +1 -1
- data/lib/appsignal.rb +9 -0
- data/sig/appsignal.rbi +426 -37
- data/sig/appsignal.rbs +386 -27
- metadata +23 -1
|
@@ -5,6 +5,25 @@ module Appsignal
|
|
|
5
5
|
# @!visibility private
|
|
6
6
|
module ActiveRecord
|
|
7
7
|
class SqlFormatter < Appsignal::EventFormatter
|
|
8
|
+
# A query is an outgoing call to a datastore.
|
|
9
|
+
def opentelemetry_kind
|
|
10
|
+
:client
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# The payload carries the connection the query ran on (Rails 6.0+),
|
|
14
|
+
# whose `adapter_name` is each adapter's own name for itself, such as
|
|
15
|
+
# `"PostgreSQL"` or `"Mysql2"`. A name the mapping does not recognise
|
|
16
|
+
# is left to the SQL sentinel, same as an adapter this gem has never
|
|
17
|
+
# heard of.
|
|
18
|
+
def opentelemetry_attributes(payload)
|
|
19
|
+
name = Appsignal::OpenTelemetry::SqlDbSystem.name_for_active_record(
|
|
20
|
+
payload[:connection]&.adapter_name
|
|
21
|
+
)
|
|
22
|
+
return unless name
|
|
23
|
+
|
|
24
|
+
{ "db.system.name" => name }
|
|
25
|
+
end
|
|
26
|
+
|
|
8
27
|
def format(payload)
|
|
9
28
|
[payload[:name], payload[:sql], SQL_BODY_FORMAT]
|
|
10
29
|
end
|
|
@@ -5,6 +5,21 @@ module Appsignal
|
|
|
5
5
|
# @!visibility private
|
|
6
6
|
module ElasticSearch
|
|
7
7
|
class SearchFormatter < Appsignal::EventFormatter
|
|
8
|
+
# A search is an outgoing call to an Elasticsearch cluster.
|
|
9
|
+
def opentelemetry_kind
|
|
10
|
+
:client
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def opentelemetry_attributes(payload)
|
|
14
|
+
{
|
|
15
|
+
"db.system.name" => "elasticsearch",
|
|
16
|
+
# This notification is only emitted for a search, so that is the
|
|
17
|
+
# operation every one of these spans describes.
|
|
18
|
+
"db.operation.name" => "search",
|
|
19
|
+
"db.collection.name" => search_index(payload)
|
|
20
|
+
}.compact
|
|
21
|
+
end
|
|
22
|
+
|
|
8
23
|
def format(payload)
|
|
9
24
|
[
|
|
10
25
|
"#{payload[:name]}: #{payload[:klass]}",
|
|
@@ -12,6 +27,18 @@ module Appsignal
|
|
|
12
27
|
]
|
|
13
28
|
end
|
|
14
29
|
|
|
30
|
+
# The index a search ran against, which the notification carries in the
|
|
31
|
+
# search it describes. A search that names more than one index, or none
|
|
32
|
+
# at all, is left without this attribute rather than described with a
|
|
33
|
+
# value that is not an index name.
|
|
34
|
+
def search_index(payload)
|
|
35
|
+
search = payload[:search]
|
|
36
|
+
return unless search.respond_to?(:[])
|
|
37
|
+
|
|
38
|
+
index = search[:index]
|
|
39
|
+
index if index.is_a?(String)
|
|
40
|
+
end
|
|
41
|
+
|
|
15
42
|
def sanitized_search(search)
|
|
16
43
|
return unless search.is_a?(Hash)
|
|
17
44
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Appsignal
|
|
4
|
+
class EventFormatter
|
|
5
|
+
# Registered for an event that a dedicated AppSignal integration already
|
|
6
|
+
# records with richer semantics. The generic instrumentation paths ask the
|
|
7
|
+
# registry whether to record an event, so registering this for an event
|
|
8
|
+
# name is how that integration claims it.
|
|
9
|
+
#
|
|
10
|
+
# @!visibility private
|
|
11
|
+
class RecordedElsewhere < Appsignal::EventFormatter
|
|
12
|
+
def record?
|
|
13
|
+
false
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -5,6 +5,18 @@ module Appsignal
|
|
|
5
5
|
# @!visibility private
|
|
6
6
|
module Rom
|
|
7
7
|
class SqlFormatter < Appsignal::EventFormatter
|
|
8
|
+
# These events arrive over dry-monitor, which is a notification bus
|
|
9
|
+
# rather than a library that queries a database. ROM is what emits
|
|
10
|
+
# them, so that is what the scope names.
|
|
11
|
+
def opentelemetry_scope
|
|
12
|
+
["appsignal-ruby/rom", Appsignal::VERSION]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# A query is an outgoing call to a datastore.
|
|
16
|
+
def opentelemetry_kind
|
|
17
|
+
:client
|
|
18
|
+
end
|
|
19
|
+
|
|
8
20
|
# dry-monitor reports an event under an id rather than a name, so the
|
|
9
21
|
# first value here names the event. Naming it after ROM keeps every ROM
|
|
10
22
|
# query in one group.
|
|
@@ -17,6 +29,18 @@ module Appsignal
|
|
|
17
29
|
def format(payload)
|
|
18
30
|
["query.rom", payload[:query], SQL_BODY_FORMAT]
|
|
19
31
|
end
|
|
32
|
+
|
|
33
|
+
# The payload's `name` is Sequel's `database_type` symbol for the
|
|
34
|
+
# database ROM is talking to, so this uses Sequel's own lookup
|
|
35
|
+
# rather than a coincidentally similar one. A symbol the mapping does
|
|
36
|
+
# not recognise is left to the SQL sentinel, same as an engine this
|
|
37
|
+
# gem has never heard of.
|
|
38
|
+
def opentelemetry_attributes(payload)
|
|
39
|
+
name = Appsignal::OpenTelemetry::SqlDbSystem.name_for_sequel(payload[:name])
|
|
40
|
+
return unless name
|
|
41
|
+
|
|
42
|
+
{ "db.system.name" => name }
|
|
43
|
+
end
|
|
20
44
|
end
|
|
21
45
|
end
|
|
22
46
|
end
|
|
@@ -10,6 +10,11 @@ module Appsignal
|
|
|
10
10
|
# formatter the sequel-rails events are recorded without the SQL query
|
|
11
11
|
# that's being executed.
|
|
12
12
|
class SqlFormatter < Appsignal::EventFormatter
|
|
13
|
+
# A query is an outgoing call to a datastore.
|
|
14
|
+
def opentelemetry_kind
|
|
15
|
+
:client
|
|
16
|
+
end
|
|
17
|
+
|
|
13
18
|
def format(payload)
|
|
14
19
|
[payload[:name].to_s, payload[:sql], SQL_BODY_FORMAT]
|
|
15
20
|
end
|
|
@@ -7,11 +7,28 @@ module Appsignal
|
|
|
7
7
|
class RenderFormatter < Appsignal::EventFormatter
|
|
8
8
|
BLANK = ""
|
|
9
9
|
|
|
10
|
+
def opentelemetry_attributes(_payload)
|
|
11
|
+
Appsignal::OpenTelemetry::Rendering.attributes
|
|
12
|
+
end
|
|
13
|
+
|
|
10
14
|
def format(payload)
|
|
15
|
+
# The body is the component's path made relative to the application's
|
|
16
|
+
# root, so a component rendered outside an application gets no title
|
|
17
|
+
# and no body.
|
|
18
|
+
return unless root_path
|
|
19
|
+
|
|
11
20
|
[payload[:name], payload[:identifier].sub(root_path, BLANK)]
|
|
12
21
|
end
|
|
13
22
|
|
|
23
|
+
# The application's root, which a component's path is made relative to.
|
|
24
|
+
#
|
|
25
|
+
# Whether there is an application is decided here, when the event is
|
|
26
|
+
# formatted, rather than when this file is loaded. AppSignal can be
|
|
27
|
+
# required before Rails is, and deciding it at load time would leave
|
|
28
|
+
# every component render in the application without a title.
|
|
14
29
|
def root_path
|
|
30
|
+
return unless defined?(Rails)
|
|
31
|
+
|
|
15
32
|
@root_path ||= "#{Rails.root}/"
|
|
16
33
|
end
|
|
17
34
|
end
|
|
@@ -19,13 +36,7 @@ module Appsignal
|
|
|
19
36
|
end
|
|
20
37
|
end
|
|
21
38
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
)
|
|
27
|
-
Appsignal::EventFormatter.register(
|
|
28
|
-
"!render.view_component",
|
|
29
|
-
Appsignal::EventFormatter::ViewComponent::RenderFormatter
|
|
30
|
-
)
|
|
31
|
-
end
|
|
39
|
+
Appsignal::EventFormatter.register(
|
|
40
|
+
"render.view_component",
|
|
41
|
+
Appsignal::EventFormatter::ViewComponent::RenderFormatter
|
|
42
|
+
)
|
|
@@ -102,8 +102,77 @@ module Appsignal
|
|
|
102
102
|
formatter&.format(payload)
|
|
103
103
|
end
|
|
104
104
|
|
|
105
|
+
# The OpenTelemetry span kind for an event, which its formatter can
|
|
106
|
+
# declare. An event with no formatter, or whose formatter declares
|
|
107
|
+
# nothing, has no kind of its own and falls back to the default.
|
|
108
|
+
#
|
|
109
|
+
# A formatter written against the documented interface only implements
|
|
110
|
+
# `format`, so ask whether this one answers to the method at all rather
|
|
111
|
+
# than assuming every formatter does.
|
|
112
|
+
#
|
|
113
|
+
# @!visibility private
|
|
114
|
+
def opentelemetry_kind(name)
|
|
115
|
+
formatter = formatter_for(name)
|
|
116
|
+
return unless formatter.respond_to?(:opentelemetry_kind)
|
|
117
|
+
|
|
118
|
+
formatter.opentelemetry_kind
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# The OpenTelemetry attributes describing an event, which its formatter
|
|
122
|
+
# can build from the event's payload. An event with no formatter, or
|
|
123
|
+
# whose formatter describes nothing, gets no attributes of its own.
|
|
124
|
+
#
|
|
125
|
+
# @!visibility private
|
|
126
|
+
def opentelemetry_attributes(name, payload)
|
|
127
|
+
formatter = formatter_for(name)
|
|
128
|
+
return unless formatter.respond_to?(:opentelemetry_attributes)
|
|
129
|
+
|
|
130
|
+
formatter.opentelemetry_attributes(payload)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# The OpenTelemetry instrumentation scope for an event, which its
|
|
134
|
+
# formatter can declare. It names the library the instrumentation is for,
|
|
135
|
+
# which is not always the library the event arrived through.
|
|
136
|
+
#
|
|
137
|
+
# An event with no formatter, or whose formatter declares nothing, is
|
|
138
|
+
# left to the scope the recording path derives for it.
|
|
139
|
+
#
|
|
140
|
+
# @!visibility private
|
|
141
|
+
def opentelemetry_scope(name)
|
|
142
|
+
formatter = formatter_for(name)
|
|
143
|
+
return unless formatter.respond_to?(:opentelemetry_scope)
|
|
144
|
+
|
|
145
|
+
formatter.opentelemetry_scope
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
# Whether the generic instrumentation paths should record an event, which
|
|
149
|
+
# its formatter can answer. An event a dedicated integration already
|
|
150
|
+
# records says no, so that it is not recorded a second time. An event
|
|
151
|
+
# with no formatter, or whose formatter says nothing, is recorded.
|
|
152
|
+
#
|
|
153
|
+
# @!visibility private
|
|
154
|
+
def record?(name)
|
|
155
|
+
formatter = formatter_for(name)
|
|
156
|
+
return true unless formatter.respond_to?(:record?)
|
|
157
|
+
|
|
158
|
+
formatter.record?
|
|
159
|
+
end
|
|
160
|
+
|
|
105
161
|
private
|
|
106
162
|
|
|
163
|
+
# The formatter registered for an event name.
|
|
164
|
+
#
|
|
165
|
+
# A formatter is registered under whatever key was given to `register`,
|
|
166
|
+
# which is a String for every formatter in this gem. An event can be
|
|
167
|
+
# instrumented under a Symbol name, so fall back to the String form of it.
|
|
168
|
+
#
|
|
169
|
+
# `format` does not do this, on purpose. It has always looked a name up
|
|
170
|
+
# exactly as given, so making it match a Symbol name would start giving a
|
|
171
|
+
# title to events that have never had one.
|
|
172
|
+
def formatter_for(name)
|
|
173
|
+
formatters[name] || formatters[name.to_s]
|
|
174
|
+
end
|
|
175
|
+
|
|
107
176
|
def initialize_formatter(name, formatter)
|
|
108
177
|
format_method = formatter.instance_method(:format)
|
|
109
178
|
if !format_method || format_method.arity != 1
|
|
@@ -123,6 +192,15 @@ module Appsignal
|
|
|
123
192
|
end
|
|
124
193
|
end
|
|
125
194
|
|
|
195
|
+
# The title and the body to show for an event, as an array. A formatter
|
|
196
|
+
# that is registered to describe an event in some other way, rather than to
|
|
197
|
+
# name it, does not have to implement this.
|
|
198
|
+
#
|
|
199
|
+
# @!visibility private
|
|
200
|
+
def format(_payload)
|
|
201
|
+
nil
|
|
202
|
+
end
|
|
203
|
+
|
|
126
204
|
# @return [Integer]
|
|
127
205
|
# @api public
|
|
128
206
|
DEFAULT = 0
|
data/lib/appsignal/extension.rb
CHANGED
|
@@ -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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
241
|
-
|
|
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(
|
|
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(
|
|
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
|
|
608
|
-
#
|
|
788
|
+
# Use this helper to report no parameters for this transaction, whatever
|
|
789
|
+
# their source.
|
|
609
790
|
#
|
|
610
|
-
#
|
|
611
|
-
#
|
|
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}
|
|
614
|
-
#
|
|
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]
|
|
@@ -715,7 +899,7 @@ module Appsignal
|
|
|
715
899
|
# Breadcrumbs can be used to trace what path a user has taken
|
|
716
900
|
# before encountering an error.
|
|
717
901
|
#
|
|
718
|
-
#
|
|
902
|
+
# At most 20 of the added breadcrumbs will be saved.
|
|
719
903
|
#
|
|
720
904
|
# @example
|
|
721
905
|
# Appsignal.add_breadcrumb(
|
|
@@ -786,6 +970,12 @@ module Appsignal
|
|
|
786
970
|
# instrumented. Accepted values are {EventFormatter::DEFAULT} and
|
|
787
971
|
# {EventFormatter::SQL_BODY_FORMAT}, but we recommend you use
|
|
788
972
|
# {.instrument_sql} instead of {EventFormatter::SQL_BODY_FORMAT}.
|
|
973
|
+
# @param opentelemetry_kind [Symbol] In collector mode, the OpenTelemetry
|
|
974
|
+
# span kind for the event's span, such as `:client` for an outgoing HTTP
|
|
975
|
+
# request. Defaults to the OpenTelemetry default of `:internal`.
|
|
976
|
+
# @param opentelemetry_scope [Array(String, String)] In collector mode, the
|
|
977
|
+
# OpenTelemetry instrumentation scope to record the event's span under,
|
|
978
|
+
# given as a `[name, version]` pair. Defaults to the AppSignal scope.
|
|
789
979
|
# @yield [] yields the given block of code instrumented in an AppSignal
|
|
790
980
|
# event.
|
|
791
981
|
# @return [Object] Returns the block's return value.
|
|
@@ -795,15 +985,25 @@ module Appsignal
|
|
|
795
985
|
# AppSignal custom instrumentation guide
|
|
796
986
|
# @see https://docs.appsignal.com/api/event-names.html
|
|
797
987
|
# AppSignal event naming guide
|
|
798
|
-
def instrument(
|
|
988
|
+
def instrument( # rubocop:disable Metrics/ParameterLists
|
|
799
989
|
name,
|
|
800
990
|
title = nil,
|
|
801
991
|
body = nil,
|
|
802
992
|
body_format = Appsignal::EventFormatter::DEFAULT,
|
|
993
|
+
opentelemetry_kind: nil,
|
|
994
|
+
opentelemetry_scope: nil,
|
|
803
995
|
&block
|
|
804
996
|
)
|
|
805
997
|
Appsignal::Transaction.current
|
|
806
|
-
.instrument(
|
|
998
|
+
.instrument(
|
|
999
|
+
name,
|
|
1000
|
+
title,
|
|
1001
|
+
body,
|
|
1002
|
+
body_format,
|
|
1003
|
+
:opentelemetry_kind => opentelemetry_kind,
|
|
1004
|
+
:opentelemetry_scope => opentelemetry_scope,
|
|
1005
|
+
&block
|
|
1006
|
+
)
|
|
807
1007
|
end
|
|
808
1008
|
|
|
809
1009
|
# Instrumentation helper for SQL queries.
|
|
@@ -827,6 +1027,13 @@ module Appsignal
|
|
|
827
1027
|
# naming guide listed under "See also".
|
|
828
1028
|
# @param title [String, nil] Human readable name of the event.
|
|
829
1029
|
# @param body [String, nil] SQL query that's being executed.
|
|
1030
|
+
# @param opentelemetry_kind [Symbol] In collector mode, the OpenTelemetry
|
|
1031
|
+
# span kind for the event's span. Defaults to `:client`, because a query
|
|
1032
|
+
# is an outgoing call to a datastore. Pass `:internal` for a query that
|
|
1033
|
+
# is not an outgoing call.
|
|
1034
|
+
# @param opentelemetry_scope [Array(String, String)] In collector mode, the
|
|
1035
|
+
# OpenTelemetry instrumentation scope to record the event's span under,
|
|
1036
|
+
# given as a `[name, version]` pair. Defaults to the AppSignal scope.
|
|
830
1037
|
# @yield [] yields the given block of code instrumented in an AppSignal
|
|
831
1038
|
# event.
|
|
832
1039
|
# @return [Object] Returns the block's return value.
|
|
@@ -836,12 +1043,21 @@ module Appsignal
|
|
|
836
1043
|
# AppSignal custom instrumentation guide
|
|
837
1044
|
# @see https://docs.appsignal.com/api/event-names.html
|
|
838
1045
|
# AppSignal event naming guide
|
|
839
|
-
def instrument_sql(
|
|
1046
|
+
def instrument_sql(
|
|
1047
|
+
name,
|
|
1048
|
+
title = nil,
|
|
1049
|
+
body = nil,
|
|
1050
|
+
opentelemetry_kind: :client,
|
|
1051
|
+
opentelemetry_scope: nil,
|
|
1052
|
+
&block
|
|
1053
|
+
)
|
|
840
1054
|
instrument(
|
|
841
1055
|
name,
|
|
842
1056
|
title,
|
|
843
1057
|
body,
|
|
844
1058
|
Appsignal::EventFormatter::SQL_BODY_FORMAT,
|
|
1059
|
+
:opentelemetry_kind => opentelemetry_kind,
|
|
1060
|
+
:opentelemetry_scope => opentelemetry_scope,
|
|
845
1061
|
&block
|
|
846
1062
|
)
|
|
847
1063
|
end
|