datadog-lambda 0.4.0 → 0.9.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: d37e92d79f90e4049e303719d3639560e7b025e20a62c2199342603e9f76f71d
4
- data.tar.gz: c82eb5b84734b2621220eb402e57ba1f88855f39ba94e6567bdde4a6bc6ea80c
3
+ metadata.gz: 15ddc462886c4a35ba66d327ebbc2be17c403b2d47cab973fa06e05d6df3d2d1
4
+ data.tar.gz: b90918aa8b2372e2149e4b084b5ee97d9a8268ebff7ebb83a0e1a6a3751488c1
5
5
  SHA512:
6
- metadata.gz: d6154dce5ec1743195799df476f5b0da7f13db96015822ecfcc4b42e560ba042b9b403355b33a060417c05efa2b9a99975e8fedc540cfea73c1f8e872b8d3985
7
- data.tar.gz: 649a76d46ce8fc2ab5f22590137448ec77d518f7f27cb7518300a90ee00fae638250de6ebb486bcf8c3346fa7074257f901dab00b643b30b32e8a2611cf919e1
6
+ metadata.gz: 71b82b6b3ec47c17fff39fb4f3bfd40c6d2ef7ba477baa82de83a87bc710fc0114fa7aadc84153908db40de6af8437248e9634b8838a6d60af54e44fefbe8e29
7
+ data.tar.gz: ca9afd36577caa6b5efef5663add0b37e32bfa953b55ee2909bc2f104a139e0a6478fcddcdde67687537672ae88b2d50f81b3d79c4aefa2967c29cae4faf367b
@@ -7,6 +7,7 @@
7
7
  # This product includes software developed at Datadog (https://www.datadoghq.com/).
8
8
  # Copyright 2019 Datadog, Inc.
9
9
  #
10
+ # rubocop:disable Metrics/ModuleLength
10
11
 
11
12
  require 'datadog/lambda/trace/listener'
12
13
  require 'datadog/lambda/utils/logger'
@@ -18,26 +19,57 @@ module Datadog
18
19
  # Instruments AWS Lambda functions with Datadog distributed tracing and
19
20
  # custom metrics
20
21
  module Lambda
22
+ @is_cold_start = true
23
+ @patch_http = true
24
+
25
+ # Configures Datadog's APM tracer with lambda specific defaults.
26
+ # Same options can be given as Datadog.configure in tracer
27
+ # See https://github.com/DataDog/dd-trace-rb/blob/master/docs/GettingStarted.md#quickstart-for-ruby-applications
28
+ def self.configure_apm
29
+ require 'ddtrace'
30
+ require 'ddtrace/sync_writer'
31
+
32
+ @patch_http = false
33
+ # Needed to keep trace flushes on a single line
34
+ $stdout.sync = true
35
+
36
+ Datadog.configure do |c|
37
+ c.tracer writer: Datadog::SyncWriter.new(
38
+ transport: Datadog::Transport::IO.default
39
+ )
40
+ yield(c) if block_given?
41
+ end
42
+ end
43
+
21
44
  # Wrap the body of a lambda invocation
22
45
  # @param event [Object] event sent to lambda
23
46
  # @param context [Object] lambda context
24
47
  # @param block [Proc] implementation of the handler function.
25
- def self.wrap(event, _context, &block)
48
+ def self.wrap(event, context, &block)
26
49
  Datadog::Utils.update_log_level
27
-
28
- @listener ||= Trace::Listener.new
50
+ @listener ||= initialize_listener
29
51
  @listener.on_start(event: event)
52
+ record_enhanced('invocations', context)
30
53
  begin
31
- res = block.call
54
+ cold = @is_cold_start
55
+ res = @listener.on_wrap(request_context: context, cold_start: cold) do
56
+ block.call
57
+ end
58
+ rescue StandardError => e
59
+ record_enhanced('errors', context)
60
+ raise e
32
61
  ensure
33
62
  @listener.on_end
63
+ @is_cold_start = false
34
64
  end
35
65
  res
36
66
  end
37
67
 
38
68
  # Gets the current tracing context
39
69
  def self.trace_context
