opentelemetry-exporters-datadog 0.1.0 → 0.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.
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