elastic-apm 1.1.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
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
|