40
- Datadog::Trace.trace_context
70
+ context = Hash[Datadog::Trace.trace_context]
71
+ context.delete(:source)
72
+ context
41
73
  end
42
74
 
43
75
  # Send a custom distribution metric
@@ -58,5 +90,88 @@ module Datadog
58
90
  metric = { e: time_ms, m: name, t: tag_list, v: value }.to_json
59
91
  puts metric
60
92
  end
93
+
94
+ # Generate tags for enhanced metrics
95
+ # @param context [Object] https://docs.aws.amazon.com/lambda/latest/dg/ruby-context.html
96
+ # @return [hash] a hash of the enhanced metrics tags
97
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
98
+ def self.gen_enhanced_tags(context)
99
+ arn_parts = context.invoked_function_arn.split(':')
100
+ # Check if we have an alias or version
101
+ function_alias = arn_parts[7].nil? ? nil : arn_parts[7]
102
+
103
+ tags = {
104
+ functionname: context.function_name,
105
+ region: arn_parts[3],
106
+ account_id: arn_parts[4],
107
+ memorysize: context.memory_limit_in_mb,
108
+ cold_start: @is_cold_start,
109
+ runtime: "Ruby #{RUBY_VERSION}",
110
+ resource: context.function_name
111
+ }
112
+ # If we have an alias...
113
+ unless function_alias.nil?
114
+ # If the alis version is $Latest, drop the $ for ddog tag convention.
115
+ if function_alias.start_with?('$')
116
+ function_alias[0] = ''
117
+ # If the alias is not a version number add the executed version tag
118
+ elsif !/\A\d+\z/.match(function_alias)
119
+ tags[:executedversion] = context.function_version
120
+ end
121
+ # Append the alias to the resource tag
122
+ tags[:resource] = context.function_name + ':' + function_alias
123
+ end
124
+
125
+ tags
126
+ rescue StandardError => e
127
+ Datadog::Utils.logger.error 'Unable to parse Lambda context' \
128
+ "#{context}: #{e}"
129
+ {}
130
+ end
131
+
132
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
133
+ # Format and add tags to enhanced metrics
134
+ # This method wraps the metric method, checking the DD_ENHANCED_METRICS
135
+ # environment variable, adding 'aws.lambda.enhanced' to the metric name,
136
+ # and adding the enhanced metric tags to the enhanced metrics.
137
+ # @param metric_name [String] basic name of the metric
138
+ # @param context [Object] AWS Ruby Lambda Context
139
+ # @return [boolean] false if the metric was not added for some reason,
140
+ # true otherwise (for ease of testing
141
+
142
+ def self.record_enhanced(metric_name, context)
143
+ return false unless do_enhanced_metrics?
144
+
145
+ etags = gen_enhanced_tags(context)
146
+ metric("aws.lambda.enhanced.#{metric_name}", 1, **etags)
147
+ true
148
+ end
149
+
150
+ # Check the DD_ENHANCED_METRICS environment variable
151
+ # @reurn [boolean] true if this lambda should have
152
+ # enhanced metrics
153
+ def self.do_enhanced_metrics?
154
+ dd_enhanced_metrics = ENV['DD_ENHANCED_METRICS']
155
+ return true if dd_enhanced_metrics.nil?
156
+
157
+ dd_enhanced_metrics.downcase == 'true'
158
+ end
159
+
160
+ def self.initialize_listener
161
+ handler = ENV['_HANDLER'].nil? ? 'handler' : ENV['_HANDLER']
162
+ function = ENV['AWS_LAMBDA_FUNCTION_NAME']
163
+ merge_xray_traces = false
164
+ merge_xray_traces_env = ENV['DD_MERGE_DATADOG_XRAY_TRACES']
165
+ unless merge_xray_traces_env.nil?
166
+ merge_xray_traces = merge_xray_traces_env.downcase == 'true'
167
+ Datadog::Utils.logger.debug("Setting merge traces #{merge_xray_traces}")
168
+ end
169
+
170
+ Trace::Listener.new(handler_name: handler,
171
+ function_name: function,
172
+ patch_http: @patch_http,
173
+ merge_xray_traces: merge_xray_traces)
174
+ end
61
175
  end
