epsagon 0.0.10 → 0.0.15

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: dcd34d0e419fb2fcbc2ffa3d2b7a90c5d7ca801934050d2a1dbce6c6060cdd1b
4
- data.tar.gz: 0fdb70755b5db1bd8fc965fd47d1f8d8d0ac28d8e131ab7f768311d33c44ae71
3
+ metadata.gz: 98d6993dedabe8fbc959569568d7c2ba3275f9b474bb7846df066b6d406ceb58
4
+ data.tar.gz: bd37e34d099293df8f9fa07189a40c1c6d3e10d58adb45298fc0bb55524c0017
5
5
  SHA512:
6
- metadata.gz: b868ea0d2887c31e1781ebbe31c6a5f04fb2fdafa1ecfc897142555f2191b8f9b606d50a249a025fd141c8e606c521c0030e5f33de139825066fb925dce19619
7
- data.tar.gz: 7c376ffa54f29a2186a0b9acf456250738d9d7ea8d1f6a26d673d40118d0210999c500ac58a326593cc32429461bae7e15b98a9856b8dd1cc6675490c9e04a25
6
+ metadata.gz: 6dc01e0e49dcf9e2d211ce8b0c2d48e6b74cadf5063f0e06119f3593092414f22572f836ec28980c8d4174c57e37f83a6722b0ffbc534e6bb27764c173c50ac6
7
+ data.tar.gz: 0ce2dc315d5a5b2d6ccbfeba4379874d7fd9c31d9dadde2b1954bf4efe8d8c2f495dec0041814516dd7f04f4c0f3aa2c944ecd87a55d0d8cd34e3578c119a945
data/lib/epsagon.rb CHANGED
@@ -10,19 +10,22 @@ require_relative 'instrumentation/sinatra'
10
10
  require_relative 'instrumentation/net_http'
11
11
  require_relative 'instrumentation/faraday'
12
12
  require_relative 'instrumentation/aws_sdk'
13
+ require_relative 'instrumentation/rails'
13
14
  require_relative 'util'
14
15
 
15
16
  Bundler.require
16
17
 
17
18
  # Epsagon tracing main entry point
18
19
  module Epsagon
20
+ DEFAULT_BACKEND = 'opentelemetry.tc.epsagon.com:443/traces'
21
+
19
22
  @@epsagon_config = {
20
- metadata_only: ENV['EPSAGON_METADATA']&.to_s&.downcase != 'false',
21
- debug: ENV['EPSAGON_DEBUG']&.to_s&.downcase == 'true',
22
- token: ENV['EPSAGON_TOKEN'],
23
- app_name: ENV['EPSAGON_APP_NAME'],
24
- backend: ENV['EPSAGON_BACKEND'] || 'localhost:55681/v1/trace'
25
- }
23
+ metadata_only: ENV['EPSAGON_METADATA']&.to_s&.downcase != 'false',
24
+ debug: ENV['EPSAGON_DEBUG']&.to_s&.downcase == 'true',
25
+ token: ENV['EPSAGON_TOKEN'],
26
+ app_name: ENV['EPSAGON_APP_NAME'],
27
+ backend: ENV['EPSAGON_BACKEND'] || DEFAULT_BACKEND
28
+ }
26
29
 
27
30
  module_function
28
31
 
@@ -41,30 +44,30 @@ module Epsagon
41
44
  configurator.use 'EpsagonNetHTTPInstrumentation', { epsagon: @@epsagon_config }
42
45
  configurator.use 'EpsagonFaradayInstrumentation', { epsagon: @@epsagon_config }
43
46
  configurator.use 'EpsagonAwsSdkInstrumentation', { epsagon: @@epsagon_config }
47
+ configurator.use 'EpsagonRailsInstrumentation', { epsagon: @@epsagon_config }
44
48
 
45
49
  if @@epsagon_config[:debug]
