opentelemetry-exporters-datadog 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d6a3655e5031e8d6468cfb70c94d9121d6dc24797207124066392f6215a36e0d
4
- data.tar.gz: 2587db24b129fff673be086fe542140edf64327d783a022b2edafeee6cd64416
3
+ metadata.gz: f7dde9e181d97049cde4959b77b40c51bea98076fa95f0d1f438ef2668c3fa8d
4
+ data.tar.gz: 5ee0eb46973deb9e05a1da16f7e7cd4adbf85878ce0f11343b98adcbf2505891
5
5
  SHA512:
6
- metadata.gz: d0663fcc6cadd7eb0baefa0f33251c59c380e16f42079873a2c463cbbd889b49a7123351d248afe0c6e527b090a6ed43a7d276ee6ca78d101ffc01c321856f79
7
- data.tar.gz: 2ce86ba82c00838ad078112e016e3c8b67f7f52144d354229913861aeb0002a73a6068179897bc77eedcf370c00093d03dd9e5f0c0e2ad55e05592005fdd605c
6
+ metadata.gz: '0820577aff95b2743e39449eefe1f9a390e94e234fb282d8398ddacda9b6d943c433021a39bbc6ad39655ac86c870476bd37f5a58f04842765512a2c03da2b82'
7
+ data.tar.gz: b820f015106de8c45881ea5d84069cb5310dd6c35a7b592efbfc66f6bbc2e7ac110ba5ec05e32b900ca6d40738f580797a4f1ddbb5a0bfc019958420ba88a127
@@ -2,7 +2,15 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.2.0] - 2020-12-04
6
+
7
+ ### Added
8
+ - update compatibility for v0.10.0 of opentelemetry-api and opentelemetry-sdk
9
+ - add export of resource attributes
10
+ - add handling of unified service tags for version and service
11
+
5
12
  ## [0.1.0] - 2020-07-22
13
+
6
14
  ### Added
7
15
  - initial release
8
16
  - add DatadogSpanProcessor
data/README.md CHANGED
@@ -136,7 +136,7 @@ You can configure the application to automatically tag your Datadog exported tra
136
136
  - `DD_TAGS`: Custom tags in value pairs separated by `,` (e.g. `layer:api,team:intake`)
137
137
  - If `DD_ENV`, `DD_SERVICE` or `DD_VERSION` are set, it will override any respective `env`/`service`/`version` tag defined in `DD_TAGS`.
138
138
  - If `DD_ENV`, `DD_SERVICE` or `DD_VERSION` are NOT set, tags defined in `DD_TAGS` will be used to populate `env`/`service`/`version` respectively.
139
-
139
+ - As a fallback, Resource attributes `deployment.environment` `service.name`, and `service.version` will be used to populate `env`/`service`/`version` respectively.
140
140
  These values can also be overridden at the trace exporter level:
141
141
 