62
176
  end
177
+ # rubocop:enable Metrics/ModuleLength
@@ -20,5 +20,11 @@ module Datadog
20
20
  DD_XRAY_SUBSEGMENT_NAME = 'datadog-metadata'
21
21
  DD_XRAY_SUBSEGMENT_KEY = 'trace'
22
22
  DD_XRAY_SUBSEGMENT_NAMESPACE = 'datadog'
23
+ SOURCE_XRAY = 'XRAY'
24
+ SOURCE_EVENT = 'EVENT'
25
+ XRAY_ENV_VAR = '_X_AMZN_TRACE_ID'
26
+ XRAY_UDP_PORT = 2000
27
+ LOCAL_HOST = '127.0.0.1'
28
+ AWS_XRAY_DAEMON_ADDRESS_ENV_VAR = 'AWS_XRAY_DAEMON_ADDRESS'
23
29
  end
24
30
  end
@@ -8,8 +8,8 @@
8
8
  # Copyright 2019 Datadog, Inc.
9
9
  #
10
10
 
11
- require 'aws-xray-sdk'
12
11
  require 'datadog/lambda/trace/constants'
12
+ require 'datadog/lambda/trace/xray'
13
13
  require 'datadog/lambda/utils/logger'
14
14
 
15
15
  module Datadog
@@ -17,56 +17,19 @@ module Datadog
17
17
  # lambda events/X-Ray
18
18
  module Trace
19
19
  class << self
20
- def extract_trace_context(event)
20
+ def extract_trace_context(event, merge_xray_traces)
21
21
  context = read_trace_context_from_event(event)
22
22
  unless context.nil?
23
23
  begin
24
24
  add_trace_context_to_xray(context)
25
25
  rescue StandardError => e
26
- Datadog::Utils.logger.error("couldn't add metadata to xray #{e}")
26
+ Datadog::Utils.logger.debug("couldn't add metadata to xray #{e}")
27
27
  end
28
28
  return context
29
29
  end
30
- read_trace_context_from_xray
31
- end
32
-
33
- def add_trace_context_to_xray(context)
34
- seg = XRay.recorder.begin_subsegment(
35
- DD_XRAY_SUBSEGMENT_NAME,
36
- namespace: DD_XRAY_SUBSEGMENT_NAMESPACE
37
- )
38
- data = {
39
- "parent-id": context[:parent_id],
40
- "sampling-priority": context[:sample_mode].to_s,
41
- "trace-id": context[:trace_id]
42
- }
43
- seg.metadata(namespace: DD_XRAY_SUBSEGMENT_NAMESPACE)
44
- .update("#{DD_XRAY_SUBSEGMENT_KEY}": data)
45
- XRay.recorder.end_subsegment
46
- end
30
+ return nil unless merge_xray_traces
47
31
 
48
- def current_trace_context(trace_context)
49
- entity = XRay.recorder.current_entity
50
- parent_id = entity.id
51
- {
52
- trace_id: trace_context[:trace_id],
53
- parent_id: convert_to_apm_parent_id(parent_id),
54
- sample_mode: trace_context[:sample_mode]
55
- }
56
- end
57
-
58
- def read_trace_context_from_xray
59
- segment = XRay.recorder.current_entity
60
- parent_id = segment.id
61
- mode = segment.sampled ? SAMPLE_MODE_USER_KEEP : SAMPLE_MODE_USER_REJECT
62
- {
63
- trace_id: convert_to_apm_trace_id(segment.trace_id),
64
- parent_id: convert_to_apm_parent_id(parent_id),
65
- sample_mode: mode
66
- }
67
- rescue StandardError => e
68
- Datadog::Utils.logger.error("couldn't read xray trace header #{e}")
69
- nil
32
+ read_trace_context_from_xray
70
33
  end
71
34
 
72
35
  def read_trace_context_from_event(event)