46
50
  configurator.add_span_processor OpenTelemetry::SDK::Trace::Export::SimpleSpanProcessor.new(
47
51
  OpenTelemetry::Exporter::OTLP::Exporter.new(headers: {
48
- 'x-epsagon-token' => @@epsagon_config[:token]
49
- },
50
- endpoint: @@epsagon_config[:backend],
51
- insecure: @@epsagon_config[:insecure] || false)
52
+ 'x-epsagon-token' => @@epsagon_config[:token]
53
+ },
54
+ endpoint: @@epsagon_config[:backend],
55
+ insecure: @@epsagon_config[:insecure] || false)
52
56
  )
53
57
 
54
58
  configurator.add_span_processor OpenTelemetry::SDK::Trace::Export::SimpleSpanProcessor.new(
55
59
  OpenTelemetry::SDK::Trace::Export::ConsoleSpanExporter.new
56
60
  )
57
61
  else
58
- configurator.add_span_processor OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new(
59
- exporter: OpenTelemetry::Exporter::OTLP::Exporter.new(headers: {
60
- 'x-epsagon-token' => @@epsagon_config[:token]
61
- },
62
- endpoint: @@epsagon_config[:backend],
63
- insecure: @@epsagon_config[:insecure] || false)
62
+ configurator.add_span_processor OpenTelemetry::SDK::Trace::Export::SimpleSpanProcessor.new(
63
+ OpenTelemetry::Exporter::OTLP::Exporter.new(headers: {
64
+ 'x-epsagon-token' => @@epsagon_config[:token]
65
+ },
66
+ endpoint: @@epsagon_config[:backend],
67
+ insecure: @@epsagon_config[:insecure] || false)
64
68
  )
65
69
  end
66
70
  end
67
-
68
71
  end
69
72
 
70
73
  # monkey patch to include epsagon confs
@@ -1,4 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'aws-sdk-core'
4
+ require 'opentelemetry/common'
5
+ require 'opentelemetry/sdk'
6
+
7
+ def untraced(&block)
8
+ OpenTelemetry::Trace.with_span(OpenTelemetry::Trace::Span.new, &block)
9
+ end
2
10
 
3
11
  # AWS SDK plugin for epsagon instrumentation
4
12
  class EpsagonAwsPlugin < Seahorse::Client::Plugin
@@ -10,12 +18,14 @@ end
10
18
  # Generates Spans for all uses of AWS SDK
11
19
  class EpsagonAwsHandler < Seahorse::Client::Handler
12
20
  def call(context)
13
- tracer.in_span('') do |span|
14
- @handler.call(context).tap do
15
- span.set_attribute('aws.service', context.client.class.to_s.split('::')[1].downcase)
16
- span.set_attribute('aws.aws.operation', context.operation.name)
17
- span.set_attribute('aws.region', context.client.config.region)
18
- span.set_attribute('aws.status_code', context.http_response.status_code)
21
+ tracer.in_span('', kind: :client) do |span|
22
+ 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)
27
+ span.set_attribute('http.status_code', context.http_response.status_code)
28
+ end
19
29
  end
20
30
  end
21
31
  end
@@ -23,4 +33,4 @@ class EpsagonAwsHandler < Seahorse::Client::Handler
23
33
  def tracer
24
34
  EpsagonAwsSdkInstrumentation.instance.tracer
25
35
  end
26
- end
36
+ end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  require_relative '../util'
3
4
  require 'faraday'
