elastic-apm 0.2.0 → 0.3.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/.rubocop.yml +4 -0
- data/README.md +17 -49
- data/docs/api.asciidoc +15 -0
- data/docs/configuration.asciidoc +2 -0
- data/docs/context.asciidoc +16 -0
- data/docs/getting-started-rails.asciidoc +1 -0
- data/lib/elastic_apm.rb +33 -2
- data/lib/elastic_apm/agent.rb +15 -3
- data/lib/elastic_apm/config.rb +42 -22
- data/lib/elastic_apm/context_builder.rb +1 -22
- data/lib/elastic_apm/error_builder.rb +2 -4
- data/lib/elastic_apm/filters.rb +44 -0
- data/lib/elastic_apm/filters/request_body_filter.rb +33 -0
- data/lib/elastic_apm/filters/secrets_filter.rb +58 -0
- data/lib/elastic_apm/http.rb +7 -4
- data/lib/elastic_apm/instrumenter.rb +5 -1
- data/lib/elastic_apm/log.rb +7 -4
- data/lib/elastic_apm/middleware.rb +1 -10
- data/lib/elastic_apm/serializers/transactions.rb +18 -11
- data/lib/elastic_apm/service_info.rb +5 -7
- data/lib/elastic_apm/span.rb +2 -1
- data/lib/elastic_apm/sql_summarizer.rb +6 -2
- data/lib/elastic_apm/stacktrace.rb +11 -6
- data/lib/elastic_apm/stacktrace/frame.rb +13 -11
- data/lib/elastic_apm/stacktrace/line_cache.rb +25 -0
- data/lib/elastic_apm/subscriber.rb +3 -5
- data/lib/elastic_apm/system_info.rb +1 -5
- data/lib/elastic_apm/transaction.rb +8 -2
- data/lib/elastic_apm/util/dig.rb +31 -0
- data/lib/elastic_apm/util/lru_cache.rb +37 -0
- data/lib/elastic_apm/version.rb +1 -1
- data/lib/elastic_apm/worker.rb +2 -4
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f6272279575b41ace4dc7581df1d6ea387f46c260d591c338fceb256f0b46ff2
|
4
|
+
data.tar.gz: f793a0c902a18abfe647e5a3a41c86d96926910dfef21094aa3b1c37deac45eb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3f16cbdffc10a05005c03ec0d122235c84b56a9bda9f2201fd913e1d3b96925d3f5ef0847cfd2cc369da0b1d1c39c21dccd187579f278d7439218c97b4548a97
|
7
|
+
data.tar.gz: 4daea6a3d579f4fba6435de9277bdd842889b6afeab63c97da9a9424809d6e4721bd873da4edecae1eeb66281ae43989385027099f0c828a38bff94c4ec3addd
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
@@ -1,57 +1,25 @@
|
|
1
|
-
# elastic-apm – Elastic APM agent for Ruby (
|
1
|
+
# elastic-apm – Elastic APM agent for Ruby (BETA)
|
2
2
|
|
3
3
|
[![Jenkins](https://img.shields.io/jenkins/s/https/apm-ci.elastic.co/job/elastic+apm-agent-ruby+master.svg)](https://apm-ci.elastic.co/job/elastic+apm-agent-ruby+master/) [![Gem](https://img.shields.io/gem/v/formatador.svg?style=flat-square)](https://rubygems.org/gems/elastic-apm)
|
4
4
|
|
5
5
|
This is the official Rubygem for adding [Elastic][]'s [APM][] to your Ruby app.
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
The suggested way to configure is to create a file `config/elastic_apm.yml` with your config:
|
24
|
-
|
25
|
-
```yaml
|
26
|
-
# config/elastic_apm.yml
|
27
|
-
|
28
|
-
server_url: http://localhost:8200
|
29
|
-
secret_token: YOUR_SECRET
|
30
|
-
```
|
31
|
-
|
32
|
-
## Getting started with Sinatra
|
33
|
-
|
34
|
-
```ruby
|
35
|
-
# config.ru
|
36
|
-
|
37
|
-
require 'sinatra/base'
|
38
|
-
|
39
|
-
class MySinatraApp < Sinatra::Base
|
40
|
-
use ElasticAPM::Middleware
|
41
|
-
|
42
|
-
# ...
|
43
|
-
end
|
44
|
-
|
45
|
-
# Takes optional ElasticAPM::Config values
|
46
|
-
ElasticAPM.start(
|
47
|
-
app: MySinatraApp, # required
|
48
|
-
server_url: 'http://localhost:8200'
|
49
|
-
)
|
50
|
-
|
51
|
-
run MySinatraApp
|
52
|
-
|
53
|
-
at_exit { ElasticAPM.stop }
|
54
|
-
```
|
7
|
+
<div>
|
8
|
+
<ul>
|
9
|
+
<li><a href="https://www.elastic.co/guide/en/apm/agent/ruby/1.x/_introduction.html">Introduction</a></li>
|
10
|
+
<li><a href="https://www.elastic.co/guide/en/apm/agent/ruby/1.x/getting-started-rails.html">Getting started with Rails</a></li>
|
11
|
+
<li><a href="https://www.elastic.co/guide/en/apm/agent/ruby/1.x/getting-started-rack.html">Getting started with Rack</a></li>
|
12
|
+
<li><a href="https://www.elastic.co/guide/en/apm/agent/ruby/1.x/configuration.html">Configuration</a></li>
|
13
|
+
<li class="collapsible">
|
14
|
+
<a href="https://www.elastic.co/guide/en/apm/agent/ruby/1.x/advanced.html">Advanced Topics</a>
|
15
|
+
<ul>
|
16
|
+
<li><a href="https://www.elastic.co/guide/en/apm/agent/ruby/1.x/custom-instrumentation.html">Custom instrumentation</a></li>
|
17
|
+
<li><a href="https://www.elastic.co/guide/en/apm/agent/ruby/1.x/injectors.html">Injectors — automatic integrations with third-party libraries</a></li>
|
18
|
+
</ul>
|
19
|
+
</li>
|
20
|
+
<li><a href="https://www.elastic.co/guide/en/apm/agent/ruby/1.x/api.html">Public API</a></li>
|
21
|
+
</ul>
|
22
|
+
</div>
|
55
23
|
|
56
24
|
# License
|
57
25
|
|
data/docs/api.asciidoc
CHANGED
@@ -44,6 +44,7 @@ Returns whether the ElasticAPM Agent is currently running.
|
|
44
44
|
|
45
45
|
Returns the currently running agent or nil.
|
46
46
|
|
47
|
+
[float]
|
47
48
|
=== Instrumentation
|
48
49
|
|
49
50
|
[float]
|
@@ -119,6 +120,7 @@ Arguments:
|
|
119
120
|
|
120
121
|
Returns the built context.
|
121
122
|
|
123
|
+
[float]
|
122
124
|
=== Errors
|
123
125
|
|
124
126
|
[float]
|
@@ -165,6 +167,7 @@ Arguments:
|
|
165
167
|
|
166
168
|
Returns `[ElasticAPM::Error]`.
|
167
169
|
|
170
|
+
[float]
|
168
171
|
=== Context
|
169
172
|
|
170
173
|
[float]
|
@@ -208,3 +211,15 @@ Arguments:
|
|
208
211
|
|
209
212
|
Returns current custom context.
|
210
213
|
|
214
|
+
[float]
|
215
|
+
[[api-set-user]]
|
216
|
+
==== `ElasticAPM.set_user`
|
217
|
+
|
218
|
+
Add the current user to the current transaction's context.
|
219
|
+
|
220
|
+
Arguments:
|
221
|
+
|
222
|
+
* `user`: An object representing the user
|
223
|
+
|
224
|
+
Returns the given user
|
225
|
+
|
data/docs/configuration.asciidoc
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
There are several ways to shape how Elastic APM behaves.
|
5
5
|
|
6
|
+
[float]
|
6
7
|
=== Rails
|
7
8
|
|
8
9
|
The recommended way to configure Elastic APM for Rails is to create a file `config/elastic_apm.yml` and specify options in there:
|
@@ -14,6 +15,7 @@ server_url: 'http://localhost:8200'
|
|
14
15
|
secret_token: 'very_very_secret'
|
15
16
|
----
|
16
17
|
|
18
|
+
[float]
|
17
19
|
=== Sinatra and Rack
|
18
20
|
|
19
21
|
When using APM with Sinatra and Rack, you should configure it when starting the agent:
|
data/docs/context.asciidoc
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
[float]
|
1
2
|
[[context]]
|
2
3
|
=== Adding additional context
|
3
4
|
|
5
|
+
[float]
|
4
6
|
==== Adding custom context
|
5
7
|
|
6
8
|
You can add your own custom, nested JSON-compatible data to the current transaction using `ElasticAPM.add_custom_context(hash)` eg.:
|
@@ -16,6 +18,7 @@ class ThingsController < ApplicationController
|
|
16
18
|
end
|
17
19
|
----
|
18
20
|
|
21
|
+
[float]
|
19
22
|
==== Adding tags
|
20
23
|
|
21
24
|
Tags are special in that they are indexed in your Elasticsearch database and therefore searchable.
|
@@ -25,3 +28,16 @@ Tags are special in that they are indexed in your Elasticsearch database and the
|
|
25
28
|
ElasticAPM.set_tag(:company_name, 'Acme, Inc.')
|
26
29
|
----
|
27
30
|
|
31
|
+
[float]
|
32
|
+
==== Providing info about the user
|
33
|
+
|
34
|
+
You can provide ElasticAPM with info about the current user.
|
35
|
+
|
36
|
+
[source,ruby]
|
37
|
+
----
|
38
|
+
class ApplicationController < ActionController::Base
|
39
|
+
before_action do
|
40
|
+
current_user && ElasticAPM.set_user(current_user)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
----
|
data/lib/elastic_apm.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'elastic_apm/version'
|
4
4
|
require 'elastic_apm/log'
|
5
|
+
require 'elastic_apm/util/dig'
|
5
6
|
|
6
7
|
# Core
|
7
8
|
require 'elastic_apm/agent'
|
@@ -73,9 +74,17 @@ module ElasticAPM
|
|
73
74
|
# @param context [Span::Context] Context information about the span
|
74
75
|
# @yield [Span] Optional block encapsulating span
|
75
76
|
# @return [Span] Unless block given
|
76
|
-
def self.span(name, type = nil, context: nil,
|
77
|
+
def self.span(name, type = nil, context: nil, include_stacktrace: true,
|
78
|
+
&block)
|
77
79
|
return call_through(&block) unless agent
|
78
|
-
|
80
|
+
|
81
|
+
agent.span(
|
82
|
+
name,
|
83
|
+
type,
|
84
|
+
context: context,
|
85
|
+
backtrace: include_stacktrace ? caller : nil,
|
86
|
+
&block
|
87
|
+
)
|
79
88
|
end
|
80
89
|
|
81
90
|
# Build a [Context] from a Rack `env`. The context may include information
|
@@ -125,6 +134,28 @@ module ElasticAPM
|
|
125
134
|
agent && agent.set_custom_context(custom)
|
126
135
|
end
|
127
136
|
|
137
|
+
# Provide a user to the current transaction
|
138
|
+
#
|
139
|
+
# @param user [Object] An object representing a user
|
140
|
+
# @return [Object] Given user
|
141
|
+
def self.set_user(user)
|
142
|
+
agent && agent.set_user(user)
|
143
|
+
end
|
144
|
+
|
145
|
+
# Provide a filter to transform payloads before sending them off
|
146
|
+
#
|
147
|
+
# @param key [Symbol] Unique filter key
|
148
|
+
# @param callback [Object, Proc] A filter that responds to #call(payload)
|
149
|
+
# @yield [Hash] A filter. Will be used if provided. Otherwise using `callback`
|
150
|
+
# @return [Bool] true
|
151
|
+
def self.add_filter(key, callback = nil, &block)
|
152
|
+
if callback.nil? && !block_given?
|
153
|
+
raise ArgumentError, '#add_filter needs either `callback\' or a block'
|
154
|
+
end
|
155
|
+
|
156
|
+
agent && agent.add_filter(key, block || callback)
|
157
|
+
end
|
158
|
+
|
128
159
|
class << self
|
129
160
|
private
|
130
161
|
|
data/lib/elastic_apm/agent.rb
CHANGED
@@ -28,7 +28,8 @@ module ElasticAPM
|
|
28
28
|
|
29
29
|
LOCK.synchronize do
|
30
30
|
return @instance if @instance
|
31
|
-
|
31
|
+
|
32
|
+
@instance = new(config.freeze).start
|
32
33
|
end
|
33
34
|
end
|
34
35
|
|
@@ -45,11 +46,13 @@ module ElasticAPM
|
|
45
46
|
!!@instance
|
46
47
|
end
|
47
48
|
|
49
|
+
# rubocop:disable Metrics/MethodLength
|
48
50
|
def initialize(config)
|
49
51
|
config = Config.new(config) if config.is_a?(Hash)
|
50
52
|
|
51
53
|
@config = config
|
52
54
|
|
55
|
+
@http = Http.new(config)
|
53
56
|
@queue = Queue.new
|
54
57
|
|
55
58
|
@instrumenter = Instrumenter.new(config, self)
|
@@ -61,8 +64,9 @@ module ElasticAPM
|
|
61
64
|
Serializers::Errors.new(config)
|
62
65
|
)
|
63
66
|
end
|
67
|
+
# rubocop:enable Metrics/MethodLength
|
64
68
|
|
65
|
-
attr_reader :config, :queue, :instrumenter, :context_builder
|
69
|
+
attr_reader :config, :queue, :instrumenter, :context_builder, :http
|
66
70
|
|
67
71
|
def start
|
68
72
|
debug 'Starting agent reporting to %s', config.server_url
|
@@ -150,6 +154,14 @@ module ElasticAPM
|
|
150
154
|
instrumenter.set_custom_context(*args)
|
151
155
|
end
|
152
156
|
|
157
|
+
def set_user(*args)
|
158
|
+
instrumenter.set_user(*args)
|
159
|
+
end
|
160
|
+
|
161
|
+
def add_filter(key, callback)
|
162
|
+
@http.filters.add(key, callback)
|
163
|
+
end
|
164
|
+
|
153
165
|
def inspect
|
154
166
|
'<ElasticAPM::Agent>'
|
155
167
|
end
|
@@ -160,7 +172,7 @@ module ElasticAPM
|
|
160
172
|
debug 'Booting worker in thread'
|
161
173
|
|
162
174
|
@worker_thread = Thread.new do
|
163
|
-
Worker.new(@config, @queue).run_forever
|
175
|
+
Worker.new(@config, @queue, @http).run_forever
|
164
176
|
end
|
165
177
|
end
|
166
178
|
|
data/lib/elastic_apm/config.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'logger'
|
4
4
|
|
5
5
|
module ElasticAPM
|
6
|
+
# rubocop:disable Metrics/ClassLength
|
6
7
|
# @api private
|
7
8
|
class Config
|
8
9
|
DEFAULTS = {
|
@@ -16,50 +17,67 @@ module ElasticAPM
|
|
16
17
|
|
17
18
|
log_path: '-',
|
18
19
|
log_level: Logger::INFO,
|
20
|
+
logger: nil,
|
19
21
|
|
20
|
-
|
21
|
-
|
22
|
+
http_timeout: 10,
|
23
|
+
http_open_timeout: 10,
|
22
24
|
transaction_send_interval: 10,
|
23
25
|
debug_transactions: false,
|
24
26
|
debug_http: false,
|
25
27
|
|
26
|
-
enabled_injectors: %w[net_http],
|
28
|
+
enabled_injectors: %w[net_http json],
|
27
29
|
|
28
|
-
current_user_method: :current_user,
|
29
30
|
current_user_id_method: :id,
|
30
31
|
current_user_email_method: :email,
|
31
32
|
current_user_username_method: :username,
|
32
33
|
|
33
|
-
view_paths: []
|
34
|
+
view_paths: [],
|
35
|
+
root_path: Dir.pwd
|
34
36
|
}.freeze
|
35
37
|
|
36
|
-
|
38
|
+
ENV_TO_KEY = {
|
39
|
+
'ELASTIC_APM_APP_NAME' => 'app_name',
|
40
|
+
'ELASTIC_APM_SERVER_URL' => 'server_url',
|
41
|
+
'ELASTIC_APM_SECRET_TOKEN' => 'secret_token'
|
42
|
+
}.freeze
|
37
43
|
|
44
|
+
# rubocop:disable Metrics/MethodLength
|
38
45
|
def initialize(options = nil)
|
39
46
|
options = {} if options.nil?
|
40
47
|
|
41
|
-
|
48
|
+
# Start with the defaults
|
49
|
+
DEFAULTS.each do |key, value|
|
42
50
|
send("#{key}=", value)
|
43
51
|
end
|
44
52
|
|
45
|
-
|
53
|
+
# Set options from ENV
|
54
|
+
ENV_TO_KEY.each do |env_key, key|
|
55
|
+
next unless (value = ENV[env_key])
|
56
|
+
send("#{key}=", value)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Set options from arguments
|
60
|
+
options.each do |key, value|
|
61
|
+
send("#{key}=", value)
|
62
|
+
end
|
46
63
|
|
47
|
-
yield self
|
64
|
+
yield self if block_given?
|
48
65
|
end
|
66
|
+
# rubocop:enable Metrics/MethodLength
|
49
67
|
|
50
68
|
attr_accessor :server_url
|
51
69
|
attr_accessor :secret_token
|
52
70
|
|
53
71
|
attr_accessor :app_name
|
54
|
-
|
72
|
+
attr_reader :environment
|
55
73
|
attr_accessor :framework_name
|
56
74
|
attr_accessor :framework_version
|
57
75
|
|
58
76
|
attr_accessor :log_path
|
59
77
|
attr_accessor :log_level
|
60
78
|
|
61
|
-
attr_accessor :
|
62
|
-
attr_accessor :
|
79
|
+
attr_accessor :http_timeout
|
80
|
+
attr_accessor :http_open_timeout
|
63
81
|
attr_accessor :transaction_send_interval
|
64
82
|
attr_accessor :debug_transactions
|
65
83
|
attr_accessor :debug_http
|
@@ -67,13 +85,14 @@ module ElasticAPM
|
|
67
85
|
attr_accessor :enabled_injectors
|
68
86
|
|
69
87
|
attr_accessor :view_paths
|
88
|
+
attr_accessor :root_path
|
70
89
|
|
71
90
|
attr_accessor :current_user_method
|
72
91
|
attr_accessor :current_user_id_method
|
73
92
|
attr_accessor :current_user_email_method
|
74
93
|
attr_accessor :current_user_username_method
|
75
94
|
|
76
|
-
|
95
|
+
attr_reader :logger
|
77
96
|
|
78
97
|
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
79
98
|
def app=(app)
|
@@ -82,11 +101,14 @@ module ElasticAPM
|
|
82
101
|
self.app_name = format_name(app_name || app.to_s)
|
83
102
|
self.framework_name = 'Sinatra'
|
84
103
|
self.framework_version = Sinatra::VERSION
|
104
|
+
self.enabled_injectors += %w[sinatra]
|
105
|
+
self.root_path = Dir.pwd
|
85
106
|
when :rails
|
86
107
|
self.app_name = format_name(app_name || app.class.parent_name)
|
87
108
|
self.framework_name = 'Ruby on Rails'
|
88
109
|
self.framework_version = Rails::VERSION::STRING
|
89
110
|
self.logger = Rails.logger
|
111
|
+
self.root_path = Rails.root.to_s
|
90
112
|
self.view_paths = app.config.paths['app/views'].existent
|
91
113
|
else
|
92
114
|
# TODO: define custom?
|
@@ -107,19 +129,16 @@ module ElasticAPM
|
|
107
129
|
nil
|
108
130
|
end
|
109
131
|
|
110
|
-
def
|
111
|
-
|
132
|
+
def use_ssl?
|
133
|
+
server_url.start_with?('https')
|
112
134
|
end
|
113
135
|
|
114
|
-
def
|
115
|
-
@
|
116
|
-
LOCK.synchronize do
|
117
|
-
build_logger(log_path, log_level)
|
118
|
-
end
|
136
|
+
def environment=(env)
|
137
|
+
@environment = env || ENV['RAILS_ENV'] || ENV['RACK_ENV']
|
119
138
|
end
|
120
139
|
|
121
|
-
def
|
122
|
-
|
140
|
+
def logger=(logger)
|
141
|
+
@logger = logger || build_logger(log_path, log_level)
|
123
142
|
end
|
124
143
|
|
125
144
|
private
|
@@ -134,4 +153,5 @@ module ElasticAPM
|
|
134
153
|
str.gsub('::', '_')
|
135
154
|
end
|
136
155
|
end
|
156
|
+
# rubocop:enable Metrics/ClassLength
|
137
157
|
end
|
@@ -3,20 +3,11 @@
|
|
3
3
|
module ElasticAPM
|
4
4
|
# @api private
|
5
5
|
class ContextBuilder
|
6
|
-
|
7
|
-
|
8
|
-
def initialize(config)
|
9
|
-
@config = config
|
10
|
-
end
|
11
|
-
|
12
|
-
attr_reader :config
|
6
|
+
def initialize(_config); end
|
13
7
|
|
14
8
|
def build(rack_env)
|
15
9
|
context = Context.new
|
16
|
-
|
17
10
|
apply_to_request(context, rack_env)
|
18
|
-
apply_to_user(context, rack_env)
|
19
|
-
|
20
11
|
context
|
21
12
|
end
|
22
13
|
|
@@ -40,18 +31,6 @@ module ElasticAPM
|
|
40
31
|
end
|
41
32
|
# rubocop:enable Metrics/AbcSize
|
42
33
|
|
43
|
-
def apply_to_user(context, rack_env)
|
44
|
-
return unless (controller = rack_env[CONTROLLER_KEY])
|
45
|
-
|
46
|
-
method = config.current_user_method.to_sym
|
47
|
-
return unless controller.respond_to?(method)
|
48
|
-
|
49
|
-
return unless (record = controller.send method)
|
50
|
-
|
51
|
-
context.user = Context::User.new(config, record)
|
52
|
-
context
|
53
|
-
end
|
54
|
-
|
55
34
|
def get_body(req)
|
56
35
|
return req.POST if req.form_data?
|
57
36
|
|
@@ -7,8 +7,6 @@ module ElasticAPM
|
|
7
7
|
@config = config
|
8
8
|
end
|
9
9
|
|
10
|
-
attr_reader :config
|
11
|
-
|
12
10
|
def build_exception(exception, handled: true)
|
13
11
|
error = Error.new
|
14
12
|
error.exception = Error::Exception.new(exception, handled: handled)
|
@@ -36,7 +34,7 @@ module ElasticAPM
|
|
36
34
|
private
|
37
35
|
|
38
36
|
def add_stacktrace(error, kind, backtrace)
|
39
|
-
return unless (stacktrace = Stacktrace.build(config, backtrace))
|
37
|
+
return unless (stacktrace = Stacktrace.build(@config, backtrace))
|
40
38
|
|
41
39
|
case kind
|
42
40
|
when :exception
|
@@ -45,7 +43,7 @@ module ElasticAPM
|
|
45
43
|
error.log.stacktrace = stacktrace
|
46
44
|
end
|
47
45
|
|
48
|
-
error.culprit = stacktrace.frames.
|
46
|
+
error.culprit = stacktrace.frames.first.function
|
49
47
|
end
|
50
48
|
|
51
49
|
def add_transaction_id(error)
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'elastic_apm/filters/request_body_filter'
|
4
|
+
require 'elastic_apm/filters/secrets_filter'
|
5
|
+
|
6
|
+
module ElasticAPM
|
7
|
+
# @api private
|
8
|
+
module Filters
|
9
|
+
def self.new(config)
|
10
|
+
Container.new(config)
|
11
|
+
end
|
12
|
+
|
13
|
+
# @api private
|
14
|
+
class Container
|
15
|
+
def initialize(config)
|
16
|
+
@config = config
|
17
|
+
@filters = {
|
18
|
+
request_body: RequestBodyFilter.new(config),
|
19
|
+
secrets: SecretsFilter.new(config)
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
attr_reader :config
|
24
|
+
|
25
|
+
def add(key, filter)
|
26
|
+
@filters[key] = filter
|
27
|
+
end
|
28
|
+
|
29
|
+
def remove(key)
|
30
|
+
@filters.delete(key)
|
31
|
+
end
|
32
|
+
|
33
|
+
def apply(payload)
|
34
|
+
@filters.reduce(payload) do |result, (_key, filter)|
|
35
|
+
filter.call(result)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def length
|
40
|
+
@filters.length
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ElasticAPM
|
4
|
+
module Filters
|
5
|
+
# @api private
|
6
|
+
class RequestBodyFilter
|
7
|
+
FILTERED = '[FILTERED]'.freeze
|
8
|
+
|
9
|
+
def initialize(config)
|
10
|
+
@config = config
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(payload)
|
14
|
+
strip_body_from payload[:transactions]
|
15
|
+
strip_body_from payload[:errors]
|
16
|
+
|
17
|
+
payload
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def strip_body_from(arr)
|
23
|
+
return unless arr
|
24
|
+
|
25
|
+
arr.each do |entity|
|
26
|
+
next unless (request = entity.dig(:context, :request))
|
27
|
+
|
28
|
+
request[:body] = FILTERED
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ElasticAPM
|
4
|
+
module Filters
|
5
|
+
# @api private
|
6
|
+
class SecretsFilter
|
7
|
+
FILTERED = '[FILTERED]'.freeze
|
8
|
+
|
9
|
+
KEY_FILTERS = [
|
10
|
+
/passw(or)?d/i,
|
11
|
+
/^pw$/,
|
12
|
+
/secret/i,
|
13
|
+
/token/i,
|
14
|
+
/api[-._]?key/i,
|
15
|
+
/session[-._]?id/i
|
16
|
+
].freeze
|
17
|
+
|
18
|
+
VALUE_FILTERS = [
|
19
|
+
/^\d{4}[- ]?\d{4}[- ]?\d{4}[- ]?\d{4}$/ # (probably) credit card number
|
20
|
+
].freeze
|
21
|
+
|
22
|
+
def initialize(config)
|
23
|
+
@config = config
|
24
|
+
end
|
25
|
+
|
26
|
+
def call(payload)
|
27
|
+
strip_from payload[:transactions], :context, :request, :headers
|
28
|
+
strip_from payload[:transactions], :context, :response, :headers
|
29
|
+
strip_from payload[:errors], :context, :request, :headers
|
30
|
+
strip_from payload[:errors], :context, :response, :headers
|
31
|
+
|
32
|
+
payload
|
33
|
+
end
|
34
|
+
|
35
|
+
def strip_from(events, *path)
|
36
|
+
return unless events
|
37
|
+
|
38
|
+
events.each do |event|
|
39
|
+
next unless (headers = event.dig(*path))
|
40
|
+
|
41
|
+
headers.each do |k, v|
|
42
|
+
if filter_key?(k) || filter_value?(v)
|
43
|
+
headers[k] = FILTERED
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def filter_key?(key)
|
50
|
+
KEY_FILTERS.any? { |regex| key =~ regex }
|
51
|
+
end
|
52
|
+
|
53
|
+
def filter_value?(value)
|
54
|
+
VALUE_FILTERS.any? { |regex| value =~ regex }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/elastic_apm/http.rb
CHANGED
@@ -5,6 +5,7 @@ require 'net/http'
|
|
5
5
|
require 'elastic_apm/service_info'
|
6
6
|
require 'elastic_apm/system_info'
|
7
7
|
require 'elastic_apm/process_info'
|
8
|
+
require 'elastic_apm/filters'
|
8
9
|
|
9
10
|
module ElasticAPM
|
10
11
|
# @api private
|
@@ -23,12 +24,14 @@ module ElasticAPM
|
|
23
24
|
process: ProcessInfo.build(config),
|
24
25
|
system: SystemInfo.build(config)
|
25
26
|
}
|
27
|
+
@filters = Filters.new(config)
|
26
28
|
end
|
27
29
|
|
28
|
-
attr_reader :
|
30
|
+
attr_reader :filters
|
29
31
|
|
30
32
|
def post(path, payload = {})
|
31
33
|
payload.merge! @base_payload
|
34
|
+
filters.apply(payload)
|
32
35
|
request = prepare_request path, payload.to_json
|
33
36
|
response = @adapter.perform request
|
34
37
|
|
@@ -50,7 +53,7 @@ module ElasticAPM
|
|
50
53
|
req['User-Agent'] = USER_AGENT
|
51
54
|
req['Content-Length'] = data.bytesize.to_s
|
52
55
|
|
53
|
-
if (token = config.secret_token)
|
56
|
+
if (token = @config.secret_token)
|
54
57
|
req['Authorization'] = "Bearer #{token}"
|
55
58
|
end
|
56
59
|
|
@@ -88,8 +91,8 @@ module ElasticAPM
|
|
88
91
|
|
89
92
|
http = Net::HTTP.new server_uri.host, server_uri.port
|
90
93
|
http.use_ssl = @config.use_ssl?
|
91
|
-
http.read_timeout = @config.
|
92
|
-
http.open_timeout = @config.
|
94
|
+
http.read_timeout = @config.http_timeout
|
95
|
+
http.open_timeout = @config.http_open_timeout
|
93
96
|
|
94
97
|
if @config.debug_http
|
95
98
|
http.set_debug_output(@config.logger)
|
@@ -32,7 +32,7 @@ module ElasticAPM
|
|
32
32
|
|
33
33
|
@transaction_info = TransactionInfo.new
|
34
34
|
|
35
|
-
@subscriber = subscriber_class.new(
|
35
|
+
@subscriber = subscriber_class.new(config)
|
36
36
|
|
37
37
|
@pending_transactions = []
|
38
38
|
@last_sent_transactions = Time.now.utc
|
@@ -92,6 +92,10 @@ module ElasticAPM
|
|
92
92
|
transaction.context.custom.merge!(context)
|
93
93
|
end
|
94
94
|
|
95
|
+
def set_user(user)
|
96
|
+
transaction.context.user = Context::User.new(config, user)
|
97
|
+
end
|
98
|
+
|
95
99
|
def submit_transaction(transaction)
|
96
100
|
@pending_transactions << transaction
|
97
101
|
|
data/lib/elastic_apm/log.rb
CHANGED
@@ -26,12 +26,14 @@ module ElasticAPM
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def log(lvl, msg, *args)
|
29
|
+
return unless logger
|
30
|
+
|
29
31
|
formatted_msg = prepend_prefix(format(msg.to_s, *args))
|
30
32
|
|
31
|
-
return
|
33
|
+
return logger.send(lvl, formatted_msg) unless block_given?
|
32
34
|
|
33
35
|
# TODO: dont evaluate block if level is higher
|
34
|
-
|
36
|
+
logger.send(lvl, "#{formatted_msg}\n#{yield}")
|
35
37
|
end
|
36
38
|
|
37
39
|
private
|
@@ -40,8 +42,9 @@ module ElasticAPM
|
|
40
42
|
"#{PREFIX}#{str}"
|
41
43
|
end
|
42
44
|
|
43
|
-
def
|
44
|
-
|
45
|
+
def logger
|
46
|
+
return false unless (config = instance_variable_get(:@config))
|
47
|
+
config.logger
|
45
48
|
end
|
46
49
|
end
|
47
50
|
end
|
@@ -10,7 +10,7 @@ module ElasticAPM
|
|
10
10
|
# rubocop:disable Metrics/MethodLength
|
11
11
|
def call(env)
|
12
12
|
begin
|
13
|
-
transaction = ElasticAPM.transaction 'Rack',
|
13
|
+
transaction = ElasticAPM.transaction 'Rack', 'app',
|
14
14
|
context: ElasticAPM.build_context(env)
|
15
15
|
|
16
16
|
resp = @app.call env
|
@@ -29,14 +29,5 @@ module ElasticAPM
|
|
29
29
|
resp
|
30
30
|
end
|
31
31
|
# rubocop:enable Metrics/MethodLength
|
32
|
-
|
33
|
-
private
|
34
|
-
|
35
|
-
def type_for(env)
|
36
|
-
format(
|
37
|
-
'request.%s'.freeze,
|
38
|
-
env.fetch('REQUEST_METHOD'.freeze, 'unknown'.freeze)
|
39
|
-
)
|
40
|
-
end
|
41
32
|
end
|
42
33
|
end
|
@@ -13,17 +13,7 @@ module ElasticAPM
|
|
13
13
|
result: transaction.result.to_s,
|
14
14
|
duration: ms(transaction.duration),
|
15
15
|
timestamp: micros_to_time(transaction.timestamp).utc.iso8601,
|
16
|
-
spans: transaction.spans.map
|
17
|
-
{
|
18
|
-
id: span.id,
|
19
|
-
parent: span.parent && span.parent.id,
|
20
|
-
name: span.name,
|
21
|
-
type: span.type,
|
22
|
-
start: ms(span.relative_start),
|
23
|
-
duration: ms(span.duration),
|
24
|
-
context: span.context && { db: span.context.to_h }
|
25
|
-
}
|
26
|
-
end,
|
16
|
+
spans: transaction.spans.map(&method(:build_span)),
|
27
17
|
sampled: transaction.sampled,
|
28
18
|
context: transaction.context.to_h
|
29
19
|
}
|
@@ -33,6 +23,23 @@ module ElasticAPM
|
|
33
23
|
def build_all(transactions)
|
34
24
|
{ transactions: Array(transactions).map(&method(:build)) }
|
35
25
|
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
# rubocop:disable Metrics/AbcSize
|
30
|
+
def build_span(span)
|
31
|
+
{
|
32
|
+
id: span.id,
|
33
|
+
parent: span.parent && span.parent.id,
|
34
|
+
name: span.name,
|
35
|
+
type: span.type,
|
36
|
+
start: ms(span.relative_start),
|
37
|
+
duration: ms(span.duration),
|
38
|
+
context: span.context && { db: span.context.to_h },
|
39
|
+
stacktrace: span.stacktrace.to_a
|
40
|
+
}
|
41
|
+
end
|
42
|
+
# rubocop:enable Metrics/AbcSize
|
36
43
|
end
|
37
44
|
end
|
38
45
|
end
|
@@ -7,13 +7,11 @@ module ElasticAPM
|
|
7
7
|
@config = config
|
8
8
|
end
|
9
9
|
|
10
|
-
attr_reader :config
|
11
|
-
|
12
10
|
# rubocop:disable Metrics/MethodLength
|
13
11
|
def build
|
14
12
|
base = {
|
15
|
-
name: config.app_name,
|
16
|
-
environment: config.environment,
|
13
|
+
name: @config.app_name,
|
14
|
+
environment: @config.environment,
|
17
15
|
agent: {
|
18
16
|
name: 'ruby',
|
19
17
|
version: VERSION
|
@@ -27,10 +25,10 @@ module ElasticAPM
|
|
27
25
|
version: git_sha
|
28
26
|
}
|
29
27
|
|
30
|
-
if config.framework_name
|
28
|
+
if @config.framework_name
|
31
29
|
base[:framework] = {
|
32
|
-
name: config.framework_name,
|
33
|
-
version: config.framework_version
|
30
|
+
name: @config.framework_name,
|
31
|
+
version: @config.framework_version
|
34
32
|
}
|
35
33
|
end
|
36
34
|
|
data/lib/elastic_apm/span.rb
CHANGED
@@ -22,10 +22,11 @@ module ElasticAPM
|
|
22
22
|
@type = type
|
23
23
|
@parent = parent
|
24
24
|
@context = context
|
25
|
+
@stacktrace = nil
|
25
26
|
end
|
26
27
|
# rubocop:enable Metrics/ParameterLists
|
27
28
|
|
28
|
-
attr_accessor :name, :context, :type
|
29
|
+
attr_accessor :name, :context, :type, :stacktrace
|
29
30
|
attr_reader :id, :duration, :parent, :relative_start
|
30
31
|
|
31
32
|
def start
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'elastic_apm/util/lru_cache'
|
4
|
+
|
3
5
|
module ElasticAPM
|
4
6
|
# @api private
|
5
7
|
class SqlSummarizer
|
@@ -10,15 +12,17 @@ module ElasticAPM
|
|
10
12
|
/^DELETE FROM ([^ ]+)/i => 'DELETE FROM '
|
11
13
|
}.freeze
|
12
14
|
|
15
|
+
FORMAT = '%s%s'.freeze
|
16
|
+
|
13
17
|
def self.cache
|
14
|
-
@cache ||=
|
18
|
+
@cache ||= Util::LruCache.new
|
15
19
|
end
|
16
20
|
|
17
21
|
def summarize(sql)
|
18
22
|
self.class.cache[sql] ||=
|
19
23
|
REGEXES.find do |regex, sig|
|
20
24
|
if (match = sql.match(regex))
|
21
|
-
break format(
|
25
|
+
break format(FORMAT, sig, match[1].gsub(/["']/, ''))
|
22
26
|
end
|
23
27
|
end
|
24
28
|
end
|
@@ -1,27 +1,30 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'elastic_apm/stacktrace/frame'
|
4
|
+
require 'elastic_apm/stacktrace/line_cache'
|
4
5
|
|
5
6
|
module ElasticAPM
|
6
7
|
# @api private
|
7
8
|
class Stacktrace
|
9
|
+
GEMS_REGEX = %r{/gems/}
|
10
|
+
|
8
11
|
def initialize(backtrace)
|
9
12
|
@backtrace = backtrace
|
10
13
|
end
|
11
14
|
|
12
15
|
attr_reader :frames
|
13
16
|
|
14
|
-
def self.build(
|
17
|
+
def self.build(config, backtrace)
|
15
18
|
return nil unless backtrace
|
16
19
|
|
17
20
|
stack = new(backtrace)
|
18
|
-
stack.build_frames(
|
21
|
+
stack.build_frames(config)
|
19
22
|
stack
|
20
23
|
end
|
21
24
|
|
22
|
-
def build_frames(
|
23
|
-
@frames = @backtrace.
|
24
|
-
build_frame(
|
25
|
+
def build_frames(config)
|
26
|
+
@frames = @backtrace.map do |line|
|
27
|
+
build_frame(config, line)
|
25
28
|
end
|
26
29
|
end
|
27
30
|
|
@@ -53,7 +56,7 @@ module ElasticAPM
|
|
53
56
|
[file, number, method, module_name]
|
54
57
|
end
|
55
58
|
|
56
|
-
def build_frame(
|
59
|
+
def build_frame(config, line)
|
57
60
|
abs_path, lineno, function, _module_name = parse_line(line)
|
58
61
|
|
59
62
|
frame = Frame.new
|
@@ -62,6 +65,8 @@ module ElasticAPM
|
|
62
65
|
frame.function = function
|
63
66
|
frame.lineno = lineno.to_i
|
64
67
|
frame.build_context 3
|
68
|
+
frame.library_frame =
|
69
|
+
!(abs_path && abs_path.start_with?(config.root_path))
|
65
70
|
|
66
71
|
frame
|
67
72
|
end
|
@@ -14,30 +14,32 @@ module ElasticAPM
|
|
14
14
|
:pre_context,
|
15
15
|
:context_line,
|
16
16
|
:post_context,
|
17
|
-
:
|
17
|
+
:library_frame,
|
18
18
|
:lineno,
|
19
19
|
:module,
|
20
20
|
:colno
|
21
21
|
)
|
22
22
|
|
23
|
-
# rubocop:disable Metrics/AbcSize
|
24
23
|
def build_context(context_line_count)
|
25
24
|
return unless abs_path
|
26
25
|
|
27
|
-
|
26
|
+
from = (lineno - context_line_count - 1)
|
27
|
+
to = (lineno + context_line_count)
|
28
|
+
file_lines = read_lines(abs_path, from..to)
|
28
29
|
|
29
|
-
self.context_line = file_lines[
|
30
|
-
self.pre_context
|
31
|
-
|
32
|
-
self.post_context =
|
33
|
-
file_lines[(lineno + 1)..(lineno + context_line_count)]
|
30
|
+
self.context_line = file_lines[context_line_count]
|
31
|
+
self.pre_context = file_lines.first(context_line_count)
|
32
|
+
self.post_context = file_lines.last(context_line_count)
|
34
33
|
end
|
35
|
-
# rubocop:enable Metrics/AbcSize
|
36
34
|
|
37
35
|
private
|
38
36
|
|
39
|
-
def read_lines(path)
|
40
|
-
|
37
|
+
def read_lines(path, range)
|
38
|
+
if (cached = LineCache.get(path, range))
|
39
|
+
return cached
|
40
|
+
end
|
41
|
+
|
42
|
+
LineCache.set(path, range, File.readlines(path)[range])
|
41
43
|
rescue Errno::ENOENT
|
42
44
|
[]
|
43
45
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'elastic_apm/util/lru_cache'
|
4
|
+
|
5
|
+
module ElasticAPM
|
6
|
+
class Stacktrace
|
7
|
+
# A basic LRU Cache
|
8
|
+
# @api private
|
9
|
+
class LineCache
|
10
|
+
class << self
|
11
|
+
def cache
|
12
|
+
@cache ||= Util::LruCache.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def get(*key)
|
16
|
+
cache[key]
|
17
|
+
end
|
18
|
+
|
19
|
+
def set(*key, value)
|
20
|
+
cache[key] = value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -8,14 +8,12 @@ module ElasticAPM
|
|
8
8
|
class Subscriber
|
9
9
|
include Log
|
10
10
|
|
11
|
-
def initialize(agent)
|
11
|
+
def initialize(config, agent: ElasticAPM)
|
12
|
+
@config = config
|
12
13
|
@agent = agent
|
13
|
-
@config = agent.config
|
14
14
|
@normalizers = Normalizers.build(config)
|
15
15
|
end
|
16
16
|
|
17
|
-
attr_reader :config
|
18
|
-
|
19
17
|
def register!
|
20
18
|
unregister! if @subscription
|
21
19
|
|
@@ -43,7 +41,7 @@ module ElasticAPM
|
|
43
41
|
nil
|
44
42
|
else
|
45
43
|
name, type, context = normalized
|
46
|
-
|
44
|
+
@agent.span(name, type, context: context)
|
47
45
|
end
|
48
46
|
|
49
47
|
transaction.notifications << Notification.new(id, span)
|
@@ -28,7 +28,7 @@ module ElasticAPM
|
|
28
28
|
|
29
29
|
attr_accessor :id, :name, :result, :type
|
30
30
|
attr_reader :context, :duration, :root_span, :timestamp, :spans,
|
31
|
-
:notifications, :sampled
|
31
|
+
:notifications, :sampled, :instrumenter
|
32
32
|
|
33
33
|
def release
|
34
34
|
@instrumenter.current_transaction = nil
|
@@ -61,9 +61,14 @@ module ElasticAPM
|
|
61
61
|
spans.select(&:running?)
|
62
62
|
end
|
63
63
|
|
64
|
-
|
64
|
+
# rubocop:disable Metrics/MethodLength
|
65
|
+
def span(name, type = nil, backtrace: nil, context: nil)
|
65
66
|
span = next_span(name, type, context)
|
66
67
|
spans << span
|
68
|
+
|
69
|
+
span.stacktrace =
|
70
|
+
backtrace && Stacktrace.build(@instrumenter.config, backtrace)
|
71
|
+
|
67
72
|
span.start
|
68
73
|
|
69
74
|
return span unless block_given?
|
@@ -76,6 +81,7 @@ module ElasticAPM
|
|
76
81
|
|
77
82
|
result
|
78
83
|
end
|
84
|
+
# rubocop:enable Metrics/MethodLength
|
79
85
|
|
80
86
|
def current_span
|
81
87
|
spans.reverse.lazy.find(&:running?)
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# Monkeypatch/backport/polyfill Enumerable#dig to Ruby < 2.3
|
2
|
+
#
|
3
|
+
# Implementation from
|
4
|
+
# https://github.com/Invoca/ruby_dig/blob/master/lib/ruby_dig.rb
|
5
|
+
|
6
|
+
# @api private
|
7
|
+
module RubyDig
|
8
|
+
def dig(key, *rest)
|
9
|
+
value = self[key]
|
10
|
+
|
11
|
+
if value.nil? || rest.empty?
|
12
|
+
value
|
13
|
+
elsif value.respond_to?(:dig)
|
14
|
+
value.dig(*rest)
|
15
|
+
else
|
16
|
+
raise TypeError, "#{value.class} does not respond to `#dig'"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
if RUBY_VERSION < '2.3'
|
22
|
+
# @api private
|
23
|
+
class Array
|
24
|
+
include RubyDig
|
25
|
+
end
|
26
|
+
|
27
|
+
# @api private
|
28
|
+
class Hash
|
29
|
+
include RubyDig
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ElasticAPM
|
4
|
+
module Util
|
5
|
+
# @api private
|
6
|
+
class LruCache
|
7
|
+
def initialize(max_size = 512)
|
8
|
+
@max_size = max_size
|
9
|
+
@data = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def [](key)
|
13
|
+
found = true
|
14
|
+
value = @data.delete(key) { found = false }
|
15
|
+
|
16
|
+
found ? @data[key] = value : nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def []=(key, val)
|
20
|
+
@data.delete(key)
|
21
|
+
@data[key] = val
|
22
|
+
|
23
|
+
return unless @data.length > @max_size
|
24
|
+
|
25
|
+
@data.delete(@data.first[0])
|
26
|
+
end
|
27
|
+
|
28
|
+
def length
|
29
|
+
@data.length
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_a
|
33
|
+
@data.to_a
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/elastic_apm/version.rb
CHANGED
data/lib/elastic_apm/worker.rb
CHANGED
@@ -16,14 +16,12 @@ module ElasticAPM
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
def initialize(config, queue,
|
19
|
+
def initialize(config, queue, adapter)
|
20
20
|
@config = config
|
21
|
-
@adapter =
|
21
|
+
@adapter = adapter
|
22
22
|
@queue = queue
|
23
23
|
end
|
24
24
|
|
25
|
-
attr_reader :config
|
26
|
-
|
27
25
|
def run_forever
|
28
26
|
loop do
|
29
27
|
while (item = @queue.pop)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: elastic-apm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mikkel Malmberg
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-01-
|
11
|
+
date: 2018-01-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -66,6 +66,9 @@ files:
|
|
66
66
|
- lib/elastic_apm/error/exception.rb
|
67
67
|
- lib/elastic_apm/error/log.rb
|
68
68
|
- lib/elastic_apm/error_builder.rb
|
69
|
+
- lib/elastic_apm/filters.rb
|
70
|
+
- lib/elastic_apm/filters/request_body_filter.rb
|
71
|
+
- lib/elastic_apm/filters/secrets_filter.rb
|
69
72
|
- lib/elastic_apm/http.rb
|
70
73
|
- lib/elastic_apm/injectors.rb
|
71
74
|
- lib/elastic_apm/injectors/action_dispatch.rb
|
@@ -96,11 +99,14 @@ files:
|
|
96
99
|
- lib/elastic_apm/sql_summarizer.rb
|
97
100
|
- lib/elastic_apm/stacktrace.rb
|
98
101
|
- lib/elastic_apm/stacktrace/frame.rb
|
102
|
+
- lib/elastic_apm/stacktrace/line_cache.rb
|
99
103
|
- lib/elastic_apm/subscriber.rb
|
100
104
|
- lib/elastic_apm/system_info.rb
|
101
105
|
- lib/elastic_apm/transaction.rb
|
102
106
|
- lib/elastic_apm/util.rb
|
107
|
+
- lib/elastic_apm/util/dig.rb
|
103
108
|
- lib/elastic_apm/util/inspector.rb
|
109
|
+
- lib/elastic_apm/util/lru_cache.rb
|
104
110
|
- lib/elastic_apm/version.rb
|
105
111
|
- lib/elastic_apm/worker.rb
|
106
112
|
- vendor/.gitkeep
|