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

@@ -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