@@ -79,7 +42,8 @@ module Datadog
79
42
  {
80
43
  trace_id: headers[DD_TRACE_ID_HEADER],
81
44
  parent_id: headers[DD_PARENT_ID_HEADER],
82
- sample_mode: headers[DD_SAMPLING_PRIORITY_HEADER].to_i
45
+ sample_mode: headers[DD_SAMPLING_PRIORITY_HEADER].to_i,
46
+ source: SOURCE_EVENT
83
47
  }
84
48
  end
85
49
 
@@ -99,32 +63,6 @@ module Datadog
99
63
  end
100
64
  true
101
65
  end
102
-
103
- def convert_to_apm_trace_id(xray_trace_id)
104
- parts = xray_trace_id.split('-')
105
- return nil if parts.length < 3
106
-
107
- last_part = parts[2]
108
- return nil if last_part.length != 24
109
- # Make sure every character is hex
110
- return nil if last_part.upcase[/\H/]
111
-
112
- hex = last_part.to_i(16)
113
- last_63_bits = hex & 0x7fffffffffffffff
114
- last_63_bits.to_s(10)
115
- end
116
-
117
- def convert_to_apm_parent_id(xray_parent_id)
118
- return nil if xray_parent_id.length != 16
119
- return nil if xray_parent_id.upcase[/\H/]
120
-
121
- hex = xray_parent_id.to_i(16)
122
- hex.to_s(10)
123
- end
124
-
125
- def convert_to_sample_mode(xray_sampled)
126
- xray_sampled == '1' ? SAMPLE_MODE_USER_KEEP : SAMPLE_MODE_USER_REJECT
127
- end
128
66
  end
129
67
  end
130
68
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ # ddtrace is an optional dependency for the ruby package
4
+ begin
5
+ require 'ddtrace'
6
+ rescue LoadError
7
+ Datadog::Utils.logger.debug 'dd-trace unavailable'
8
+ end
9
+
10
+ module Datadog
11
+ # TraceListener tracks tracing context information
12
+ module Trace
13
+ class <<self
14
+ def apply_datadog_trace_context(context)
15
+ unless context.nil?
16
+ trace_id = context[:trace_id].to_i
17
+ span_id = context[:parent_id].to_i
18
+ sampling_priority = context[:sample_mode]
19
+ Datadog.tracer.provider.context = Datadog::Context.new(
20
+ trace_id: trace_id,
21
+ span_id: span_id,
22
+ sampling_priority: sampling_priority
23
+ )
24
+ end
25
+ rescue StandardError
26
+ Datadog::Utils.logger.debug 'dd-trace unavailable'
27
+ end
28
+
29
+ def wrap_datadog(options, &block)
30
+ tracer_available = false
31
+ begin
32
+ Datadog.tracer
33
+ tracer_available = true
34
+ rescue StandardError
35
+ Datadog::Utils.logger.debug 'dd-trace unavailable'
36
+ end
37
+ return block.call unless tracer_available
38
+
39
+ Datadog.tracer.trace('aws.lambda', options) do |_span|
40
+ block.call
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -9,27 +9,25 @@
9
9
  #
10
10
 
11
11
  require 'datadog/lambda/trace/context'
12
- require 'datadog/lambda/trace/xray_lambda'
13
12
  require 'datadog/lambda/trace/patch_http'
14
-
15
- require 'aws-xray-sdk'
13
+ require 'datadog/lambda/trace/ddtrace'
16
14
 
17
15
  module Datadog
18
16
  module Trace
19
17
  # TraceListener tracks tracing context information
20
18
  class Listener
21
- def initialize
22
- XRay.recorder.configure(
23
- patch: %I[aws_sdk],
24
- context: Datadog::Trace::LambdaContext.new,
25
- streamer: Datadog::Trace::LambdaStreamer.new,
26
- emitter: Datadog::Trace::LambdaEmitter.new
27
- )
28
- Datadog::Trace.patch_http
19
+ def initialize(handler_name:, function_name:, patch_http:,
20
+ merge_xray_traces:)
21
+ @handler_name = handler_name
22
+ @function_name = function_name
23
+ @merge_xray_traces = merge_xray_traces
24
+
25
+ Datadog::Trace.patch_http if patch_http
29
26
  end
