epsagon 0.0.20 → 0.0.25

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: 6064c0bad59a827b3521f5e26dabfad76f4e80ba729be380d96fd682a178fc6e
4
- data.tar.gz: d84a5475b4b0c81cb7f20fb9a8baeca13a1f83580affadc5932cc37023e82a6b
3
+ metadata.gz: e4dd6a90b916b237e688e45551af0324cebf6dc8288c5be00c2c360604748aa7
4
+ data.tar.gz: e70b552116e3a68515e6363352527ba0e1a438a1b8f26d9882358c61e7f2f5f7
5
5
  SHA512:
6
- metadata.gz: bbfa836f01e358d43452b1d2eb64c37870f50a6241d5e0748b965eb606ddb5c049e10b32e4467e04a9153227fdcf62ec57e19e2ee0005c3e632c31278fded005
7
- data.tar.gz: 1ba143caeb354cf9fc06d567d6f26ae27df6ef9ff01e820baf0ab8b677e992639ec13f56f04fa45a907c5d944d3eb8b9061436c8f819e7431a1240989c7d5afc
6
+ metadata.gz: '048ca5df1c956861b25634b497ceb8b1e6bcb45ff171a14e4c61bb1d1ea8731b5cf87237a158debe2ff146b81ba72445c1050bab2ba875596624cef82b1feec1'
7
+ data.tar.gz: 7474c11f77a5f24da6a23e7c825e1f4cf1e2ef0111cabd0ece1c68322a3e5cc8345e499618796f41de6484b2cdfb98c95abc7d1eeca3c13b2abb7a63d00a60b3
data/lib/epsagon.rb CHANGED
@@ -1,10 +1,11 @@
1
1
  # frozen_string_literal: true
2
-
2
+ require 'json'
3
3
  require 'rubygems'
4
4
  require 'net/http'
5
5
  require 'bundler/setup'
6
6
  require 'opentelemetry/sdk'
7
7
  require 'opentelemetry/exporter/otlp'
8
+ require 'opentelemetry/instrumentation/sidekiq'
8
9
 
9
10
  require_relative 'instrumentation/sinatra'
10
11
  require_relative 'instrumentation/net_http'
@@ -13,26 +14,29 @@ require_relative 'instrumentation/aws_sdk'
13
14
  require_relative 'instrumentation/rails'
14
15
  require_relative 'util'
15
16
  require_relative 'epsagon_constants'
17
+ require_relative 'exporter_extension'
16
18
 
17
19
  Bundler.require
18
20
 
19
21
  # Epsagon tracing main entry point
20
22
  module Epsagon
21
-
22
23
  DEFAULT_BACKEND = 'opentelemetry.tc.epsagon.com:443/traces'
24
+ DEFAULT_IGNORE_DOMAINS = ['newrelic.com']
23
25
 
24
- @@epsagon_config = {
25
- metadata_only: ENV['EPSAGON_METADATA']&.to_s&.downcase != 'false',
26
- debug: ENV['EPSAGON_DEBUG']&.to_s&.downcase == 'true',
27
- token: ENV['EPSAGON_TOKEN'],
28
- app_name: ENV['EPSAGON_APP_NAME'],
29
- max_attribute_size: ENV['EPSAGON_MAX_ATTRIBUTE_SIZE'] || 5000,
30
- backend: ENV['EPSAGON_BACKEND'] || DEFAULT_BACKEND
31
- }
26
+ @@epsagon_config = {}
32
27
 
33
28
  module_function
34
29
 
35
30
  def init(**args)
31
+ @@epsagon_config = {
32
+ metadata_only: ENV['EPSAGON_METADATA']&.to_s&.downcase != 'false',
33
+ debug: ENV['EPSAGON_DEBUG']&.to_s&.downcase == 'true',
34
+ token: ENV['EPSAGON_TOKEN'] || '',
35
+ app_name: ENV['EPSAGON_APP_NAME'] || '',
36
+ max_attribute_size: ENV['EPSAGON_MAX_ATTRIBUTE_SIZE'] || 5000,
37
+ backend: ENV['EPSAGON_BACKEND'] || DEFAULT_BACKEND,
38
+ ignore_domains: ENV['EPSAGON_IGNORE_DOMAINS'] || DEFAULT_IGNORE_DOMAINS
39
+ }
36
40
  @@epsagon_config.merge!(args)
37
41
  OpenTelemetry::SDK.configure
