elastic-apm 2.1.2 → 2.2.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.

@@ -13,55 +13,52 @@ module ElasticAPM
13
13
  def initialize(
14
14
  name,
15
15
  type = nil,
16
- transaction: nil,
17
- parent: nil,
16
+ transaction_id: nil,
17
+ parent_id: nil,
18
18
  context: nil,
19
- stacktrace_builder: nil
19
+ stacktrace_builder: nil,
20
+ trace_context: nil
20
21
  )
21
22
  @name = name
22
23
  @type = type || DEFAULT_TYPE
23
24
 
24
- @id = SecureRandom.hex(8)
25
+ @transaction_id = transaction_id
25
26
 
26
- self.transaction = transaction
27
- self.parent = parent
27
+ @parent_id = parent_id
28
+ @trace_context = trace_context || TraceContext.for_span
28
29
 
29
- @context = context
30
+ @context = context || Span::Context.new
30
31
  @stacktrace_builder = stacktrace_builder
31
32
  end
32
33
  # rubocop:enable Metrics/ParameterLists
33
34
 
34
- attr_accessor :name, :type, :original_backtrace, :parent
35
- attr_reader :id, :context, :stacktrace, :duration,
36
- :timestamp, :transaction_id, :trace_id
35
+ attr_accessor :name, :type, :original_backtrace, :parent_id, :trace_context
36
+ attr_reader :context, :stacktrace, :duration, :timestamp, :transaction_id
37
37
 
38
- def transaction=(transaction)
39
- @transaction_id = transaction&.id
40
- @trace_id = transaction&.trace_id
38
+ def id
39
+ trace_context&.span_id
41
40
  end
42
41
 
43
- def parent_id
44
- @parent&.id || transaction_id
42
+ def trace_id
43
+ trace_context&.trace_id
45
44
  end
46
45
 
47
46
  # life cycle
48
47
 
49
- def start
50
- @timestamp = Util.micros
48
+ def start(timestamp = Util.micros)
49
+ @timestamp = timestamp
51
50
 
52
51
  self
53
52
  end
54
53
 
55
- def stop
56
- @duration = Util.micros - timestamp
54
+ def stop(end_timestamp = Util.micros)
55
+ @duration ||= (end_timestamp - timestamp)
57
56
  end
58
57
 
59
- def done
60
- stop
58
+ def done(end_time: Util.micros)
59
+ stop end_time
61
60
 
62
- if should_build_stacktrace?
63
- build_stacktrace
64
- end
61
+ build_stacktrace! if should_build_stacktrace?
65
62
 
66
63
  self
67
64
  end
@@ -89,13 +86,13 @@ module ElasticAPM
89
86
 
90
87
  private
91
88
 
92
- def should_build_stacktrace?
93
- @stacktrace_builder && original_backtrace && long_enough_for_stacktrace?
89
+ def build_stacktrace!
90
+ @stacktrace = @stacktrace_builder.build(original_backtrace, type: :span)
91
+ self.original_backtrace = nil # release original
94
92
  end
95
93
 
96
- def build_stacktrace
97
- @stacktrace = @stacktrace_builder.build(original_backtrace, type: :span)
98
- self.original_backtrace = nil # release it
94
+ def should_build_stacktrace?
95
+ @stacktrace_builder && original_backtrace && long_enough_for_stacktrace?
99
96
  end
100
97
 
101
98
  def long_enough_for_stacktrace?
@@ -4,12 +4,14 @@ module ElasticAPM
4
4
  class Span
5
5
  # @api private
6
6
  class Context
7
- def initialize(db: nil, http: nil)
7
+ def initialize(db: nil, http: nil, tags: {})
8
+ @sync = true
8
9
  @db = db && Db.new(db)
9
10
  @http = http && Http.new(http)
11
+ @tags = tags
10
12
  end
11
13
 
12
- attr_accessor :sync, :db, :http
14
+ attr_accessor :sync, :db, :http, :tags
13
15
 
14
16
  # @api private
15
17
  class Db
@@ -26,11 +26,10 @@ module ElasticAPM
26
26
 
27
27
  ElasticAPM.with_span name, type do |span|
28
28
  ElasticAPM::Spies::NetHTTPSpy.disable_in do
29
- id = span&.id || transaction.id
29
+ trace_context = span&.trace_context || transaction.trace_context
30
30
 
31
31
  run_request_without_apm(method, url, body, headers) do |req|
32
- req['Elastic-Apm-Traceparent'] =
33
- transaction.traceparent.to_header(span_id: id)
32
+ req['Elastic-Apm-Traceparent'] = trace_context.to_header
34
33
 
35
34
  yield req if block_given?
36
35
  end
@@ -5,7 +5,7 @@ module ElasticAPM
5
5
  module Spies
6
6
  # @api private
7
7
  class HTTPSpy
8
- # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
8
+ # rubocop:disable Metrics/MethodLength
9
9
  def install
10
10
  ::HTTP::Client.class_eval do