@@ -0,0 +1,286 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'opentelemetry/trace/status'
4
+
5
+ module QueueTime
6
+ REQUEST_START = 'HTTP_X_REQUEST_START'
7
+ QUEUE_START = 'HTTP_X_QUEUE_START'
8
+ MINIMUM_ACCEPTABLE_TIME_VALUE = 1_000_000_000
9
+
10
+ module_function
11
+
12
+ def get_request_start(env, now = nil) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
13
+ header = env[REQUEST_START] || env[QUEUE_START]
14
+ return unless header
15
+
16
+ # nginx header is seconds in the format "t=1512379167.574"
17
+ # apache header is microseconds in the format "t=1570633834463123"
18
+ # heroku header is milliseconds in the format "1570634024294"
19
+ time_string = header.to_s.delete('^0-9')
20
+ return if time_string.nil?
21
+
22
+ # Return nil if the time is clearly invalid
23
+ time_value = "#{time_string[0, 10]}.#{time_string[10, 6]}".to_f
24
+ return if time_value.zero? || time_value < MINIMUM_ACCEPTABLE_TIME_VALUE
25
+
26
+ # return the request_start only if it's lesser than
27
+ # current time, to avoid significant clock skew
28
+ request_start = Time.at(time_value)
29
+ now ||= Time.now.utc
30
+ request_start.utc > now ? nil : request_start
31
+ rescue StandardError => e
32
+ # in case of an Exception we don't create a
33
+ # `request.queuing` span
34
+ OpenTelemetry.logger.debug("[rack] unable to parse request queue headers: #{e}")
35
+ nil
36
+ end
37
+ end
38
+
39
+ class EpsagonRackMiddleware
40
+ class << self
41
+ def allowed_rack_request_headers
42
+ @allowed_rack_request_headers ||= Array(config[:allowed_request_headers]).each_with_object({}) do |header, memo|
43
+ memo["HTTP_#{header.to_s.upcase.gsub(/[-\s]/, '_')}"] = build_attribute_name('http.request.headers.', header)
44
+ end
45
+ end
46
+
47
+ def allowed_response_headers
48
+ @allowed_response_headers ||= Array(config[:allowed_response_headers]).each_with_object({}) do |header, memo|
49
+ memo[header] = build_attribute_name('http.response.headers.', header)
50
+ memo[header.to_s.upcase] = build_attribute_name('http.response.headers.', header)
51
+ end
52
+ end
53
+
54
+ def build_attribute_name(prefix, suffix)
55
+ prefix + suffix.to_s.downcase.gsub(/[-\s]/, '_')
56
+ end
57
+
58
+ def config
59
+ EpsagonRailsInstrumentation.instance.config
60
+ end
61
+
62
+ private
63
+
64
+ def clear_cached_config
65
+ @allowed_rack_request_headers = nil
66
+ @allowed_response_headers = nil
67
+ end
68
+ end
69
+
70
+ EMPTY_HASH = {}.freeze
71
+
72
+ def initialize(app)
73
+ @app = app
74
+ end
75
+
76
+ def call(env)
77
+ original_env = env.dup
78
+ extracted_context = OpenTelemetry.propagation.http.extract(env)
79
+ frontend_context = create_frontend_span(env, extracted_context)
80
+
81
+ # restore extracted context in this process:
82
+ OpenTelemetry::Context.with_current(frontend_context || extracted_context) do
83
+ request_span_name = create_request_span_name(env['REQUEST_URI'] || original_env['PATH_INFO'])
84
+ tracer.in_span(env['HTTP_HOST'] || 'unknown',
85
+ attributes: request_span_attributes(env: env),
86
+ kind: :server) do |http_span|
87
+ RackExtension.with_span(http_span) do
88
+ tracer.in_span(
89
+ env['HTTP_HOST'],
90
+ kind: :server,
91
+ attributes: {type: 'rails'}
92
+ ) do |framework_span|
93
+ @app.call(env).tap do |status, headers, response|
94
+ set_attributes_after_request(http_span, framework_span, status, headers, response)
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ ensure
101
+ finish_span(frontend_context)
102
+ end
103
+
104
+ private
105
+
106
+ # return Context with the frontend span as the current span
107
+ def create_frontend_span(env, extracted_context)
108
+ request_start_time = QueueTime.get_request_start(env)
109
+
110
+ return unless config[:record_frontend_span] && !request_start_time.nil?
111
+
112
+ span = tracer.start_span('http_server.proxy',
113
+ with_parent: extracted_context,
114
+ attributes: {
115
+ 'start_time' => request_start_time.to_f
116
+ },
117
+ kind: :server)
118
+
119
+ OpenTelemetry::Trace.context_with_span(span, parent_context: extracted_context)
120
+ end
121
+
122
+ def finish_span(context)
123
+ OpenTelemetry::Trace.current_span(context).finish if context
124
+ end
125
+
126
+ def tracer
127
+ EpsagonRailsInstrumentation.instance.tracer
128
+ end
129
+
130
+ def request_span_attributes(env:)
131
+ request = Rack::Request.new(env)
132
+ path, path_params = request.path.split(';')
133
+ request_headers = JSON.generate(Hash[*env.select { |k, _v| k.start_with? 'HTTP_' }
134
+ .collect { |k, v| [k.sub(/^HTTP_/, ''), v] }
135
+ .collect { |k, v| [k.split('_').collect(&:capitalize).join('-'), v] }
136
+ .sort
137
+ .flatten])
138
+
139
+ attributes = {
140
+ 'operation' => env['REQUEST_METHOD'],
141
+ 'type' => 'http',
142
+ 'http.scheme' => env['rack.url_scheme'],
143
+ 'http.request.path' => path,
144
+ 'http.request.headers' => request_headers
145
+ }
146
+
147
+ unless config[:epsagon][:metadata_only]
148
+ request.body.rewind
149
+ request_body = request.body.read
150
+ request.body.rewind
151
+
152
+ attributes.merge!(Util.epsagon_query_attributes(request.query_string))
153
+
154
+ attributes.merge!({
155
+ 'http.request.body' => request_body,
156
+ 'http.request.path_params' => path_params,
157
+ 'http.request.headers.User-Agent' => env['HTTP_USER_AGENT']
158
+ })
159
+ end
160
+
161
+ attributes
162
+ end
163
+
164
+ # e.g., "/webshop/articles/4?s=1":
165
+ def fullpath(env)
166
+ query_string = env['QUERY_STRING']
167
+ path = env['SCRIPT_NAME'] + env['PATH_INFO']
168
+
169
+ query_string.empty? ? path : "#{path}?#{query_string}"
170
+ end
171
+
172
+ # https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/data-http.md#name
173
+ #
174
+ # recommendation: span.name(s) should be low-cardinality (e.g.,
175
+ # strip off query param value, keep param name)
176
+ #
177
+ # see http://github.com/open-telemetry/opentelemetry-specification/pull/416/files
178
+ def create_request_span_name(request_uri_or_path_info)
179
+ # NOTE: dd-trace-rb has implemented 'quantization' (which lowers url cardinality)
180
+ # see Datadog::Quantization::HTTP.url
181
+
182
+ if (implementation = config[:url_quantization])
183
+ implementation.call(request_uri_or_path_info)
184
+ else
185
+ request_uri_or_path_info
186
+ end
187
+ end
188
+
189
+ def set_attributes_after_request(http_span, _framework_span, status, headers, response)
190
+ unless config[:epsagon][:metadata_only]
191
+ http_span.set_attribute('http.response.headers', JSON.generate(headers))
192
+ http_span.set_attribute('http.response.body', response.join)
193
+ end
194
+
195
+ http_span.set_attribute('http.status_code', status)
196
+ http_span.status = OpenTelemetry::Trace::Status.http_to_status(status)
197
+ end
198
+
199
+ def allowed_request_headers(env)
200
+ return EMPTY_HASH if self.class.allowed_rack_request_headers.empty?
201
+
202
+ {}.tap do |result|
203
+ self.class.allowed_rack_request_headers.each do |key, value|
204
+ result[value] = env[key] if env.key?(key)
205
+ end
206
+ end
207
+ end
208
+
209
+ def allowed_response_headers(headers)
210
+ return EMPTY_HASH if headers.nil?
211
+ return EMPTY_HASH if self.class.allowed_response_headers.empty?
212
+
213
+ {}.tap do |result|
214
+ self.class.allowed_response_headers.each do |key, value|
215
+ if headers.key?(key)
216
+ result[value] = headers[key]
217
+ else
218
+ # do case-insensitive match:
219
+ headers.each do |k, v|
220
+ if k.upcase == key
221
+ result[value] = v
222
+ break
223
+ end
224
+ end
225
+ end
226
+ end
227
+ end
228
+ end
229
+
230
+ def config
231
+ EpsagonRailsInstrumentation.instance.config
232
+ end
233
+ end
234
+
235
+ # class EpsagonRackInstrumentation < OpenTelemetry::Instrumentation::Base
236
+ # install do |config|
237
+ # require_dependencies
238
+
239
+ # retain_middleware_names if config[:retain_middleware_names]
240
+ # end
241
+
242
+ # present do
243
+ # defined?(::Rack)
244
+ # end
245
+
246
+ # private
247
+
248
+ # def require_dependencies
249
+ # require_relative 'middlewares/tracer_middleware'
250
+ # end
251
+
252
+ # MissingApplicationError = Class.new(StandardError)
253
+
254
+ # # intercept all middleware-compatible calls, retain class name
255
+ # def retain_middleware_names
256
+ # next_middleware = config[:application]
257
+ # raise MissingApplicationError unless next_middleware
258
+
259
+ # while next_middleware
260
+ # if next_middleware.respond_to?(:call)
261
+ # next_middleware.singleton_class.class_eval do
262
+ # alias_method :__call, :call
263
+
264
+ # def call(env)
265
+ # env['RESPONSE_MIDDLEWARE'] = self.class.to_s
266
+ # __call(env)
267
+ # end
268
+ # end
269
+ # end
270
+
271
+ # next_middleware = next_middleware.instance_variable_defined?('@app') &&
272
+ # next_middleware.instance_variable_get('@app')
273
+ # end
274
+ # end
275
+ # end
276
+
277
+ class EpsagonRailtie < ::Rails::Railtie
278
+ config.before_initialize do |app|
279
+ # EpsagonRackInstrumentation.instance.install({})
280
+
281
+ app.middleware.insert_after(
282
+ ActionDispatch::RequestId,
283
+ EpsagonRackMiddleware
284
+ )
285
+ end
286
+ end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Patch faraday to include middleware
3
4
  module EpsagonFaradayPatch
