elastic-apm 1.1.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of elastic-apm might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rspec +1 -0
- data/.rubocop.yml +7 -1
- data/CHANGELOG.md +45 -0
- data/Gemfile +17 -12
- data/bench/app.rb +1 -2
- data/bench/benchmark.rb +1 -1
- data/bench/stackprof.rb +1 -1
- data/docs/api.asciidoc +115 -76
- data/docs/configuration.asciidoc +232 -167
- data/docs/context.asciidoc +7 -3
- data/docs/custom-instrumentation.asciidoc +17 -28
- data/docs/index.asciidoc +13 -7
- data/docs/supported-technologies.asciidoc +65 -0
- data/elastic-apm.gemspec +3 -2
- data/lib/elastic_apm.rb +272 -121
- data/lib/elastic_apm/agent.rb +56 -107
- data/lib/elastic_apm/config.rb +130 -106
- data/lib/elastic_apm/config/duration.rb +25 -0
- data/lib/elastic_apm/config/size.rb +28 -0
- data/lib/elastic_apm/context_builder.rb +1 -0
- data/lib/elastic_apm/deprecations.rb +19 -0
- data/lib/elastic_apm/error.rb +5 -2
- data/lib/elastic_apm/error/exception.rb +1 -1
- data/lib/elastic_apm/error_builder.rb +5 -0
- data/lib/elastic_apm/instrumenter.rb +121 -53
- data/lib/elastic_apm/internal_error.rb +1 -0
- data/lib/elastic_apm/{log.rb → logging.rb} +16 -11
- data/lib/elastic_apm/metadata.rb +20 -0
- data/lib/elastic_apm/metadata/process_info.rb +26 -0
- data/lib/elastic_apm/metadata/service_info.rb +56 -0
- data/lib/elastic_apm/metadata/system_info.rb +30 -0
- data/lib/elastic_apm/middleware.rb +31 -15
- data/lib/elastic_apm/normalizers/action_controller.rb +1 -1
- data/lib/elastic_apm/normalizers/action_mailer.rb +1 -1
- data/lib/elastic_apm/normalizers/action_view.rb +3 -3
- data/lib/elastic_apm/normalizers/active_record.rb +2 -1
- data/lib/elastic_apm/railtie.rb +1 -1
- data/lib/elastic_apm/span.rb +59 -29
- data/lib/elastic_apm/span/context.rb +30 -4
- data/lib/elastic_apm/span_helpers.rb +1 -1
- data/lib/elastic_apm/spies/delayed_job.rb +7 -7
- data/lib/elastic_apm/spies/elasticsearch.rb +4 -4
- data/lib/elastic_apm/spies/http.rb +38 -0
- data/lib/elastic_apm/spies/mongo.rb +22 -11
- data/lib/elastic_apm/spies/net_http.rb +7 -4
- data/lib/elastic_apm/spies/rake.rb +5 -6
- data/lib/elastic_apm/spies/redis.rb +1 -1
- data/lib/elastic_apm/spies/sequel.rb +9 -7
- data/lib/elastic_apm/spies/sidekiq.rb +5 -5
- data/lib/elastic_apm/spies/tilt.rb +2 -2
- data/lib/elastic_apm/sql_summarizer.rb +3 -3
- data/lib/elastic_apm/stacktrace_builder.rb +6 -6
- data/lib/elastic_apm/subscriber.rb +3 -3
- data/lib/elastic_apm/traceparent.rb +62 -0
- data/lib/elastic_apm/transaction.rb +62 -93
- data/lib/elastic_apm/transport/base.rb +98 -0
- data/lib/elastic_apm/transport/connection.rb +175 -0
- data/lib/elastic_apm/transport/filters.rb +45 -0
- data/lib/elastic_apm/transport/filters/request_body_filter.rb +31 -0
- data/lib/elastic_apm/transport/filters/secrets_filter.rb +59 -0
- data/lib/elastic_apm/transport/serializers.rb +58 -0
- data/lib/elastic_apm/transport/serializers/error_serializer.rb +59 -0
- data/lib/elastic_apm/transport/serializers/span_serializer.rb +30 -0
- data/lib/elastic_apm/transport/serializers/transaction_serializer.rb +33 -0
- data/lib/elastic_apm/transport/worker.rb +73 -0
- data/lib/elastic_apm/util.rb +11 -8
- data/lib/elastic_apm/version.rb +1 -1
- metadata +40 -21
- data/.travis.yml +0 -5
- data/docs/troubleshooting.asciidoc +0 -28
- data/lib/elastic_apm/filters.rb +0 -46
- data/lib/elastic_apm/filters/request_body_filter.rb +0 -33
- data/lib/elastic_apm/filters/secrets_filter.rb +0 -59
- data/lib/elastic_apm/http.rb +0 -139
- data/lib/elastic_apm/process_info.rb +0 -24
- data/lib/elastic_apm/serializers.rb +0 -28
- data/lib/elastic_apm/serializers/errors.rb +0 -61
- data/lib/elastic_apm/serializers/transactions.rb +0 -51
- data/lib/elastic_apm/service_info.rb +0 -54
- data/lib/elastic_apm/system_info.rb +0 -28
- data/lib/elastic_apm/util/dig.rb +0 -31
- data/lib/elastic_apm/util/inspector.rb +0 -61
- data/lib/elastic_apm/worker.rb +0 -106
data/docs/context.asciidoc
CHANGED
@@ -5,13 +5,14 @@
|
|
5
5
|
[float]
|
6
6
|
==== Adding custom context
|
7
7
|
|
8
|
-
You can add your own custom, nested JSON-compatible data to the current
|
8
|
+
You can add your own custom, nested JSON-compatible data to the current
|
9
|
+
transaction using `ElasticAPM.set_custom_context(hash)` eg.:
|
9
10
|
|
10
11
|
[source,ruby]
|
11
12
|
----
|
12
13
|
class ThingsController < ApplicationController
|
13
14
|
before_action do
|
14
|
-
ElasticAPM.
|
15
|
+
ElasticAPM.set_custom_context(company: current_user.company)
|
15
16
|
end
|
16
17
|
|
17
18
|
# ...
|
@@ -21,13 +22,16 @@ end
|
|
21
22
|
[float]
|
22
23
|
==== Adding tags
|
23
24
|
|
24
|
-
Tags are special in that they are indexed in your Elasticsearch database and
|
25
|
+
Tags are special in that they are indexed in your Elasticsearch database and
|
26
|
+
therefore searchable.
|
25
27
|
|
26
28
|
[source,ruby]
|
27
29
|
----
|
28
30
|
ElasticAPM.set_tag(:company_name, 'Acme, Inc.')
|
29
31
|
----
|
30
32
|
|
33
|
+
Note that `.`, `*` and `"` in keys are converted to `_`.
|
34
|
+
|
31
35
|
[float]
|
32
36
|
==== Providing info about the user
|
33
37
|
|
@@ -1,19 +1,22 @@
|
|
1
1
|
[[custom-instrumentation]]
|
2
2
|
=== Custom instrumentation
|
3
3
|
|
4
|
-
When <<introduction,installed>> and <<configuration,properly configured>>
|
5
|
-
|
4
|
+
When <<introduction,installed>> and <<configuration,properly configured>>
|
5
|
+
ElasticAPM will automatically wrap your app's request/responses in transactions
|
6
|
+
and report its errors.
|
6
7
|
It also wraps each background job if you use Sidekiq or DelayedJob.
|
7
8
|
|
8
|
-
But it is possible to create your own transactions as well as provide spans for
|
9
|
-
automatic or custom transaction.
|
9
|
+
But it is possible to create your own transactions as well as provide spans for
|
10
|
+
any automatic or custom transaction.
|
10
11
|
|
11
|
-
See <<api-
|
12
|
+
See <<api-agent-start_transaction,`ElasticAPM.start_transaction`>> and
|
13
|
+
<<api-agent-start_span,`ElasticAPM.start_span`>>.
|
12
14
|
|
13
15
|
[float]
|
14
16
|
==== Helpers
|
15
17
|
|
16
|
-
ElasticAPM includes some nifty helpers if you just want to instrument a regular
|
18
|
+
ElasticAPM includes some nifty helpers if you just want to instrument a regular
|
19
|
+
method.
|
17
20
|
|
18
21
|
[source,ruby]
|
19
22
|
----
|
@@ -35,14 +38,14 @@ end
|
|
35
38
|
[float]
|
36
39
|
==== Custom span example
|
37
40
|
|
38
|
-
If you are already inside a Transaction (most likely) and you want to
|
41
|
+
If you are already inside a Transaction (most likely) and you want to instrument
|
39
42
|
some work inside it, add a custom span:
|
40
43
|
|
41
44
|
[source,ruby]
|
42
45
|
----
|
43
46
|
class ThingsController < ApplicationController
|
44
47
|
def index
|
45
|
-
@result_of_work = ElasticAPM.
|
48
|
+
@result_of_work = ElasticAPM.with_span "Heavy work" do
|
46
49
|
do_the_heavy_work
|
47
50
|
end
|
48
51
|
end
|
@@ -52,40 +55,26 @@ end
|
|
52
55
|
[float]
|
53
56
|
==== Custom transaction example
|
54
57
|
|
55
|
-
If you are **not** inside a Transaction already (eg. outside of your common web
|
56
|
-
start and manage your own transactions like so:
|
58
|
+
If you are **not** inside a Transaction already (eg. outside of your common web
|
59
|
+
application) start and manage your own transactions like so:
|
57
60
|
|
58
61
|
[source,ruby]
|
59
62
|
----
|
60
63
|
class Something
|
61
64
|
def do_work
|
62
|
-
transaction = ElasticAPM.
|
65
|
+
transaction = ElasticAPM.start_transaction 'Something#do_work'
|
63
66
|
|
64
67
|
begin
|
65
68
|
Sequel[:users] # many third party libs will be automatically instrumented
|
66
|
-
transaction.submit('success') if transaction
|
67
69
|
rescue Exception => e
|
68
70
|
ElasticAPM.report(e)
|
69
|
-
transaction.submit('error') if transaction
|
70
71
|
raise
|
71
72
|
ensure
|
72
|
-
|
73
|
+
ElasticAPM.end_transaction('result')
|
73
74
|
end
|
74
75
|
end
|
75
76
|
end
|
76
77
|
----
|
77
78
|
|
78
|
-
**Note:** If the agent isn't started beforehand this will do nothing.
|
79
|
-
|
80
|
-
[[spies]]
|
81
|
-
=== Spies
|
82
|
-
|
83
|
-
[float]
|
84
|
-
==== Automatic integrations with third-party libraries
|
85
|
-
|
86
|
-
ElasticAPM has built-in integrations for some popular libraries.
|
87
|
-
Use `config.disabled_spies` to disable specific integrations.
|
88
|
-
|
89
|
-
For a list of available spies, see
|
90
|
-
https://github.com/elastic/apm-agent-ruby/blob/1.x/lib/elastic_apm/config.rb#L174-L188[config.rb].
|
91
|
-
|
79
|
+
**Note:** If the agent isn't started beforehand this will do nothing.
|
80
|
+
See <<api-agent-start,ElasticAPM.start>>.
|
data/docs/index.asciidoc
CHANGED
@@ -2,7 +2,8 @@
|
|
2
2
|
include::{asciidoc-dir}/../../shared/attributes.asciidoc[]
|
3
3
|
|
4
4
|
ifdef::env-github[]
|
5
|
-
NOTE: For the best reading experience, please view this documentation at
|
5
|
+
NOTE: For the best reading experience, please view this documentation at
|
6
|
+
https://www.elastic.co/guide/en/apm/agent/ruby[elastic.co]
|
6
7
|
endif::[]
|
7
8
|
|
8
9
|
= APM Ruby Agent Reference
|
@@ -10,18 +11,23 @@ endif::[]
|
|
10
11
|
[[introduction]]
|
11
12
|
== Introduction
|
12
13
|
|
13
|
-
The Elastic APM Ruby Agent sends performance metrics and error logs to an
|
14
|
+
The Elastic APM Ruby Agent sends performance metrics and error logs to an
|
15
|
+
Elastic APM Server.
|
14
16
|
|
15
|
-
It has built-in support for <<getting-started-rails,Ruby on Rails>> and other
|
17
|
+
It has built-in support for <<getting-started-rails,Ruby on Rails>> and other
|
18
|
+
<<getting-started-rack,Rack-compatible>> applications.
|
16
19
|
|
17
|
-
This agent is one of several components you need to get started collecting APM
|
20
|
+
This agent is one of several components you need to get started collecting APM
|
21
|
+
data. See also:
|
18
22
|
|
19
23
|
* {apm-server-ref}[APM Server]
|
20
24
|
|
21
25
|
[[framework-support]]
|
22
|
-
The Elastic APM Ruby Agent officially supports
|
26
|
+
The Elastic APM Ruby Agent officially supports Ruby on Rails versions 4.x on
|
27
|
+
onwards, see <<getting-started-rails,Getting started with Ruby on Rails>>.
|
23
28
|
|
24
|
-
For Sinatra and other Rack compatible frameworks, see
|
29
|
+
For Sinatra and other Rack compatible frameworks, see
|
30
|
+
<<getting-started-rack,Getting started with Rack>>.
|
25
31
|
|
26
32
|
include::./getting-started-rails.asciidoc[]
|
27
33
|
include::./getting-started-rack.asciidoc[]
|
@@ -31,7 +37,7 @@ include::./configuration.asciidoc[]
|
|
31
37
|
== Advanced Topics
|
32
38
|
include::./context.asciidoc[]
|
33
39
|
include::./custom-instrumentation.asciidoc[]
|
34
|
-
include::./troubleshooting.asciidoc[]
|
35
40
|
|
41
|
+
include::./supported-technologies.asciidoc[]
|
36
42
|
include::./api.asciidoc[]
|
37
43
|
|
@@ -0,0 +1,65 @@
|
|
1
|
+
[[supported-technologies]]
|
2
|
+
== Supported technologies
|
3
|
+
|
4
|
+
The Elastic APM Ruby Agent has built-in support for many frameworks and
|
5
|
+
libraries.
|
6
|
+
|
7
|
+
Generally we want to support all the most popular libraries, so if your favorite
|
8
|
+
is missing feel free so request it in an issue or better yet supply a pull
|
9
|
+
request.
|
10
|
+
|
11
|
+
[float]
|
12
|
+
[[supported-technologies-ruby]]
|
13
|
+
=== Ruby
|
14
|
+
|
15
|
+
We follow Ruby's own maintenance policy and officially support all currently
|
16
|
+
maintained versions per
|
17
|
+
https://www.ruby-lang.org/en/downloads/branches/[Ruby Maintenance Branches].
|
18
|
+
|
19
|
+
[float]
|
20
|
+
[[supported-technologies-web]]
|
21
|
+
=== Web Frameworks and Libraries
|
22
|
+
|
23
|
+
We have automatic support for Ruby on Rails and all Rack compatible web
|
24
|
+
frameworks.
|
25
|
+
|
26
|
+
We test against all supported minor versions of Rails and Sinatra.
|
27
|
+
|
28
|
+
[float]
|
29
|
+
[[supported-technologies-rails]]
|
30
|
+
==== Ruby on Rails
|
31
|
+
|
32
|
+
We currently support all versions of Rails since 4.2.
|
33
|
+
This follows Rails' own https://rubyonrails.org/security/[Security policy].
|
34
|
+
|
35
|
+
See <<getting-started-rails>>.
|
36
|
+
|
37
|
+
[float]
|
38
|
+
[[supported-technologies-sinatra]]
|
39
|
+
==== Sinatra
|
40
|
+
|
41
|
+
We currently support all versions of Sinatra since 1.0.
|
42
|
+
|
43
|
+
See <<getting-started-rack>>.
|
44
|
+
|
45
|
+
[float]
|
46
|
+
[[supported-technologies-databases]]
|
47
|
+
=== Databases
|
48
|
+
|
49
|
+
We automatically instrument database actions using:
|
50
|
+
|
51
|
+
- ActiveRecord
|
52
|
+
- Elasticsearch
|
53
|
+
- Mongo
|
54
|
+
- Redis
|
55
|
+
- Sequel
|
56
|
+
|
57
|
+
[float]
|
58
|
+
[[supported-technologies-http]]
|
59
|
+
=== External HTTP requests
|
60
|
+
|
61
|
+
We automatically instrument and add support for distributed tracing to external
|
62
|
+
requests using these libraries:
|
63
|
+
|
64
|
+
- `net/http`
|
65
|
+
- Http.rb
|
data/elastic-apm.gemspec
CHANGED
@@ -12,13 +12,14 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.homepage = 'https://github.com/elastic/apm-agent-ruby'
|
13
13
|
spec.metadata = { 'source_code_uri' => 'https://github.com/elastic/apm-agent-ruby' }
|
14
14
|
spec.license = 'Apache-2.0'
|
15
|
-
spec.required_ruby_version = ">= 2.
|
15
|
+
spec.required_ruby_version = ">= 2.3.0"
|
16
16
|
|
17
17
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
18
|
f.match(%r{^(test|spec|features)/})
|
19
19
|
end
|
20
20
|
|
21
|
-
spec.add_dependency('concurrent-ruby', '~> 1.0
|
21
|
+
spec.add_dependency('concurrent-ruby', '~> 1.0')
|
22
|
+
spec.add_dependency('http', '>= 3.0')
|
22
23
|
|
23
24
|
spec.require_paths = ['lib']
|
24
25
|
end
|
data/lib/elastic_apm.rb
CHANGED
@@ -1,16 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'elastic_apm/version'
|
4
|
-
require 'elastic_apm/
|
5
|
-
require 'elastic_apm/
|
4
|
+
require 'elastic_apm/internal_error'
|
5
|
+
require 'elastic_apm/logging'
|
6
|
+
require 'elastic_apm/deprecations'
|
6
7
|
|
7
8
|
# Core
|
8
9
|
require 'elastic_apm/agent'
|
9
10
|
require 'elastic_apm/config'
|
10
11
|
require 'elastic_apm/context'
|
11
12
|
require 'elastic_apm/instrumenter'
|
12
|
-
require 'elastic_apm/internal_error'
|
13
|
-
require 'elastic_apm/span_helpers'
|
14
13
|
require 'elastic_apm/util'
|
15
14
|
|
16
15
|
require 'elastic_apm/middleware'
|
@@ -18,142 +17,294 @@ require 'elastic_apm/middleware'
|
|
18
17
|
require 'elastic_apm/railtie' if defined?(::Rails::Railtie)
|
19
18
|
|
20
19
|
# ElasticAPM
|
21
|
-
module ElasticAPM
|
22
|
-
|
23
|
-
|
24
|
-
# Starts the ElasticAPM Agent
|
25
|
-
#
|
26
|
-
# @param config [Config] An instance of Config
|
27
|
-
# @return [Agent] The resulting [Agent]
|
28
|
-
def self.start(config = {})
|
29
|
-
Agent.start config
|
30
|
-
end
|
20
|
+
module ElasticAPM # rubocop:disable Metrics/ModuleLength
|
21
|
+
class << self
|
22
|
+
extend ElasticAPM::Deprecations
|
31
23
|
|
32
|
-
|
33
|
-
def self.stop
|
34
|
-
Agent.stop
|
35
|
-
end
|
24
|
+
### Life cycle
|
36
25
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
26
|
+
# Starts the ElasticAPM Agent
|
27
|
+
#
|
28
|
+
# @param config [Config] An instance of Config
|
29
|
+
# @return [Agent] The resulting [Agent]
|
30
|
+
def start(config = {})
|
31
|
+
Agent.start config
|
32
|
+
end
|
41
33
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
34
|
+
# Stops the ElasticAPM Agent
|
35
|
+
def stop
|
36
|
+
Agent.stop
|
37
|
+
end
|
46
38
|
|
47
|
-
|
39
|
+
# @return [Boolean] Whether there's an [Agent] running
|
40
|
+
def running?
|
41
|
+
Agent.running?
|
42
|
+
end
|
48
43
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
agent && agent.current_transaction
|
54
|
-
end
|
44
|
+
# @return [Agent] Currently running [Agent] if any
|
45
|
+
def agent
|
46
|
+
Agent.instance
|
47
|
+
end
|
55
48
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
49
|
+
### Metrics
|
50
|
+
|
51
|
+
# Returns the currently active transaction (if any)
|
52
|
+
#
|
53
|
+
# @return [Transaction] or `nil`
|
54
|
+
def current_transaction
|
55
|
+
agent&.current_transaction
|
56
|
+
end
|
57
|
+
|
58
|
+
# Returns the currently active span (if any)
|
59
|
+
#
|
60
|
+
# @return [Span] or `nil`
|
61
|
+
def current_span
|
62
|
+
agent&.current_span
|
63
|
+
end
|
64
|
+
|
65
|
+
# Start a new transaction or return the currently running
|
66
|
+
#
|
67
|
+
# @param name [String] A description of the transaction, eg
|
68
|
+
# `ExamplesController#index`
|
69
|
+
# @param type [String] The kind of the transaction, eg `app.request.get` or
|
70
|
+
# `db.mysql2.query`
|
71
|
+
# @param context [Context] An optional [Context]
|
72
|
+
# @yield [Transaction] Optional block encapsulating transaction
|
73
|
+
# @return [Transaction] Unless block given
|
74
|
+
# @deprecated See `with_transaction` or `start_transaction`
|
75
|
+
def transaction(name = nil, type = nil, context: nil, &block)
|
76
|
+
return (block_given? ? yield : nil) unless agent
|
77
|
+
|
78
|
+
if block_given?
|
79
|
+
with_transaction(name, type, context: context, &block)
|
80
|
+
else
|
81
|
+
start_transaction(name, type, context: context)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
deprecate :transaction, :with_transaction
|
86
|
+
|
87
|
+
# Start a new transaction
|
88
|
+
#
|
89
|
+
# @param name [String] A description of the transaction, eg
|
90
|
+
# `ExamplesController#index`
|
91
|
+
# @param type [String] The kind of the transaction, eg `app.request.get` or
|
92
|
+
# `db.mysql2.query`
|
93
|
+
# @param context [Context] An optional [Context]
|
94
|
+
# @return [Transaction]
|
95
|
+
def start_transaction(
|
96
|
+
name = nil,
|
97
|
+
type = nil,
|
98
|
+
context: nil,
|
99
|
+
traceparent: nil
|
100
|
+
)
|
101
|
+
agent&.start_transaction(
|
102
|
+
name,
|
103
|
+
type,
|
104
|
+
context: context,
|
105
|
+
traceparent: traceparent
|
106
|
+
)
|
107
|
+
end
|
108
|
+
|
109
|
+
# Ends the current transaction with `result`
|
110
|
+
#
|
111
|
+
# @param result [String] The result of the transaction
|
112
|
+
# @return [Transaction]
|
113
|
+
def end_transaction(result = nil)
|
114
|
+
agent&.end_transaction(result)
|
115
|
+
end
|
116
|
+
|
117
|
+
# rubocop:disable Metrics/MethodLength
|
118
|
+
# Wrap a block in a Transaction, ending it after the block
|
119
|
+
#
|
120
|
+
# @param name [String] A description of the transaction, eg
|
121
|
+
# `ExamplesController#index`
|
122
|
+
# @param type [String] The kind of the transaction, eg `app.request.get` or
|
123
|
+
# `db.mysql2.query`
|
124
|
+
# @param context [Context] An optional [Context]
|
125
|
+
# @yield [Transaction]
|
126
|
+
# @return result of block
|
127
|
+
def with_transaction(name = nil, type = nil, context: nil, traceparent: nil)
|
128
|
+
unless block_given?
|
129
|
+
raise ArgumentError,
|
130
|
+
'expected a block. Do you want `start_transaction\' instead?'
|
131
|
+
end
|
132
|
+
|
133
|
+
return yield(nil) unless agent
|
70
134
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
135
|
+
begin
|
136
|
+
transaction =
|
137
|
+
start_transaction(
|
138
|
+
name,
|
139
|
+
type,
|
140
|
+
context: context,
|
141
|
+
traceparent: traceparent
|
142
|
+
)
|
143
|
+
yield transaction
|
144
|
+
ensure
|
145
|
+
end_transaction
|
146
|
+
end
|
147
|
+
end
|
148
|
+
# rubocop:enable Metrics/MethodLength
|
149
|
+
|
150
|
+
# rubocop:disable Metrics/MethodLength
|
151
|
+
# Start a new span
|
152
|
+
#
|
153
|
+
# @param name [String] A description of the span, eq `SELECT FROM "users"`
|
154
|
+
# @param type [String] The kind of span, eq `db.mysql2.query`
|
155
|
+
# @param context [Span::Context] Context information about the span
|
156
|
+
# @yield [Span] Optional block encapsulating span
|
157
|
+
# @return [Span] Unless block given
|
158
|
+
# @deprecated See `with_span` or `start_span`
|
159
|
+
def span(name, type = nil, context: nil, include_stacktrace: true, &block)
|
160
|
+
return (block_given? ? yield : nil) unless agent
|
161
|
+
|
162
|
+
if block_given?
|
163
|
+
with_span(
|
164
|
+
name,
|
165
|
+
type,
|
166
|
+
context:
|
167
|
+
context,
|
168
|
+
include_stacktrace: include_stacktrace,
|
169
|
+
&block
|
170
|
+
)
|
171
|
+
else
|
172
|
+
start_span(
|
173
|
+
name,
|
174
|
+
type,
|
175
|
+
context: context,
|
176
|
+
include_stacktrace: include_stacktrace
|
177
|
+
)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
# rubocop:enable Metrics/MethodLength
|
181
|
+
|
182
|
+
deprecate :span, :with_span
|
183
|
+
|
184
|
+
# Start a new span
|
185
|
+
#
|
186
|
+
# @param name [String] A description of the span, eq `SELECT FROM "users"`
|
187
|
+
# @param type [String] The kind of span, eq `db.mysql2.query`
|
188
|
+
# @param context [Span::Context] Context information about the span
|
189
|
+
# @param include_stacktrace [Boolean] Whether or not to capture a stacktrace
|
190
|
+
# @return [Span]
|
191
|
+
def start_span(name, type = nil, context: nil, include_stacktrace: true)
|
192
|
+
agent&.start_span(
|
193
|
+
name,
|
194
|
+
type,
|
195
|
+
context: context,
|
196
|
+
backtrace: include_stacktrace ? caller : nil
|
197
|
+
)
|
198
|
+
end
|
199
|
+
|
200
|
+
# Ends the current span
|
201
|
+
#
|
202
|
+
# @return [Span]
|
203
|
+
def end_span
|
204
|
+
agent&.end_span
|
205
|
+
end
|
206
|
+
|
207
|
+
# rubocop:disable Metrics/MethodLength
|
208
|
+
# Wrap a block in a Span, ending it after the block
|
209
|
+
#
|
210
|
+
# @param name [String] A description of the span, eq `SELECT FROM "users"`
|
211
|
+
# @param type [String] The kind of span, eq `db.mysql2.query`
|
212
|
+
# @param context [Span::Context] Context information about the span
|
213
|
+
# @param include_stacktrace [Boolean] Whether or not to capture a stacktrace
|
214
|
+
# @yield [Span]
|
215
|
+
# @return Result of block
|
216
|
+
def with_span(
|
83
217
|
name,
|
84
|
-
type,
|
85
|
-
context:
|
86
|
-
|
87
|
-
&block
|
218
|
+
type = nil,
|
219
|
+
context: nil,
|
220
|
+
include_stacktrace: true
|
88
221
|
)
|
89
|
-
|
222
|
+
unless block_given?
|
223
|
+
raise ArgumentError,
|
224
|
+
'expected a block. Do you want `start_span\' instead?'
|
225
|
+
end
|
90
226
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
227
|
+
return yield nil unless agent
|
228
|
+
|
229
|
+
begin
|
230
|
+
span =
|
231
|
+
start_span(
|
232
|
+
name, type, context: context, include_stacktrace: include_stacktrace
|
233
|
+
)
|
234
|
+
yield span
|
235
|
+
ensure
|
236
|
+
end_span
|
237
|
+
end
|
238
|
+
end
|
239
|
+
# rubocop:enable Metrics/MethodLength
|
99
240
|
|
100
|
-
|
241
|
+
# Build a [Context] from a Rack `env`. The context may include information
|
242
|
+
# about the request, response, current user and more
|
243
|
+
#
|
244
|
+
# @param rack_env [Rack::Env] A Rack env
|
245
|
+
# @return [Context] The built context
|
246
|
+
def build_context(rack_env)
|
247
|
+
agent&.build_context(rack_env)
|
248
|
+
end
|
101
249
|
|
102
|
-
|
103
|
-
#
|
104
|
-
# @param exception [Exception] The exception
|
105
|
-
# @param handled [Boolean] Whether the exception was rescued
|
106
|
-
# @return [Error] The generated [Error]
|
107
|
-
def self.report(exception, handled: true)
|
108
|
-
agent && agent.report(exception, handled: handled)
|
109
|
-
end
|
250
|
+
### Errors
|
110
251
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
252
|
+
# Report and exception to APM
|
253
|
+
#
|
254
|
+
# @param exception [Exception] The exception
|
255
|
+
# @param handled [Boolean] Whether the exception was rescued
|
256
|
+
# @return [Error] The generated [Error]
|
257
|
+
def report(exception, handled: true)
|
258
|
+
agent&.report(exception, handled: handled)
|
259
|
+
end
|
118
260
|
|
119
|
-
|
261
|
+
# Report a custom string error message to APM
|
262
|
+
#
|
263
|
+
# @param message [String] The message
|
264
|
+
# @return [Error] The generated [Error]
|
265
|
+
def report_message(message, **attrs)
|
266
|
+
agent&.report_message(message, backtrace: caller, **attrs)
|
267
|
+
end
|
120
268
|
|
121
|
-
|
122
|
-
#
|
123
|
-
# @param key [String,Symbol] A key
|
124
|
-
# @param value [Object] A value (will be converted to string)
|
125
|
-
# @return [Object] The given value
|
126
|
-
def self.set_tag(key, value)
|
127
|
-
agent && agent.set_tag(key, value)
|
128
|
-
end
|
269
|
+
### Context
|
129
270
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
271
|
+
# Set a _tag_ value for the current transaction
|
272
|
+
#
|
273
|
+
# @param key [String,Symbol] A key
|
274
|
+
# @param value [Object] A value (will be converted to string)
|
275
|
+
# @return [Object] The given value
|
276
|
+
def set_tag(key, value)
|
277
|
+
agent&.set_tag(key, value)
|
278
|
+
end
|
137
279
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
280
|
+
# Provide further context for the current transaction
|
281
|
+
#
|
282
|
+
# @param custom [Hash] A hash with custom information. Can be nested.
|
283
|
+
# @return [Hash] The current custom context
|
284
|
+
def set_custom_context(custom)
|
285
|
+
agent&.set_custom_context(custom)
|
286
|
+
end
|
145
287
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
def self.add_filter(key, callback = nil, &block)
|
153
|
-
if callback.nil? && !block_given?
|
154
|
-
raise ArgumentError, '#add_filter needs either `callback\' or a block'
|
288
|
+
# Provide a user to the current transaction
|
289
|
+
#
|
290
|
+
# @param user [Object] An object representing a user
|
291
|
+
# @return [Object] Given user
|
292
|
+
def set_user(user)
|
293
|
+
agent&.set_user(user)
|
155
294
|
end
|
156
295
|
|
157
|
-
|
296
|
+
# Provide a filter to transform payloads before sending them off
|
297
|
+
#
|
298
|
+
# @param key [Symbol] Unique filter key
|
299
|
+
# @param callback [Object, Proc] A filter that responds to #call(payload)
|
300
|
+
# @yield [Hash] A filter. Used if provided. Otherwise using `callback`
|
301
|
+
# @return [Bool] true
|
302
|
+
def add_filter(key, callback = nil, &block)
|
303
|
+
if callback.nil? && !block_given?
|
304
|
+
raise ArgumentError, '#add_filter needs either `callback\' or a block'
|
305
|
+
end
|
306
|
+
|
307
|
+
agent&.add_filter(key, block || callback)
|
308
|
+
end
|
158
309
|
end
|
159
310
|
end
|