30
27
 
31
28
  def on_start(event:)
32
- trace_context = Datadog::Trace.extract_trace_context(event)
29
+ trace_context = Datadog::Trace.extract_trace_context(event,
30
+ @merge_xray_traces)
33
31
  Datadog::Trace.trace_context = trace_context
34
32
  Datadog::Utils.logger.debug "extracted trace context #{trace_context}"
35
33
  rescue StandardError => e
@@ -37,6 +35,39 @@ module Datadog
37
35
  end
38
36
 
39
37
  def on_end; end
38
+
39
+ def on_wrap(request_context:, cold_start:, &block)
40
+ options = get_option_tags(
41
+ request_context: request_context,
42
+ cold_start: cold_start
43
+ )
44
+ options[:resource] = @handler_name
45
+ options[:service] = @function_name
46
+ options[:span_type] = 'serverless'
47
+ Datadog::Trace.apply_datadog_trace_context(Datadog::Trace.trace_context)
48
+ Datadog::Trace.wrap_datadog(options) do
49
+ block.call
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ def get_option_tags(request_context:, cold_start:)
56
+ function_arn = request_context.invoked_function_arn.downcase
57
+ tk = function_arn.split(':')
58
+ function_arn = tk.length > 7 ? tk[0, 7].join(':') : function_arn
59
+ function_version = tk.length > 7 ? tk[7] : '$LATEST'
60
+ options = {
61
+ tags: {
62
+ cold_start: cold_start,
63
+ function_arn: function_arn,
64
+ function_version: function_version,
65
+ request_id: request_context.aws_request_id,
66
+ resource_names: request_context.function_name
67
+ }
68
+ }
69
+ options
70
+ end
40
71
  end
41
72
  end
42
73
  end
