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
@@ -1,54 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ElasticAPM
|
4
|
-
# @api private
|
5
|
-
class ServiceInfo
|
6
|
-
def initialize(config)
|
7
|
-
@config = config
|
8
|
-
end
|
9
|
-
|
10
|
-
# rubocop:disable Metrics/MethodLength
|
11
|
-
def build
|
12
|
-
base = {
|
13
|
-
name: @config.service_name,
|
14
|
-
environment: @config.environment,
|
15
|
-
agent: {
|
16
|
-
name: 'ruby',
|
17
|
-
version: VERSION
|
18
|
-
},
|
19
|
-
framework: nil,
|
20
|
-
language: {
|
21
|
-
name: 'ruby',
|
22
|
-
version: RUBY_VERSION
|
23
|
-
},
|
24
|
-
runtime: runtime,
|
25
|
-
version: @config.service_version || Util.git_sha
|
26
|
-
}
|
27
|
-
|
28
|
-
if @config.framework_name
|
29
|
-
base[:framework] = {
|
30
|
-
name: @config.framework_name,
|
31
|
-
version: @config.framework_version
|
32
|
-
}
|
33
|
-
end
|
34
|
-
|
35
|
-
base
|
36
|
-
end
|
37
|
-
# rubocop:enable Metrics/MethodLength
|
38
|
-
|
39
|
-
def self.build(config)
|
40
|
-
new(config).build
|
41
|
-
end
|
42
|
-
|
43
|
-
private
|
44
|
-
|
45
|
-
def runtime
|
46
|
-
case RUBY_ENGINE
|
47
|
-
when 'ruby'
|
48
|
-
{ name: RUBY_ENGINE, version: RUBY_VERSION || RUBY_ENGINE_VERSION }
|
49
|
-
when 'jruby'
|
50
|
-
{ name: RUBY_ENGINE, version: JRUBY_VERSION || RUBY_ENGINE_VERSION }
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ElasticAPM
|
4
|
-
# @api private
|
5
|
-
class SystemInfo
|
6
|
-
def initialize(config)
|
7
|
-
@config = config
|
8
|
-
end
|
9
|
-
|
10
|
-
def build
|
11
|
-
{
|
12
|
-
hostname: @config.hostname || `hostname`.chomp,
|
13
|
-
architecture: platform.cpu,
|
14
|
-
platform: platform.os
|
15
|
-
}
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.build(config)
|
19
|
-
new(config).build
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
def platform
|
25
|
-
@platform ||= Gem::Platform.local
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
data/lib/elastic_apm/util/dig.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
# Backport 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
|
@@ -1,61 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ElasticAPM
|
4
|
-
module Util
|
5
|
-
# @api private
|
6
|
-
class Inspector
|
7
|
-
def initialize(width = 80)
|
8
|
-
@width = width
|
9
|
-
end
|
10
|
-
|
11
|
-
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
12
|
-
def transaction(transaction)
|
13
|
-
unless transaction.done?
|
14
|
-
raise ArgumentError, 'Transaction still running'
|
15
|
-
end
|
16
|
-
|
17
|
-
width_factor = @width.to_f / ms(transaction.duration)
|
18
|
-
|
19
|
-
lines = ['=' * @width]
|
20
|
-
lines << "[T] #{transaction.name} " \
|
21
|
-
"- #{transaction.type} (#{ms transaction.duration} ms)"
|
22
|
-
lines << "+#{'-' * (@width - 2)}+"
|
23
|
-
|
24
|
-
transaction.spans.each do |span|
|
25
|
-
indent = (ms(span.relative_start) * width_factor).to_i
|
26
|
-
|
27
|
-
if span.duration
|
28
|
-
span_width = ms(span.duration) * width_factor
|
29
|
-
duration_desc = ms(span.duration)
|
30
|
-
else
|
31
|
-
span_width = @width - indent
|
32
|
-
duration_desc = 'RUNNING'
|
33
|
-
end
|
34
|
-
|
35
|
-
description = "[#{span.id}] " \
|
36
|
-
"#{span.name} - #{span.type} (#{duration_desc} ms)"
|
37
|
-
description_indent = [
|
38
|
-
0,
|
39
|
-
[indent, @width - description.length].min
|
40
|
-
].max
|
41
|
-
|
42
|
-
lines << "#{' ' * description_indent}#{description}"
|
43
|
-
lines << "#{' ' * indent}+#{'-' * [(span_width - 2), 0].max}+"
|
44
|
-
end
|
45
|
-
|
46
|
-
lines.map { |s| s[0..@width] }.join("\n")
|
47
|
-
rescue StandardError => e
|
48
|
-
puts e
|
49
|
-
puts e.backtrace.join("\n")
|
50
|
-
nil
|
51
|
-
end
|
52
|
-
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
53
|
-
|
54
|
-
private
|
55
|
-
|
56
|
-
def ms(micros)
|
57
|
-
micros.to_f / 1_000
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
data/lib/elastic_apm/worker.rb
DELETED
@@ -1,106 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'concurrent/timer_task'
|
4
|
-
|
5
|
-
module ElasticAPM
|
6
|
-
# @api private
|
7
|
-
class Worker
|
8
|
-
include Log
|
9
|
-
|
10
|
-
# @api private
|
11
|
-
class StopMsg; end
|
12
|
-
|
13
|
-
# @api private
|
14
|
-
class FlushMsg; end
|
15
|
-
|
16
|
-
# @api private
|
17
|
-
class ErrorMsg
|
18
|
-
def initialize(error)
|
19
|
-
@error = error
|
20
|
-
end
|
21
|
-
|
22
|
-
attr_reader :error
|
23
|
-
end
|
24
|
-
|
25
|
-
def initialize(config, messages, pending_transactions, adapter)
|
26
|
-
@config = config
|
27
|
-
@messages = messages
|
28
|
-
@pending_transactions = pending_transactions
|
29
|
-
@adapter = adapter
|
30
|
-
|
31
|
-
@serializers = Struct.new(:transactions, :errors).new(
|
32
|
-
Serializers::Transactions.new(config),
|
33
|
-
Serializers::Errors.new(config)
|
34
|
-
)
|
35
|
-
end
|
36
|
-
|
37
|
-
attr_reader :config, :messages, :pending_transactions
|
38
|
-
|
39
|
-
# rubocop:disable Metrics/MethodLength
|
40
|
-
def run_forever
|
41
|
-
@timer_task = build_timer_task.execute
|
42
|
-
|
43
|
-
while (msg = messages.pop)
|
44
|
-
case msg
|
45
|
-
when ErrorMsg
|
46
|
-
post_error msg
|
47
|
-
when FlushMsg
|
48
|
-
collect_and_send_transactions
|
49
|
-
when StopMsg
|
50
|
-
# empty collected transactions before exiting
|
51
|
-
collect_and_send_transactions
|
52
|
-
stop!
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
# rubocop:enable Metrics/MethodLength
|
57
|
-
|
58
|
-
private
|
59
|
-
|
60
|
-
def stop!
|
61
|
-
@timer_task && @timer_task.shutdown
|
62
|
-
Thread.exit
|
63
|
-
end
|
64
|
-
|
65
|
-
def build_timer_task
|
66
|
-
Concurrent::TimerTask.new(execution_interval: config.flush_interval) do
|
67
|
-
messages.push(FlushMsg.new)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def post_error(msg)
|
72
|
-
payload = @serializers.errors.build_all([msg.error])
|
73
|
-
@adapter.post('/v1/errors', payload)
|
74
|
-
end
|
75
|
-
|
76
|
-
def collect_and_send_transactions
|
77
|
-
return if pending_transactions.empty?
|
78
|
-
|
79
|
-
transactions = collect_batched_transactions
|
80
|
-
|
81
|
-
payload = @serializers.transactions.build_all(transactions)
|
82
|
-
|
83
|
-
begin
|
84
|
-
@adapter.post('/v1/transactions', payload)
|
85
|
-
rescue ::Exception => e
|
86
|
-
fatal 'Failed posting: %s', e.inspect
|
87
|
-
debug e.backtrace.join("\n")
|
88
|
-
nil
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def collect_batched_transactions
|
93
|
-
batch = []
|
94
|
-
|
95
|
-
begin
|
96
|
-
while (transaction = pending_transactions.pop(true)) &&
|
97
|
-
batch.length <= config.max_queue_size
|
98
|
-
batch << transaction
|
99
|
-
end
|
100
|
-
rescue ThreadError # queue empty
|
101
|
-
end
|
102
|
-
|
103
|
-
batch
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|