4
5
  def adapter(*args)
@@ -40,7 +40,7 @@ module EpsagonNetHTTPExtension
40
40
  tracer.in_span(
41
41
  @address,
42
42
  attributes: attributes,
43
- kind: :Client
43
+ kind: :client
44
44
  ) do |span|
45
45
  OpenTelemetry.propagation.http.inject(req)
46
46
 
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'opentelemetry'
4
+ require 'rails'
5
+ require 'action_controller/railtie'
6
+
7
+ require_relative '../util'
8
+
9
+ module RackExtension
10
+ module_function
11
+
12
+ CURRENT_SPAN_KEY = OpenTelemetry::Context.create_key('current-span')
13
+
14
+ private_constant :CURRENT_SPAN_KEY
15
+
16
+ # Returns the current span from the current or provided context
17
+ #
18
+ # @param [optional Context] context The context to lookup the current
19
+ # {Span} from. Defaults to Context.current
20
+ def current_span(context = nil)
21
+ context ||= OpenTelemetry::Context.current
22
+ context.value(CURRENT_SPAN_KEY) || OpenTelemetry::Trace::Span::INVALID
23
+ end
24
+
25
+ # Returns a context containing the span, derived from the optional parent
26
+ # context, or the current context if one was not provided.
27
+ #
28
+ # @param [optional Context] context The context to use as the parent for
29
+ # the returned context
30
+ def context_with_span(span, parent_context: OpenTelemetry::Context.current)
31
+ parent_context.set_value(CURRENT_SPAN_KEY, span)
32
+ end
33
+
34
+ # Activates/deactivates the Span within the current Context, which makes the "current span"
35
+ # available implicitly.
36
+ #
37
+ # On exit, the Span that was active before calling this method will be reactivated.
38
+ #
39
+ # @param [Span] span the span to activate
40
+ # @yield [span, context] yields span and a context containing the span to the block.
41
+ def with_span(span)
42
+ OpenTelemetry::Context.with_value(CURRENT_SPAN_KEY, span) { |c, s| yield s, c }
43
+ end
44
+ end
45
+
46
+ module MetalPatch
47
+ def dispatch(name, request, response)
48
+ rack_span = RackExtension.current_span
49
+ # rack_span.name = "#{self.class.name}##{name}" if rack_span.context.valid? && !request.env['action_dispatch.exception']
50
+ super(name, request, response)
51
+ end
52
+ end
53
+
54
+ class EpsagonRailsInstrumentation < OpenTelemetry::Instrumentation::Base
55
+ install do |_config|
56
+ require_relative 'epsagon_rails_middleware'
57
+ ::ActionController::Metal.prepend(MetalPatch)
58
+ end
59
+
60
+ present do
61
+ defined?(::Rails)
62
+ end
63
+ end
@@ -26,7 +26,7 @@ class EpsagonTracerMiddleware
26
26
  attributes = {
27
27
  'operation' => env['REQUEST_METHOD'],
28
28
  'type' => 'http',
29
- 'http.scheme' => env['PATH_INFO'],
29
+ 'http.scheme' => env['rack.url_scheme'],
30
30
  'http.request.path' => path,
31
31
  'http.request.headers' => request_headers
32
32
  }