@@ -0,0 +1,141 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Unless explicitly stated otherwise all files in this repository are licensed
5
+ # under the Apache License Version 2.0.
6
+ #
7
+ # This product includes software developed at Datadog (https://www.datadoghq.com/).
8
+ # Copyright 2019 Datadog, Inc.
9
+ #
10
+ require 'datadog/lambda/trace/constants'
11
+ require 'datadog/lambda/utils/logger'
12
+ require 'securerandom'
13
+ require 'json'
14
+ require 'socket'
15
+
16
+ module Datadog
17
+ # Trace contains utilities related to reading/writing trace context from
18
+ # lambda events/X-Ray
19
+ module Trace
20
+ class << self
21
+ def read_trace_context_from_xray
22
+ header = ENV[XRAY_ENV_VAR]
23
+ segment = parse_xray_trace_context_header(header)
24
+ trace_id = convert_to_apm_trace_id(segment[:xray_trace_id])
25
+ parent_id = convert_to_apm_parent_id(segment[:xray_parent_id])
26
+ sample_mode = convert_to_sample_mode(segment[:xray_sample_mode])
27
+
28
+ if trace_id.nil? || parent_id.nil? || sample_mode.nil?
29
+ Datadog::Utils.logger.error("couldn't read xray header #{header}")
30
+ return nil
31
+ end
32
+ {
33
+ trace_id: trace_id,
34
+ parent_id: parent_id,
35
+ sample_mode: sample_mode,
36
+ source: SOURCE_XRAY
37
+ }
38
+ end
39
+
40
+ def add_trace_context_to_xray(context)
41
+ data = generate_xray_metadata_subsegment(context)
42
+ send_xray_daemon_data(data)
43
+ Datadog::Utils.logger.debug("sent metadata to xray #{data}")
44
+ end
45
+
46
+ def generate_xray_metadata_subsegment(context)
47
+ header = ENV[XRAY_ENV_VAR]
48
+ segment = parse_xray_trace_context_header(header)
49
+
50
+ {
51
+ "id": SecureRandom.hex(8),
52
+ "trace_id": segment[:xray_trace_id],
53
+ "parent_id": segment[:xray_parent_id],
54
+ "name": DD_XRAY_SUBSEGMENT_NAME,
55
+ "start_time": Time.now.to_f,
56
+ "end_time": Time.now.to_f,
57
+ "type": 'subsegment',
58
+ "metadata": {
59
+ "datadog": {
60
+ "trace": {
61
+ "parent-id": context[:parent_id],
62
+ "sampling-priority": context[:sample_mode].to_s,
63
+ "trace-id": context[:trace_id]
64
+ }
65
+ }
66
+ }
67
+ }.to_json
68
+ end
69
+
70
+ def current_trace_context(trace_context)
71
+ trace_context = Hash[trace_context]
72
+ begin
73
+ # This will only succeed if the user has imported xray themselves
74
+ entity = XRay.recorder.current_entity
75
+ trace_context[:parent_id] = convert_to_apm_parent_id(entity.id)
76
+ rescue StandardError
77
+ Datadog::Utils.logger.debug("couldn't fetch xray entity")
78
+ end
79
+ trace_context
80
+ end
81
+
82
+ def send_xray_daemon_data(data)
83
+ xray_daemon_env = ENV[AWS_XRAY_DAEMON_ADDRESS_ENV_VAR]
84
+ socket = XRAY_UDP_PORT
85
+ address = LOCAL_HOST
86
+ address, socket = xray_daemon_env.split(':') unless xray_daemon_env.nil?
87
+
88
+ sock = UDPSocket.open
89
+ message = "{\"format\": \"json\", \"version\": 1}\n#{data}"
90
+ sock.send(message, 0, address, socket)
91
+ end
92
+
93
+ def parse_xray_trace_context_header(header)
94
+ Datadog::Utils.logger.debug("Reading trace context from env #{header}")
95
+ trace_id, parent_id, sampled = header.split(';')
96
+ .map { |v| parse_assignment(v) }
97
+
98
+ return nil if trace_id.nil? || parent_id.nil? || sampled. nil?
99
+
100
+ {
101
+ xray_trace_id: trace_id,
102
+ xray_parent_id: parent_id,
103
+ xray_sample_mode: sampled
104
+ }
105
+ end
106
+
107
+ def parse_assignment(value)
108
+ return nil if value.nil?
109
+
110
+ _, raw_value, * = value.split('=')
111
+ raw_value
112
+ end
113
+
114
+ def convert_to_apm_trace_id(xray_trace_id)
115
+ parts = xray_trace_id.split('-')
116
+ return nil if parts.length < 3
117
+
118
+ last_part = parts[2]
119
+ return nil if last_part.length != 24
120
+ # Make sure every character is hex
121
+ return nil if last_part.upcase[/\H/]
122
+
123
+ hex = last_part.to_i(16)
124
+ last_63_bits = hex & 0x7fffffffffffffff
125
+ last_63_bits.to_s(10)
126
+ end
127
+
128
+ def convert_to_apm_parent_id(xray_parent_id)
129
+ return nil if xray_parent_id.length != 16
130
+ return nil if xray_parent_id.upcase[/\H/]
131
+
132
+ hex = xray_parent_id.to_i(16)
133
+ hex.to_s(10)
134
+ end
135
+
136
+ def convert_to_sample_mode(xray_sampled)
137
+ xray_sampled == '1' ? SAMPLE_MODE_USER_KEEP : SAMPLE_MODE_USER_REJECT
138
+ end
139
+ end
140
+ end
141
+ end
@@ -12,7 +12,7 @@ module Datadog
12
12
  module Lambda
13
13
  module VERSION
14
14
  MAJOR = 0
15
- MINOR = 4
15
+ MINOR = 9
16
16
  PATCH = 0
17
17
  PRE = nil
18
18
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: datadog-lambda
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Datadog, Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-10-30 00:00:00.000000000 Z
11
+ date: 2020-07-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-xray-sdk
@@ -16,14 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.11'
19
+ version: 0.11.3
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0.11'
26
+ version: 0.11.3
27
+ - !ruby/object:Gem::Dependency
28
+ name: ddtrace
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.32'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.32'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rake
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -93,12 +107,13 @@ files:
93
107
  - lib/datadog/lambda.rb
94
108
  - lib/datadog/lambda/trace/constants.rb