11
11
  alias perform_without_apm perform
@@ -22,17 +22,14 @@ module ElasticAPM
22
22
  type = "ext.http_rb.#{method}"
23
23
 
24
24
  ElasticAPM.with_span name, type do |span|
25
- id = span&.id || transaction.id
26
-
27
- req['Elastic-Apm-Traceparent'] =
28
- transaction.traceparent.to_header(span_id: id)
29
-
25
+ trace_context = span&.trace_context || transaction.trace_context
26
+ req['Elastic-Apm-Traceparent'] = trace_context.to_header
30
27
  perform_without_apm(req, options)
31
28
  end
32
29
  end
33
30
  end
34
31
  end
35
- # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
32
+ # rubocop:enable Metrics/MethodLength
36
33
  end
37
34
 
38
35
  register 'HTTP', 'http', HTTPSpy.new
@@ -49,11 +49,8 @@ module ElasticAPM
49
49
  type = "ext.net_http.#{method}"
50
50
 
51
51
  ElasticAPM.with_span name, type do |span|
52
- id = span&.id || transaction.id
53
-
54
- req['Elastic-Apm-Traceparent'] =
55
- transaction.traceparent.to_header(span_id: id)
56
-
52
+ trace_context = span&.trace_context || transaction.trace_context
53
+ req['Elastic-Apm-Traceparent'] = trace_context.to_header
57
54
  request_without_apm(req, body, &block)
58
55
  end
59
56
  end
@@ -6,7 +6,7 @@ module ElasticAPM
6
6
  # @api private
7
7
  class SqlSummarizer
8
8
  DEFAULT = 'SQL'