@@ -48,10 +48,14 @@ class EpsagonTracerMiddleware
48
48
  tracer.in_span(
49
49
  env['HTTP_HOST'],
50
50
  attributes: attributes,
51
- kind: :Server,
51
+ kind: :server,
52
52
  with_parent: parent_context(env)
53
53
  ) do |http_span|
54
- tracer.in_span('sinatra') do |framework_span|
54
+ tracer.in_span(
55
+ env['HTTP_HOST'],
56
+ kind: :server,
57
+ attributes: { type: 'sinatra' }
58
+ ) do |framework_span|
55
59
  app.call(env).tap { |resp| trace_response(http_span, framework_span, env, resp) }
56
60
  end
57
61
  end
@@ -78,7 +82,7 @@ class EpsagonTracerMiddleware
78
82
  end
79
83
 
80
84
  http_span.set_attribute('http.status_code', status)
81
- framework_span.set_attribute('http.route', env['sinatra.route'].split.last) if env['sinatra.route']
85
+ http_span.set_attribute('http.route', env['sinatra.route'].split.last) if env['sinatra.route']
82
86
  http_span.status = OpenTelemetry::Trace::Status.http_to_status(status)
83
87
  end
84
88
  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.10
4
+ version: 0.0.15
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-11 00:00:00.000000000 Z
11
+ date: 2021-04-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: opentelemetry-api
@@ -25,19 +25,19 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.11.0
27
27
  - !ruby/object:Gem::Dependency