142
142
  ```ruby
@@ -5,11 +5,6 @@
5
5
  # This product includes software developed at Datadog (https://www.datadoghq.com/).
6
6
  # Copyright 2020 Datadog, Inc.
7
7
 
8
- # require_relative './datadog/exporter.rb'
9
- # require_relative './datadog/version.rb'
10
- # require_relative './datadog/datadog_span_processor.rb'
11
- # require_relative './datadog/propagator.rb'
12
- # require_relative './datadog_probability_sampler'
13
8
  require 'opentelemetry/exporters/datadog/exporter'
14
9
  require 'opentelemetry/exporters/datadog/version'
15
10
  require 'opentelemetry/exporters/datadog/datadog_span_processor'
@@ -5,7 +5,7 @@
5
5
  # This product includes software developed at Datadog (https://www.datadoghq.com/).
6
6
  # Copyright 2020 Datadog, Inc.
7
7
 
8
- require 'opentelemetry/sdk/trace/samplers/probability_sampler'
8
+ require 'opentelemetry/sdk/trace/samplers/trace_id_ratio_based'
9
9
  require 'opentelemetry/sdk/trace/samplers/decision'
10
10
  require 'opentelemetry/sdk/trace/samplers/result'
11
11
 
@@ -13,22 +13,29 @@ module OpenTelemetry
13
13
  module Exporters
14
14
  module Datadog
15
15
  # Implements sampling based on a probability but records all spans regardless.
16
- class DatadogProbabilitySampler < OpenTelemetry::SDK::Trace::Samplers::ProbabilitySampler
17
- RECORD_AND_SAMPLED = OpenTelemetry::SDK::Trace::Samplers::Result.new(decision: OpenTelemetry::SDK::Trace::Samplers::Decision::RECORD_AND_SAMPLED)
18
- RECORD = OpenTelemetry::SDK::Trace::Samplers::Result.new(decision: OpenTelemetry::SDK::Trace::Samplers::Decision::RECORD)
16
+ class DatadogProbabilitySampler
17
+ attr_reader :description
19
18
 
20
- private_constant(:RECORD_AND_SAMPLED, :RECORD)
19
+ def initialize(probability)
20
+ @probability = probability
21
+ @id_upper_bound = (probability * (2**64 - 1)).ceil
22
+ @description = format('TraceIdRatioBased{%.6f}', probability)
23
+ end
24
+
25
+ def sample?(trace_id)
26
+ @probability == 1.0 || trace_id[8, 8].unpack1('Q>') < @id_upper_bound
27
+ end
21
28
 
22
29
  # @api private
23
30
  #
24
31
  # See {Samplers}.
25
32
  def should_sample?(trace_id:, parent_context:, links:, name:, kind:, attributes:)
26
33
  # Ignored for sampling decision: links, name, kind, attributes.
27
-
28
- if sample?(trace_id, parent_context)
29
- RECORD_AND_SAMPLED
34
+ tracestate = OpenTelemetry::Trace.current_span(parent_context).context.tracestate
35
+ if sample?(trace_id)
36
+ OpenTelemetry::SDK::Trace::Samplers::Result.new(decision: OpenTelemetry::SDK::Trace::Samplers::Decision::RECORD_AND_SAMPLE, tracestate: tracestate)
30
37
  else
31
- RECORD
38
+ OpenTelemetry::SDK::Trace::Samplers::Result.new(decision: OpenTelemetry::SDK::Trace::Samplers::Decision::RECORD_ONLY, tracestate: tracestate)
32
39
  end
33
40
  end
34
41
 
@@ -40,16 +47,10 @@ module OpenTelemetry
40
47
  def self.default_with_probability(probability = 1.0)
41
48
  raise ArgumentError, 'probability must be in range [0.0, 1.0]' unless (0.0..1.0).include?(probability)
42
49
 
43
- new(probability,
44
- ignore_parent: false,
45
- apply_to_remote_parent: :root_spans_and_remote_parent,
46
- apply_to_all_spans: :root_spans_and_remote_parent)
50
+ new(probability)
47
51
  end
48
52
 
49
- DEFAULT = new(1.0,
50
- ignore_parent: false,
51
- apply_to_remote_parent: :root_spans_and_remote_parent,
52
- apply_to_all_spans: :root_spans_and_remote_parent)
53
+ DEFAULT = new(1.0)
53
54
  end
54
55
  end
55
56
  end
@@ -53,7 +53,7 @@ module OpenTelemetry
53
53
 
54
54
  # datadog trace-agent endpoint requires a complete trace to be sent
55
55
  # threadsafe may block on lock
56
- def on_start(span)
56
+ def on_start(span, _parent_context)
57
57
  context = span.context
58
58
  trace_id = context.trace_id
59
59
 
@@ -135,7 +135,7 @@ module OpenTelemetry
135
135
 
136
136
  # shuts the consumer thread down and flushes the current accumulated buffer
137
137
  # will block until the thread is finished
138
- def shutdown
138
+ def shutdown(timeout: nil)
139
139
  lock do
140
140
  @keep_running = false
141
141
  @condition.signal
@@ -7,9 +7,8 @@
7
7
 
8
8
  require 'uri'
9
9
  require 'ddtrace'
10
- require 'opentelemetry/sdk'
10
+ require 'opentelemetry'
11
11
  require 'opentelemetry/exporters/datadog/exporter/span_encoder'
12
- # require_relative './exporter/span_encoder.rb'
13
12
 
14
13
  module OpenTelemetry
15
14
  module Exporters
@@ -22,16 +21,8 @@ module OpenTelemetry
22
21
  class Exporter
23
22
  DEFAULT_AGENT_URL = 'http://localhost:8126'
24
23
  DEFAULT_SERVICE_NAME = 'my_service'
25
- SUCCESS = begin
26
- OpenTelemetry::SDK::Trace::Export::SUCCESS
27
- rescue NameError
28
- 0
29
- end
30
- FAILURE = begin
31
- OpenTelemetry::SDK::Trace::Export::FAILURE
32
- rescue NameError
33
- 1
34
- end
24
+ SUCCESS = 0
25
+ FAILURE = 1
35
26
  private_constant(:SUCCESS, :FAILURE)
36
27
 
37
28
  def initialize(service_name: nil, agent_url: nil, env: nil, version: nil, tags: nil)
@@ -68,7 +59,7 @@ module OpenTelemetry
68
59
 
69
60
  # Called when {TracerProvider#shutdown} is called, if this exporter is
70
61
  # registered to a {TracerProvider} object.
71
- def shutdown
62
+ def shutdown(timeout: nil)
72
63
  @shutdown = true
73
64
  end
74
65
 
@@ -32,6 +32,9 @@ module OpenTelemetry
32
32
  ORIGIN_REGEX = /#{DD_ORIGIN}\=(.*?)($|,)/.freeze
33
33
  PROBABILITY_REGEX = /\d[.]\d{1,6}/.freeze
34
34
  TRUNCATION_HELPER = ::Datadog::DistributedTracing::Headers::Headers.new({})
35
+ RESOURCE_SERVICE_TAG = 'service.name'
36
+ RESOURCE_VERSION_TAG = 'service.version'
37
+ RESOURCE_ENVIRONMENT_TAG = 'deployment.environment'
35
38
 
36
39
  INSTRUMENTATION_SPAN_TYPES = {
37
40
  'OpenTelemetry::Instrumentation::Ethon' => ::Datadog::Ext::HTTP::TYPE_OUTBOUND,
@@ -56,20 +59,23 @@ module OpenTelemetry
56
59
  span_type = get_span_type(span)
57
60
  span_name = get_span_name(span)
58
61
 
62
+ # this excludes service.name, which we get seperately
63
+ span_resource_tags, resource_service_name, resource_environment_name, resource_version_name = get_resource_tags_and_service(span)
64
+
65
+ default_tags_including_resource = default_tags.merge(span_resource_tags)
59
66
  datadog_span = ::Datadog::Span.new(nil, span_name,
60
- service: service,
67
+ service: resource_service_name || service,
61
68
  trace_id: trace_id,
62
69
  parent_id: parent_id,
63
70
  resource: get_resource(span),
64
71
  span_type: span_type)
65
-
66
72
  # span_id is autogenerated so have to override
67
73
  datadog_span.span_id = span_id
68
74
  datadog_span.start_time = span.start_timestamp
69
75
  datadog_span.end_time = span.end_timestamp
70
76
 
71
77
  # set span.error, span tag error.msg/error.type
72
- if span.status && span.status.canonical_code != OpenTelemetry::Trace::Status::OK
78
+ if span.status && !span.status.ok?
73
79
  datadog_span.status = 1
74
80
 
75
81
  exception_type, exception_msg, exception_stack = get_exception_info(span)
@@ -82,14 +88,14 @@ module OpenTelemetry
82
88
  end
83
89
 
84
90
  # set default tags
85
- default_tags&.keys&.each do |attribute|
86
- datadog_span.set_tag(attribute, span.attributes[attribute])
91
+ default_tags_including_resource&.keys&.each do |attribute|
92
+ datadog_span.set_tag(attribute, default_tags_including_resource[attribute])
87
93
  end
88
94
 
89
95
  origin = get_origin_string(span)
90
96
  datadog_span.set_tag(DD_ORIGIN, origin) if origin && parent_id.zero?
91
- datadog_span.set_tag(VERSION_KEY, version) if version && parent_id.zero?
92
- datadog_span.set_tag(ENV_KEY, env) if env
97
+ datadog_span.set_tag(VERSION_KEY, resource_version_name || version) if (resource_version_name || version) && parent_id.zero?
98
+ datadog_span.set_tag(ENV_KEY, resource_environment_name || env) if resource_version_name || env
93
99
 
94
100
  # set tags - takes precedence over env vars
95
101
  span.attributes&.keys&.each do |attribute|
@@ -103,7 +109,6 @@ module OpenTelemetry
103
109
  elsif sampling_rate
104
110
  datadog_span.set_metric(SAMPLE_RATE_METRIC_KEY, sampling_rate)
105
111
  end
106
-
107
112
  datadog_spans << datadog_span
108
113
  end
109
114
 
@@ -183,6 +188,34 @@ module OpenTelemetry
183
188
  span.name
184
189
  end
185
190
 
191
+ def get_resource_tags_and_service(span)
192
+ resource_tags = {}
193
+ service_name = nil
194
+ environment_name = nil
195
+ version_name = nil
196
+ # this is open to change in new versions so being extra defensive here
197
+ return resource_tags unless (resource_attributes = begin
198
+ span.resource.attribute_enumerator.to_h
199
+ rescue StandardError
200
+ nil
201
+ end)
202
+
203
+ # grab service name seperately since it has significance
204
+ resource_attributes.each do |rattribute_key, rattribute_value|
205
+ if rattribute_key == RESOURCE_SERVICE_TAG
206
+ service_name = rattribute_value
207
+ elsif rattribute_key == RESOURCE_ENVIRONMENT_TAG
208
+ environment_name = rattribute_value
209
+ elsif rattribute_key == RESOURCE_VERSION_TAG
210
+ version_name = rattribute_value
211
+ else
212
+ resource_tags[rattribute_key] = rattribute_value
213
+ end
214
+ end
215
+
216
+ [resource_tags, service_name, environment_name, version_name]
217
+ end
218
+
186
219
  def get_origin_string(span)
187
220
  tracestate = begin
188
221
  span.tracestate
@@ -4,7 +4,7 @@
4
4
  #
5
5
  # SPDX-License-Identifier: Apache-2.0
6
6
 
7
- require 'opentelemetry/sdk'
7
+ require 'opentelemetry'
8
8
  require 'opentelemetry/context/propagation'
9
9
  require 'ddtrace/distributed_tracing/headers/headers'
10
10
  require 'ddtrace/distributed_tracing/headers/helpers'
@@ -24,13 +24,13 @@ module OpenTelemetry
24
24
  DD_ORIGIN = '_dd_origin'
25
25
  ORIGIN_REGEX = /#{DD_ORIGIN}\=(.*?)($|,)/.freeze
26
26
  DEFAULT_INJECTORS = [
27
- OpenTelemetry::Trace::Propagation::TraceContext.text_injector,
28
- OpenTelemetry::CorrelationContext::Propagation.text_injector
27
+ OpenTelemetry::Trace::Propagation::TraceContext.text_map_injector,
28
+ OpenTelemetry::Baggage::Propagation.text_map_injector
29
29
  ].freeze
30
30
 
31
31
  DEFAULT_EXTRACTORS = [
32
32
  OpenTelemetry::Trace::Propagation::TraceContext.rack_extractor,
33
- OpenTelemetry::CorrelationContext::Propagation.rack_extractor
33
+ OpenTelemetry::Baggage::Propagation.rack_extractor
34
34
  ].freeze
35
35
 
36
36
  # Returns a new Propagator
@@ -92,7 +92,8 @@ module OpenTelemetry
92
92
  tracestate: tracestate,
93
93
  remote: true)
94
94
 
95
- context.set_value(Trace::Propagation::ContextKeys.extracted_span_context_key, span_context)
95
+ span = Trace::Span.new(span_context: span_context)
96
+ Trace.context_with_span(span, parent_context: context)
96
97
  rescue StandardError => e
97
98
  OpenTelemetry.logger.debug("error extracting datadog propagation, #{e.message}")
98
99
  context
@@ -116,8 +117,7 @@ module OpenTelemetry
116
117
  end
117
118
 
118
119
  def span_context_from(context)
119
- context[Trace::Propagation::ContextKeys.current_span_key]&.context ||
120
- context[Trace::Propagation::ContextKeys.extracted_span_context_key]
120
+ OpenTelemetry::Trace.current_span(context).context
121
121
  end
122
122
 
123
123
  def get_origin_string(tracestate)
@@ -9,7 +9,7 @@ module OpenTelemetry
9
9
  module Exporters
10
10
  module Datadog
11
11
  ## Current OpenTelemetry Datadog exporter version
12
- VERSION = '0.1.0'
12
+ VERSION = '0.2.0'
13
13
  end
14
14
  end
15
15
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opentelemetry-exporters-datadog
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Datadog, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-22 00:00:00.000000000 Z
11
+ date: 2020-12-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ddtrace
@@ -30,28 +30,28 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0.5'
33
+ version: 0.10.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0.5'
40
+ version: 0.10.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: opentelemetry-sdk
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0.5'
47
+ version: 0.10.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0.5'
54
+ version: 0.10.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: bundler
57
57
  requirement: !ruby/object:Gem::Requirement