95
109
  - lib/datadog/lambda/trace/context.rb
110
+ - lib/datadog/lambda/trace/ddtrace.rb
96
111
  - lib/datadog/lambda/trace/listener.rb
97
112
  - lib/datadog/lambda/trace/patch_http.rb
98
- - lib/datadog/lambda/trace/xray_lambda.rb
113
+ - lib/datadog/lambda/trace/xray.rb
99
114
  - lib/datadog/lambda/utils/logger.rb
100
115
  - lib/datadog/lambda/version.rb
101
- homepage: https://github.com/DataDog/dd-lambda-rb
116
+ homepage: https://github.com/DataDog/datadog-lambda-layer-rb
102
117
  licenses:
103
118
  - Apache-2.0
104
119
  metadata:
@@ -118,8 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
118
133
  - !ruby/object:Gem::Version
119
134
  version: '0'
120
135
  requirements: []
121
- rubyforge_project:
122
- rubygems_version: 2.7.6
136
+ rubygems_version: 3.0.3
123
137
  signing_key:
124
138
  specification_version: 4
125
139
  summary: Instruments your Ruby AWS Lambda functions with Datadog
@@ -1,84 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- #
4
- # Unless explicitly stated otherwise all files in this repository are licensed
5
- # under the Apache License Version 2.0.
6
- #
7
- # This product includes software developed at Datadog (https://www.datadoghq.com/).
8
- # Copyright 2019 Datadog, Inc.
9
- #
10
-
11
- require 'aws-xray-sdk'
12
-
13
- module Datadog
14
- module Trace
15
- # Workaround to XRay not being supported in Lambda
16
- # https://github.com/aws/aws-xray-sdk-ruby/issues/20
17
- class LambdaStreamer < XRay::DefaultStreamer
18
- def initialize
19
- @stream_threshold = 1 # Stream every subsegment as it is available
20
- end
21
- end
22
-
23
- # LambdaEmitter filters out spans generated from the lambda daemon
24
- class LambdaEmitter < XRay::DefaultEmitter
25
- def should_send?(entity:)
26
- entity.name != '127.0.0.1' # Do not send localhost entities.
27
- end
28
-
29
- def send_entity(entity:)
30
- return nil unless should_send?(entity: entity)
31
-
32
- super
33
- end
34
- end
35
-
36
- # LambdaContext updated the trace id based on the curren trace header,
37
- # using a FacadeSegment
38
- class LambdaContext < XRay::DefaultContext
39
- def handle_context_missing
40
- nil
41
- end
42
-
43
- def check_context
44
- # Create a new FacadeSegment if the _X_AMZN_TRACE_ID changes.
45
- return if ENV['_X_AMZN_TRACE_ID'] == @current_trace_id
46
-
47
- # puts "XRAY: Starting new segment for #{ENV['_X_AMZN_TRACE_ID']}"
48
- @current_trace_id = ENV['_X_AMZN_TRACE_ID']
49
- trace_header = XRay::TraceHeader.from_header_string(
50
- header_str: @current_trace_id
51
- )
52
- segment = FacadeSegment.new(trace_id: trace_header.root,
53
- parent_id: trace_header.parent_id,
54
- id: trace_header.parent_id,
55
- name: 'lambda_context',
56
- sampled: trace_header.sampled)
57
- store_entity(entity: segment)
58
- end
59
-
60
- def current_entity
61
- # ensure the FacadeSegment is current whenever the current_entity is
62
- # retrieved
63
- check_context
64
- super
65
- end
66
- end
67
-
68
- # FacadeSegment is used to create a mock root span, that segments/
69
- # subsegments can be attached to. This span will never be submitted to the
70
- # X-Ray daemon
71
- class FacadeSegment < XRay::Segment
72
- def initialize(trace_id: nil, name: nil, parent_id: nil, id: nil,
73
- sampled: true)
74
- super(trace_id: trace_id, name: name, parent_id: parent_id)
75
- @id = id
76
- @sampled = sampled
77
- end
78
-
79
- def ready_to_send?
80
- false # never send this facade.
81
- end
82
- end
83
- end
84
- end