28
- name: opentelemetry-sdk
28
+ name: opentelemetry-exporter-otlp
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.11.1
33
+ version: 0.11.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.11.1
40
+ version: 0.11.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: opentelemetry-instrumentation-sinatra
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -53,19 +53,19 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: 0.11.0
55
55
  - !ruby/object:Gem::Dependency
56
- name: opentelemetry-exporter-otlp
56
+ name: opentelemetry-sdk
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.11.0
61
+ version: 0.11.1
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 0.11.0
68
+ version: 0.11.1
69
69
  description: 'Epsagon provides tracing to Ruby applications for the collection of
70
70
  distributed tracing and performance metrics to simplify complex architectures, eliminate
71
71
  manual work, visualize and correlate data to identify and fix problems fast.
@@ -80,8 +80,10 @@ files:
80
80
  - lib/instrumentation/aws_sdk.rb
81
81
  - lib/instrumentation/aws_sdk_plugin.rb
82
82
  - lib/instrumentation/epsagon_faraday_middleware.rb
83
+ - lib/instrumentation/epsagon_rails_middleware.rb
83
84
  - lib/instrumentation/faraday.rb
84
85
  - lib/instrumentation/net_http.rb
86
+ - lib/instrumentation/rails.rb
85
87
  - lib/instrumentation/sinatra.rb
86
88
  - lib/util.rb
87
89
  homepage: https://github.com/epsagon/epsagon-ruby