9
- TABLE_REGEX = %{["'`]?([A-Za-z0-9]+)}
9
+ TABLE_REGEX = %{["'`]?([A-Za-z0-9_]+)}
10
10
 
11
11
  REGEXES = {
12
12
  /^BEGIN/i => 'BEGIN',
@@ -2,20 +2,41 @@
2
2
 
3
3
  module ElasticAPM
4
4
  # @api private
5
- class Traceparent
5
+ class TraceContext
6
6
  class InvalidTraceparentHeader < StandardError; end
7
7
 
8
8
  VERSION = '00'
9
9
  HEX_REGEX = /[^[:xdigit:]]/.freeze
10
10
 
11
- def initialize
12
- @version = VERSION
11
+ def initialize(
12
+ version: VERSION,
13
+ trace_id: nil,
14
+ span_id: nil,
15
+ recorded: true
16
+ )
17
+ @version = version
18
+ @trace_id = trace_id
19
+ @span_id = span_id
20
+ @recorded = recorded
13
21
  end
14
22
 
15
- def self.from_transaction(transaction)
23
+ attr_accessor :version, :trace_id, :span_id, :recorded
24
+
25
+ alias :recorded? :recorded
26
+
27
+ def self.for_transaction(sampled: true)
16
28
  new.tap do |t|
17
29
  t.trace_id = SecureRandom.hex(16)
18
- t.recorded = transaction.sampled?
30
+ t.span_id = SecureRandom.hex(8)
31
+ t.recorded = sampled
32
+ end
33
+ end
34
+
35
+ def self.for_span
36
+ new.tap do |t|
37
+ t.trace_id = SecureRandom.hex(16)
38
+ t.span_id = SecureRandom.hex(8)
39
+ t.recorded = true
19
40
  end
20
41
  end
21
42
 
@@ -36,10 +57,6 @@ module ElasticAPM
36
57
  end
37
58
  # rubocop:enable Metrics/AbcSize
38
59
 
39
- attr_accessor :header, :version, :trace_id, :span_id, :recorded
40
-
41
- alias :recorded? :recorded
42
-
43
60
  def flags=(flags)
44
61
  @flags = flags
45
62
 
@@ -54,8 +71,11 @@ module ElasticAPM
54
71
  format('%02x', flags.to_i(2))
55
72
  end
56
73
 
57
- def to_header(span_id: nil)
58
- span_id ||= self.span_id
74
+ def child
75
+ dup.tap { |tc| tc.span_id = SecureRandom.hex(8) }
76
+ end
77
+
78
+ def to_header
59
79
  format('%s-%s-%s-%s', version, trace_id, span_id, hex_flags)
60
80
  end
61
81
  end
@@ -16,7 +16,7 @@ module ElasticAPM
16
16
  sampled: true,
17
17
  context: nil,
18
18
  tags: nil,
19
- traceparent: nil
19
+ trace_context: nil
20
20
  )
21
21
  @name = name
22
22
  @type = type || DEFAULT_TYPE
@@ -26,13 +26,11 @@ module ElasticAPM
26
26
  @context = context || Context.new # TODO: Lazy generate this?
27
27
  Util.reverse_merge!(@context.tags, tags) if tags
28
28
 
29
- @id = SecureRandom.hex(8)
30
-
31
- if traceparent
32
- @traceparent = traceparent
33
- @parent_id = traceparent.span_id
29
+ if trace_context
30
+ @parent_id = trace_context.span_id
31
+ @trace_context = trace_context
34
32
  else
35
- @traceparent = Traceparent.from_transaction(self)
33
+ @trace_context = TraceContext.for_transaction(sampled: sampled)
36
34
  end
37
35
 
38
36
  @started_spans = 0
@@ -44,8 +42,12 @@ module ElasticAPM
44
42
 
45
43
  attr_accessor :name, :type, :result
46
44
 
47
- attr_reader :id, :context, :duration, :started_spans, :dropped_spans,
48
- :timestamp, :traceparent, :notifications, :parent_id
45
+ attr_reader :context, :duration, :started_spans, :dropped_spans,
46
+ :timestamp, :trace_context, :notifications, :parent_id
47
+
48
+ def id
49
+ trace_context.span_id
50
+ end
49
51
 
50
52
  def sampled?
51
53
  @sampled
@@ -62,24 +64,24 @@ module ElasticAPM
62
64
  deprecate :done?, :stopped?
63
65
 
64
66
  def trace_id
65
- traceparent&.trace_id
67
+ trace_context&.trace_id
66
68
  end
67
69
 
68
70
  # life cycle
69
71
 
70
- def start
71
- @timestamp = Util.micros
72
+ def start(timestamp = Util.micros)
73
+ @timestamp = timestamp
72
74
  self
73
75
  end
74
76
 
75
- def stop
77
+ def stop(end_timestamp = Util.micros)
76
78
  raise 'Transaction not yet start' unless timestamp
77
- @duration = Util.micros - timestamp
79
+ @duration = end_timestamp - timestamp
78
80
  self
79
81
  end
80
82
 
81
- def done(result = nil)
82
- stop
83
+ def done(result = nil, end_time: Util.micros)
84
+ stop end_time
83
85
  self.result = result if result
84
86
  self
85
87
  end
@@ -9,6 +9,7 @@ module ElasticAPM
9
9
 
10
10
  KEY_FILTERS = [
11
11
  /passw(or)?d/i,
12
+ /auth/i,
12
13
  /^pw$/,
13
14
  /secret/i,
14
15
  /token/i,
@@ -46,7 +46,7 @@ module ElasticAPM
46
46
  end
47
47
 
48
48
  def build_user(user)
49
- return unless user
49
+ return if !user || user.empty?
50
50
 
51
51
  {
52
52
  id: keyword_field(user.id),
@@ -37,11 +37,10 @@ module ElasticAPM
37
37
  def build(context)
38
38
  return unless context
39
39
 
40
- {
41
- sync: context.sync,
42
- db: build_db(context.db),
43
- http: build_http(context.http)
44
- }
40
+ { sync: context.sync }.tap do |base|
41
+ base[:db] = build_db(context.db) if context.db
42
+ base[:http] = build_http(context.http) if context.http
43
+ end
45
44
  end
46
45
 
47
46
  private
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ElasticAPM
4
- VERSION = '2.1.2'
4
+ VERSION = '2.2.0'
5
5
  end
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: 2.1.2
4
+ version: 2.2.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-12-07 00:00:00.000000000 Z
11
+ date: 2019-01-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -75,6 +75,7 @@ files:
75
75
  - docs/getting-started-rails.asciidoc
76
76
  - docs/index.asciidoc
77
77
  - docs/introduction.asciidoc
78
+ - docs/opentracing.asciidoc
78
79
  - docs/supported-technologies.asciidoc
79
80
  - elastic-apm.gemspec
80
81
  - lib/elastic-apm.rb
@@ -109,6 +110,7 @@ files:
109
110
  - lib/elastic_apm/normalizers/action_mailer.rb
110
111
  - lib/elastic_apm/normalizers/action_view.rb
111
112
  - lib/elastic_apm/normalizers/active_record.rb
113
+ - lib/elastic_apm/opentracing.rb
112
114
  - lib/elastic_apm/railtie.rb
113
115
  - lib/elastic_apm/span.rb
114
116
  - lib/elastic_apm/span/context.rb
@@ -133,7 +135,7 @@ files:
133
135
  - lib/elastic_apm/stacktrace/frame.rb
134
136
  - lib/elastic_apm/stacktrace_builder.rb
135
137
  - lib/elastic_apm/subscriber.rb
136
- - lib/elastic_apm/traceparent.rb
138
+ - lib/elastic_apm/trace_context.rb
137
139
  - lib/elastic_apm/transaction.rb
138
140
  - lib/elastic_apm/transport/base.rb
139
141
  - lib/elastic_apm/transport/connection.rb
@@ -173,8 +175,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
173
175
  - !ruby/object:Gem::Version
174
176
  version: '0'
175
177
  requirements: []
176
- rubyforge_project:
177
- rubygems_version: 2.7.6
178
+ rubygems_version: 3.0.2
178
179
  signing_key:
179
180
  specification_version: 4
180
181
  summary: The official Elastic APM agent for Ruby