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.

Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rspec +1 -0
  4. data/.rubocop.yml +7 -1
  5. data/CHANGELOG.md +45 -0
  6. data/Gemfile +17 -12
  7. data/bench/app.rb +1 -2
  8. data/bench/benchmark.rb +1 -1
  9. data/bench/stackprof.rb +1 -1
  10. data/docs/api.asciidoc +115 -76
  11. data/docs/configuration.asciidoc +232 -167
  12. data/docs/context.asciidoc +7 -3
  13. data/docs/custom-instrumentation.asciidoc +17 -28
  14. data/docs/index.asciidoc +13 -7
  15. data/docs/supported-technologies.asciidoc +65 -0
  16. data/elastic-apm.gemspec +3 -2
  17. data/lib/elastic_apm.rb +272 -121
  18. data/lib/elastic_apm/agent.rb +56 -107
  19. data/lib/elastic_apm/config.rb +130 -106
  20. data/lib/elastic_apm/config/duration.rb +25 -0
  21. data/lib/elastic_apm/config/size.rb +28 -0
  22. data/lib/elastic_apm/context_builder.rb +1 -0
  23. data/lib/elastic_apm/deprecations.rb +19 -0
  24. data/lib/elastic_apm/error.rb +5 -2
  25. data/lib/elastic_apm/error/exception.rb +1 -1
  26. data/lib/elastic_apm/error_builder.rb +5 -0
  27. data/lib/elastic_apm/instrumenter.rb +121 -53
  28. data/lib/elastic_apm/internal_error.rb +1 -0
  29. data/lib/elastic_apm/{log.rb → logging.rb} +16 -11
  30. data/lib/elastic_apm/metadata.rb +20 -0
  31. data/lib/elastic_apm/metadata/process_info.rb +26 -0
  32. data/lib/elastic_apm/metadata/service_info.rb +56 -0
  33. data/lib/elastic_apm/metadata/system_info.rb +30 -0
  34. data/lib/elastic_apm/middleware.rb +31 -15
  35. data/lib/elastic_apm/normalizers/action_controller.rb +1 -1
  36. data/lib/elastic_apm/normalizers/action_mailer.rb +1 -1
  37. data/lib/elastic_apm/normalizers/action_view.rb +3 -3
  38. data/lib/elastic_apm/normalizers/active_record.rb +2 -1
  39. data/lib/elastic_apm/railtie.rb +1 -1
  40. data/lib/elastic_apm/span.rb +59 -29
  41. data/lib/elastic_apm/span/context.rb +30 -4
  42. data/lib/elastic_apm/span_helpers.rb +1 -1
  43. data/lib/elastic_apm/spies/delayed_job.rb +7 -7
  44. data/lib/elastic_apm/spies/elasticsearch.rb +4 -4
  45. data/lib/elastic_apm/spies/http.rb +38 -0
  46. data/lib/elastic_apm/spies/mongo.rb +22 -11
  47. data/lib/elastic_apm/spies/net_http.rb +7 -4
  48. data/lib/elastic_apm/spies/rake.rb +5 -6
  49. data/lib/elastic_apm/spies/redis.rb +1 -1
  50. data/lib/elastic_apm/spies/sequel.rb +9 -7
  51. data/lib/elastic_apm/spies/sidekiq.rb +5 -5
  52. data/lib/elastic_apm/spies/tilt.rb +2 -2
  53. data/lib/elastic_apm/sql_summarizer.rb +3 -3
  54. data/lib/elastic_apm/stacktrace_builder.rb +6 -6
  55. data/lib/elastic_apm/subscriber.rb +3 -3
  56. data/lib/elastic_apm/traceparent.rb +62 -0
  57. data/lib/elastic_apm/transaction.rb +62 -93
  58. data/lib/elastic_apm/transport/base.rb +98 -0
  59. data/lib/elastic_apm/transport/connection.rb +175 -0
  60. data/lib/elastic_apm/transport/filters.rb +45 -0
  61. data/lib/elastic_apm/transport/filters/request_body_filter.rb +31 -0
  62. data/lib/elastic_apm/transport/filters/secrets_filter.rb +59 -0
  63. data/lib/elastic_apm/transport/serializers.rb +58 -0
  64. data/lib/elastic_apm/transport/serializers/error_serializer.rb +59 -0
  65. data/lib/elastic_apm/transport/serializers/span_serializer.rb +30 -0
  66. data/lib/elastic_apm/transport/serializers/transaction_serializer.rb +33 -0
  67. data/lib/elastic_apm/transport/worker.rb +73 -0
  68. data/lib/elastic_apm/util.rb +11 -8
  69. data/lib/elastic_apm/version.rb +1 -1
  70. metadata +40 -21
  71. data/.travis.yml +0 -5
  72. data/docs/troubleshooting.asciidoc +0 -28
  73. data/lib/elastic_apm/filters.rb +0 -46
  74. data/lib/elastic_apm/filters/request_body_filter.rb +0 -33
  75. data/lib/elastic_apm/filters/secrets_filter.rb +0 -59
  76. data/lib/elastic_apm/http.rb +0 -139
  77. data/lib/elastic_apm/process_info.rb +0 -24
  78. data/lib/elastic_apm/serializers.rb +0 -28
  79. data/lib/elastic_apm/serializers/errors.rb +0 -61
  80. data/lib/elastic_apm/serializers/transactions.rb +0 -51
  81. data/lib/elastic_apm/service_info.rb +0 -54
  82. data/lib/elastic_apm/system_info.rb +0 -28
  83. data/lib/elastic_apm/util/dig.rb +0 -31
  84. data/lib/elastic_apm/util/inspector.rb +0 -61
  85. 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
@@ -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
@@ -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