38
42
  end
@@ -45,9 +49,10 @@ module Epsagon
45
49
 
46
50
  def epsagon_confs(configurator)
47
51
  configurator.resource = OpenTelemetry::SDK::Resources::Resource.telemetry_sdk.merge(
48
- OpenTelemetry::SDK::Resources::Resource.create({
52
+ OpenTelemetry::SDK::Resources::Resource.create({
49
53
  'application' => @@epsagon_config[:app_name],
50
- 'epsagon.version' => EpsagonConstants::VERSION
54
+ 'epsagon.version' => EpsagonConstants::VERSION,
55
+ 'epsagon.metadata_only' => @@epsagon_config[:metadata_only]
51
56
  })
52
57
  )
53
58
  configurator.use 'EpsagonSinatraInstrumentation', { epsagon: @@epsagon_config }
@@ -55,8 +60,7 @@ module Epsagon
55
60
  configurator.use 'EpsagonFaradayInstrumentation', { epsagon: @@epsagon_config }
56
61
  configurator.use 'EpsagonAwsSdkInstrumentation', { epsagon: @@epsagon_config }
57
62
  configurator.use 'EpsagonRailsInstrumentation', { epsagon: @@epsagon_config }
58
- configurator.use 'OpenTelemetry::Instrumentation::Sidekiq'
59
-
63
+ configurator.use 'OpenTelemetry::Instrumentation::Sidekiq', { epsagon: @@epsagon_config }
60
64
 
61
65
  if @@epsagon_config[:debug]
62
66
  configurator.add_span_processor OpenTelemetry::SDK::Trace::Export::SimpleSpanProcessor.new(
@@ -97,15 +101,86 @@ module SpanExtension
97
101
  def initialize(*args)
98
102
  super(*args)
99
103
  if @attributes
100
- @attributes = Hash[@attributes.map { |k,v|
104
+ @attributes = Hash[@attributes.select {|k,v| not BLANKS.include? v}.map { |k,v|
101
105
  [k, Util.trim_attr(v, Epsagon.get_config[:max_attribute_size])]
102
106
  }]
103
107
  end
104
-
108
+ end
109
+ end
110
+
111
+ module SidekiqClientMiddlewareExtension
112
+
113
+ def call(_worker_class, job, _queue, _redis_pool)
114
+ config = OpenTelemetry::Instrumentation::Sidekiq::Instrumentation.instance.config[:epsagon] || {}
115
+ attributes = {
116
+ 'operation' => job['at'] ? 'perform_at' : 'perform_async',
117
+ 'messaging.system' => 'sidekiq',
118
+ 'messaging.sidekiq.job_class' => job['wrapped']&.to_s || job['class'],
119
+ 'messaging.message_id' => job['jid'],
120
+ 'messaging.destination' => job['queue'],
121
+ 'messaging.destination_kind' => 'queue',
122
+ 'messaging.sidekiq.redis_url' => Sidekiq.options['url'] || Util.redis_default_url
123
+ }
124
+ unless config[:metadata_only]
125
+ attributes.merge!({
126
+ 'messaging.sidekiq.args' => JSON.dump(job['args'])
127
+ })
128
+ end
129
+ tracer.in_span(
130
+ job['queue'],
131
+ attributes: attributes,
132
+ kind: :producer
133
+ ) do |span|
134
+ OpenTelemetry.propagation.text.inject(job)
135
+ span.add_event('created_at', timestamp: job['created_at'])
136
+ Util.untraced {yield}
137
+ end
138
+ end
139
+ end
140
+
141
+ module SidekiqServerMiddlewareExtension
142
+ def call(_worker, msg, _queue)
143
+ config = OpenTelemetry::Instrumentation::Sidekiq::Instrumentation.instance.config[:epsagon] || {}
144
+ parent_context = OpenTelemetry.propagation.text.extract(msg)
145
+ attributes = {
146
+ 'operation' => 'perform',
147
+ 'messaging.system' => 'sidekiq',
148
+ 'messaging.sidekiq.job_class' => msg['wrapped']&.to_s || msg['class'],
149
+ 'messaging.message_id' => msg['jid'],
150
+ 'messaging.destination' => msg['queue'],
151
+ 'messaging.destination_kind' => 'queue',
152
+ 'messaging.sidekiq.redis_url' => Sidekiq.options['url'] || Util.redis_default_url
153
+ }
154
+ runner_attributes = {
155
+ 'type' => 'sidekiq_worker',
156
+ 'messaging.sidekiq.redis_url' => Sidekiq.options['url'] || Util.redis_default_url,
157
+
158
+ }
159
+ unless config[:metadata_only]
160
+ attributes.merge!({
161
+ 'messaging.sidekiq.args' => JSON.dump(msg['args'])
162
+ })
163
+ end
164
+ tracer.in_span(
165
+ msg['queue'],
166
+ attributes: attributes,
167
+ with_parent: parent_context,
168
+ kind: :consumer
169
+ ) do |trigger_span|
170
+ trigger_span.add_event('created_at', timestamp: msg['created_at'])
171
+ trigger_span.add_event('enqueued_at', timestamp: msg['enqueued_at'])
172
+ tracer.in_span(msg['wrapped']&.to_s || msg['class'],
173
+ attributes: runner_attributes,
174
+ kind: :consumer
175
+ ) do |runner_span|
176
+ yield
177
+ end
178
+ end
105
179
  end
106
180
  end
107
181
 
108
182
  # monkey patch to include epsagon confs
183
+
109
184
  module OpenTelemetry
110
185
  # monkey patch inner SDK module
111
186
  module SDK
@@ -122,4 +197,35 @@ module OpenTelemetry
122
197
  end
123
198
  end
124
199
  end
200
+ module Instrumentation
201
+ module Sidekiq
202
+ class Instrumentation
203
+ def add_server_middleware
204
+ ::Sidekiq.configure_server do |config|
205
+ config.server_middleware do |chain|
206
+ chain.add Middlewares::Server::TracerMiddleware
207
+ end
208
+ end
209
+
210
+ if defined?(::Sidekiq::Testing) # rubocop:disable Style/GuardClause
211
+ ::Sidekiq::Testing.server_middleware do |chain|
212
+ chain.add Middlewares::Server::TracerMiddleware
213
+ end
214
+ end
215
+ end
216
+ end
217
+ module Middlewares
218
+ module Client
219
+ class TracerMiddleware
220
+ prepend SidekiqClientMiddlewareExtension
221
+ end
222
+ end
223
+ module Server
224
+ class TracerMiddleware
225
+ prepend SidekiqServerMiddlewareExtension
226
+ end
227
+ end
228
+ end
229
+ end
230
+ end
125
231
  end
@@ -1,3 +1,3 @@
1
1
  module EpsagonConstants
2
- VERSION = '0.0.17'
2
+ VERSION = '0.0.25'
3
3
  end
@@ -0,0 +1,78 @@
1
+
2
+
3
+ module OpenTelemetry
4
+ module Exporter
5
+ module OTLP
6
+ # An OpenTelemetry trace exporter that sends spans over HTTP as Protobuf encoded OTLP ExportTraceServiceRequests.
7
+ class Exporter # rubocop:disable Metrics/ClassLength
8
+ def send_bytes(bytes, timeout:) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
9
+ retry_count = 0
10
+ timeout ||= @timeout
11
+ start_time = Time.now
12
+ untraced do # rubocop:disable Metrics/BlockLength
13
+ request = Net::HTTP::Post.new(@path)
14
+ request.body = if @compression == 'gzip'
15
+ request.add_field('Content-Encoding', 'gzip')
16
+ Zlib.gzip(bytes)
17
+ else
18
+ bytes
19
+ end
20
+ request.add_field('Content-Type', 'application/x-protobuf')
21
+ @headers&.each { |key, value| request.add_field(key, value) }
22
+
23
+ remaining_timeout = OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time)
24
+ return TIMEOUT if remaining_timeout.zero?
25
+
26
+ @http.open_timeout = remaining_timeout
27
+ @http.read_timeout = remaining_timeout
28
+ @http.write_timeout = remaining_timeout if WRITE_TIMEOUT_SUPPORTED
29
+ @http.start unless @http.started?
30
+ response = measure_request_duration { @http.request(request) }
31
+
32
+ case response
33
+ when Net::HTTPOK
34
+ response.body # Read and discard body
35
+ SUCCESS
36
+ when Net::HTTPServiceUnavailable, Net::HTTPTooManyRequests
37
+ response.body # Read and discard body
38
+ redo if backoff?(retry_after: response['Retry-After'], retry_count: retry_count += 1, reason: response.code)
39
+ FAILURE
40
+ when Net::HTTPRequestTimeOut, Net::HTTPGatewayTimeOut, Net::HTTPBadGateway
41
+ response.body # Read and discard body
42
+ redo if backoff?(retry_count: retry_count += 1, reason: response.code)
43
+ FAILURE
44
+ when Net::HTTPBadRequest, Net::HTTPClientError, Net::HTTPServerError
45
+ # TODO: decode the body as a google.rpc.Status Protobuf-encoded message when https://github.com/open-telemetry/opentelemetry-collector/issues/1357 is fixed.
46
+ response.body # Read and discard body
47
+ FAILURE
48
+ when Net::HTTPRedirection
49
+ @http.finish
50
+ handle_redirect(response['location'])
51
+ redo if backoff?(retry_after: 0, retry_count: retry_count += 1, reason: response.code)
52
+ else
53
+ @http.finish
54
+ FAILURE
55
+ end
56
+ rescue Net::OpenTimeout, Net::ReadTimeout
57
+ puts "Epsagon: timeout while sending trace" if Epsagon.get_config[:debug]
58
+ retry if backoff?(retry_count: retry_count += 1, reason: 'timeout')
59
+ return FAILURE
60
+ ensure
61
+ if Epsagon.get_config[:debug] && response && response.code.to_i >= 400
62
+ puts "Epsagon: Error while sending trace:"
63
+ puts "#{response.code} #{response.class.name} #{response.message}"
64
+ puts "Headers: #{response.to_hash.inspect}"
65
+ puts response.body
66
+ end
67
+ end
68
+ ensure
69
+ # Reset timeouts to defaults for the next call.
70
+ @http.open_timeout = @timeout
71
+ @http.read_timeout = @timeout
72
+ @http.write_timeout = @timeout if WRITE_TIMEOUT_SUPPORTED
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+
@@ -4,6 +4,7 @@ require 'aws-sdk-core'
4
4
  require 'opentelemetry/common'
5
5
  require 'opentelemetry/sdk'
6
6
 
7
+
7
8
  def untraced(&block)
8
9
  OpenTelemetry::Trace.with_span(OpenTelemetry::Trace::Span.new, &block)
9
10
  end
@@ -17,14 +18,120 @@ end
17
18
 
18
19
  # Generates Spans for all uses of AWS SDK
19
20
  class EpsagonAwsHandler < Seahorse::Client::Handler
21
+ SPAN_KIND = {
22
+ 'ReceiveMessage' => :consumer,
23
+ 'SendMessage' => :producer,
24
+ 'SendMessageBatch' => :producer,
25
+ 'Publish' => :producer,
26
+ }
27
+
20
28
  def call(context)
21
- tracer.in_span('', kind: :client) do |span|
29
+ span_name = ''
30
+ span_kind = :client
31
+ attributes = {
32
+ 'aws.service' => context.client.class.to_s.split('::')[1].downcase,
33
+ 'aws.operation' => context.operation.name
34
+ }
35
+ attributes['aws.region'] = context.client.config.region unless attributes['aws.service'] == 's3'
36
+
37
+ span_kind = SPAN_KIND[attributes['aws.operation']] || span_kind
38
+ if attributes['aws.service'] == 's3'
39
+ attributes['aws.s3.bucket'] = context.params[:bucket]
40
+ span_name = attributes['aws.s3.bucket'] if attributes['aws.s3.bucket']
41
+ attributes['aws.s3.key'] = context.params[:key]
42
+ attributes['aws.s3.copy_source'] = context.params[:copy_source]
43
+ elsif attributes['aws.service'] == 'sqs'
44
+ queue_url = context.params[:queue_url]
45
+ queue_name = queue_url ? queue_url[queue_url.rindex('/')+1..-1] : context.params[:queue_name]
46
+ attributes['aws.sqs.max_number_of_messages'] = context.params[:max_number_of_messages]
47
+ attributes['aws.sqs.wait_time_seconds'] = context.params[:wait_time_seconds]
48
+ attributes['aws.sqs.visibility_timeout'] = context.params[:visibility_timeout]
49
+ attributes['aws.sqs.message_id'] = context.params[:message_id]
50
+ if queue_name
51
+ attributes['aws.sqs.queue_name'] = queue_name
52
+ span_name = attributes['aws.sqs.queue_name'] if attributes['aws.sqs.queue_name']
53
+ end
54
+ unless config[:epsagon][:metadata_only]
55
+ if attributes['aws.operation'] == 'SendMessageBatch'
56
+ messages_attributes = context.params[:entries].map do |m|
57
+ record = {
58
+ 'message_attributes' => m[:message_attributes].map {|k,v| [k, v.to_h]},
59
+ 'message_body' => m[:message_body],
60
+ }
61
+ end
62
+ attributes['aws.sqs.record'] = JSON.dump(messages_attributes) if messages_attributes
63
+ end
64
+ attributes['aws.sqs.record.message_body'] = context.params[:message_body]
65
+ attributes['aws.sqs.record.message_attributes'] = JSON.dump(context.params[:message_attributes]) if context.params[:message_attributes]
66
+ end
67
+ elsif attributes['aws.service'] == 'sns'
68
+ topic_arn = context.params[:topic_arn]
69
+ topic_name = topic_arn ? topic_arn[topic_arn.rindex(':')+1..-1] : context.params[:name]
70
+ span_name = attributes['aws.sns.topic_name'] = topic_name if topic_name
71
+ unless config[:epsagon][:metadata_only]
72
+ attributes['aws.sns.subject'] = context.params[:subject]
73
+ attributes['aws.sns.message'] = context.params[:message]
74
+ attributes['aws.sns.message_attributes'] = JSON.dump(context.params[:message_attributes]) if context.params[:message_attributes]
75
+ end
76
+ end
77
+ tracer.in_span(span_name, kind: span_kind, attributes: attributes) do |span|
22
78
  untraced do
23
- @handler.call(context).tap do
24
- span.set_attribute('aws.service', context.client.class.to_s.split('::')[1].downcase)
25
- span.set_attribute('aws.operation', context.operation.name)
26
- span.set_attribute('aws.region', context.client.config.region)
79
+ @handler.call(context).tap do |result|
80
+ if attributes['aws.service'] == 's3'
81
+ modified = context.http_response.headers[:'last-modified']
82
+ reformatted_modified = modified ?
83
+ Time.strptime(modified, '%a, %d %b %Y %H:%M:%S %Z')
84
+ .strftime('%Y-%m-%dT%H:%M:%SZ') :
85
+ nil
86
+ if context.operation.name == 'GetObject'
87
+ span.set_attribute('aws.s3.content_length', context.http_response.headers[:'content-length']&.to_i)
88
+ end
89
+ span.set_attribute('aws.s3.etag', context.http_response.headers[:etag]&.tr('"',''))
90
+ span.set_attribute('aws.s3.last_modified', reformatted_modified)
91
+ elsif attributes['aws.service'] == 'sqs'
92
+ if context.operation.name == 'SendMessage'
93
+ span.set_attribute('aws.sqs.record.message_id', result.message_id)
94
+ end
95
+ if context.operation.name == 'SendMessageBatch'
96
+ messages_attributes = result.successful.map do |m|
97
+ record = {'message_id' => m.message_id}
98
+ unless config[:epsagon][:metadata_only]
99
+ context.params[:entries].each do |e|
100
+ record.merge!({
101
+ 'message_attributes' => e[:message_attributes].map {|k,v| [k, v.to_h]},
102
+ 'message_body' => e[:message_body],
103
+ }) if e[:id] == m.id
104
+ end
105
+ end
106
+ record
107
+ end
108
+ span.set_attribute('aws.sqs.record', JSON.dump(messages_attributes)) if messages_attributes
109
+ end
110
+ if context.operation.name == 'ReceiveMessage'
111
+ messages_attributes = result.messages.map do |m|
112
+ record = {
113
+ 'message_id' => m.message_id,
114
+ 'attributes' => {
115
+ 'sender_id' => m.attributes['SenderId'],
116
+ 'sent_timestamp' => m.attributes['SentTimestamp'],
117
+ 'aws_trace_header' => m.attributes['AWSTraceHeader'],
118
+ }
119
+ }
120
+ unless config[:epsagon][:metadata_only]
121
+ record['message_attributes'] = m.message_attributes.map {|k,v| [k, v.to_h]}
122
+ record['message_body'] = m.body
123
+ end
124
+ record
125
+ end
126
+ span.set_attribute('aws.sqs.record', JSON.dump(messages_attributes)) if messages_attributes
127
+ end
128
+ elsif attributes['aws.service'] == 'sns'
129
+ span.set_attribute('aws.sns.message_id', result.message_id) if context.operation.name == 'Publish'
130
+ end
27
131
  span.set_attribute('http.status_code', context.http_response.status_code)
132
+ span.status = OpenTelemetry::Trace::Status.http_to_status(
133
+ context.http_response.status_code
134
+ )
28
135
  end
29
136
  end
30
137
  end
@@ -33,4 +140,8 @@ class EpsagonAwsHandler < Seahorse::Client::Handler
33
140
  def tracer
34
141
  EpsagonAwsSdkInstrumentation.instance.tracer()
35
142
  end
143
+
144
+ def config
145
+ EpsagonAwsSdkInstrumentation.instance.config
146
+ end
36
147
  end
@@ -37,11 +37,11 @@ class EpsagonFaradayMiddleware < ::Faraday::Middleware
37
37
  unless config[:epsagon][:metadata_only]
38
38
  attributes.merge!(Util.epsagon_query_attributes(env.url.query))
39
39
  attributes.merge!({
40
- 'http.request.path_params' => path_params,
41
- 'http.request.headers' => env.request_headers.to_json,
42
- 'http.request.body' => env.body,
43
- 'http.request.headers.User-Agent' => env.request_headers['User-Agent']
44
- })
40
+ 'http.request.path_params' => path_params,
41
+ 'http.request.headers' => env.request_headers.to_json,
42
+ 'http.request.body' => env.body,
43
+ 'http.request.headers.User-Agent' => env.request_headers['User-Agent']
44
+ })
45
45
  end
46
46
 
47
47
  tracer.in_span(
@@ -130,7 +130,7 @@ class EpsagonRackMiddleware
130
130
  def request_span_attributes(env:)
131
131
  request = Rack::Request.new(env)
132
132
  path, path_params = request.path.split(';')
133
- request_headers = JSON.generate(Hash[*env.select { |k, _v| k.start_with? 'HTTP_' }
133
+ request_headers = JSON.generate(Hash[*env.select { |k, _v| k.to_s.start_with? 'HTTP_' }
134
134
  .collect { |k, v| [k.sub(/^HTTP_/, ''), v] }
135
135
  .collect { |k, v| [k.split('_').collect(&:capitalize).join('-'), v] }
136
136
  .sort
@@ -17,6 +17,7 @@ module EpsagonNetHTTPExtension
17
17
  def request(req, body = nil, &block)
18
18
  # Do not trace recursive call for starting the connection
19
19
  return super(req, body, &block) unless started?
20
+ return super(req, body, &block) if config[:epsagon][:ignore_domains].any? {|d| @address.include? d}
20
21
 
21
22
  attributes = Hash[OpenTelemetry::Common::HTTP::ClientContext.attributes]
22
23
  path_with_params, query = req.path.split('?')
@@ -55,6 +56,7 @@ module EpsagonNetHTTPExtension
55
56
 
56
57
  def annotate_span_with_response!(span, response)
57
58
  return unless response&.code
59
+ return unless span.respond_to?(:set_attribute)
58
60
 
59
61
  status_code = response.code.to_i
60
62
 
data/lib/util.rb CHANGED
@@ -30,4 +30,13 @@ module Util
30
30
  value
31
31
  end
32
32
  end
33
+
34
+ def self.redis_default_url
35
+ @@redis_default_url ||= "#{Redis::Client::DEFAULTS[:scheme]}://#{Redis::Client::DEFAULTS[:host]}:#{Redis::Client::DEFAULTS[:port]}/#{Redis::Client::DEFAULTS[:db]}"
36
+ end
37
+
38
+ def self.untraced(&block)
39
+ OpenTelemetry::Trace.with_span(OpenTelemetry::Trace::Span.new, &block)
40
+ end
41
+
33
42
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: epsagon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.20
4
+ version: 0.0.25
5
5
  platform: ruby
6
6
  authors:
7
7
  - Epsagon
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-29 00:00:00.000000000 Z
11
+ date: 2021-06-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: opentelemetry-api
@@ -92,6 +92,7 @@ extra_rdoc_files: []
92
92
  files:
93
93
  - lib/epsagon.rb
94
94
  - lib/epsagon_constants.rb
95
+ - lib/exporter_extension.rb
95
96
  - lib/instrumentation/aws_sdk.rb
96
97
  - lib/instrumentation/aws_sdk_plugin.rb
97
98
  - lib/instrumentation/epsagon_faraday_middleware.rb