uptrace 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: 6fed520ea5aa64b60260f976f155c618852f95c36e0eacfca80dd3b0654cf00f
4
- data.tar.gz: b93d8bb971d72e571b9f87c098779c0aede9157d698ea522ea360801d9f133e3
3
+ metadata.gz: a05b7c62ea6f2a2fb078f3b8272951c1d114f8062ff833c14c3b5a9183524cb1
4
+ data.tar.gz: 2876c7b4803b791d5955665a5fb8e97754355f9929c2a6b5ea39b511a839f54c
5
5
  SHA512:
6
- metadata.gz: d6f4ae143df5432535606e745907a7dd8ac9e22d9ac08280826b457ad6fd15d9c16fc368baab5616ec655fa0d9a9596edb7dfd0c7802563fe70e1b4cad2aa70d
7
- data.tar.gz: 29156234fe786b7ceefa118511153fea5afbc2e4fe7890cdc32eac0cb6d6274a40e6630a3c4fee95aa94203c876438434c17e87f8a443260f480c2b6d437b85a
6
+ metadata.gz: 9ce7612b3d87b3a32605996de564ce4f44821590bca24af38c6ef267d0a5c7c3d141a8241042bb36f86e532e4e38d971d3f82c9a096f69a1a58af5262efbd0af
7
+ data.tar.gz: b9b4d42c52cdfac6ae3444a3d782c83c7d410941a8b4a63aaf05d318863fa229d30e588484746df86a60358d57c5eefc718611bc94987987c5082bd8017887a1
data/README.md CHANGED
@@ -1,89 +1,21 @@
1
1
  # Uptrace Ruby exporter for OpenTelemetry
2
2
 
3
3
  [![Build Status](https://travis-ci.org/uptrace/uptrace-ruby.svg?branch=master)](https://travis-ci.org/uptrace/uptrace-ruby)
4
+ [![Documentation](https://img.shields.io/badge/uptrace-documentation-informational)](https://docs.uptrace.dev/ruby/)
4
5
 
5
- ## Introduction
6
-
7
- uptrace-ruby is an exporter for [OpenTelemetry](https://opentelemetry.io/) that
8
- sends your traces/spans and metrics to [Uptrace.dev](https://uptrace.dev).
9
- Briefly the process is the following:
10
-
11
- - OpenTelemetry API is used to instrument your application with spans and
12
- metrics.
13
- - OpenTelemetry SDK and this exporter send collected information to Uptrace.dev.
14
- - Uptrace.dev uses that information to help you pinpoint failures and find
15
- performance bottlenecks.
16
-
17
- ## Instrumenting code
18
-
19
- You instrument your application by wrapping potentially interesting operations
20
- with spans. Each span has:
21
-
22
- - an operation name;
23
- - a start time and end time;
24
- - a set of key/value attributes containing data about the operation;
25
- - a set of timed events representing events, errors, logs, etc.
26
-
27
- You create spans using a tracer:
6
+ <a href="https://docs.uptrace.dev/ruby/">
7
+ <img src="https://docs.uptrace.dev/devicons/ruby-original.svg" height="200px" />
8
+ </a>
28
9
 
29
- ```ruby
30
- require 'opentelemetry'
10
+ ## Installation
31
11
 
32
- // Create a named tracer using your repo as an identifier.
33
- tracer = OpenTelemetry.tracer_provider.tracer('github.com/username/app-name', 'semver:1.0')
12
+ ```bash
13
+ gem install uptrace
34
14
  ```
35
15
 
36
- To create a span:
37
-
38
- ```ruby
39
- tracer.in_span('operation-name') do |span|
40
- do_some_work
41
- end
42
- ```
43
-
44
- Internally that does roughly the following:
45
-
46
- ```ruby
47
- // Create a span.
48
- span = tracer.start_span('operation-name')
49
-
50
- // Activate the span within the current context.
51
- tracer.with_span(span) do |span|
52
- do_some_work
53
- end
54
-
55
- // Finish the span when operation is completed.
56
- span.finish
57
- ```
58
-
59
- To get the active span from the context:
60
-
61
- ```ruby
62
- span = tracer.current_span
63
- ```
64
-
65
- Once you have a span you can start adding attributes:
66
-
67
- ```ruby
68
- span.set_attribute('enduser.id', '123')
69
- span.set_attribute('enduser.role', 'admin')
70
- ```
71
-
72
- or events:
73
-
74
- ```ruby
75
- span.add_event(name: 'log', attributes: {
76
- 'log.severity': 'error',
77
- 'log.message': 'User not found',
78
- 'enduser.id': '123',
79
- })
80
- ```
16
+ ## Introduction
81
17
 
82
- To record an error use `record_error` which internally uses `add_event`. Note
83
- that `tracer.in_span` already records resqued exceptions.
18
+ uptrace-ruby is the official Uptrace client for Ruby that sends your traces/spans and metrics to
19
+ [Uptrace.dev](https://uptrace.dev).
84
20
 
85
- ```ruby
86
- rescue Exception => e
87
- span.record_error(e)
88
- end
89
- ```
21
+ See [uptrace-ruby documentation](https://docs.uptrace.dev/ruby/) for details.
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'opentelemetry/sdk'
4
+
5
+ module Uptrace
6
+ # Uptrace client that configures OpenTelemetry SDK to use Uptrace exporter.
7
+ class Client
8
+ ##
9
+ # @yieldparam config [Uptrace::Config]
10
+ # @return [void]
11
+ #
12
+ def initialize
13
+ @cfg = Uptrace::Trace::Config.new
14
+ yield @cfg if block_given?
15
+
16
+ begin
17
+ @cfg.dsno
18
+ rescue ArgumentError => e
19
+ Uptrace.logger.error(e.message)
20
+ @cfg.disabled = true
21
+
22
+ @cfg.dsn = 'https://TOKEN@api.uptrace.dev/PROJECT_ID'
23
+ end
24
+
25
+ setup_tracing unless @cfg.disabled
26
+ end
27
+
28
+ # @param [optional Numeric] timeout An optional timeout in seconds.
29
+ def shutdown(timeout: nil)
30
+ return if @cfg.disabled
31
+
32
+ OpenTelemetry.tracer_provider.shutdown(timeout: timeout)
33
+ end
34
+
35
+ # @return [OpenTelemetry::Trace::Span]
36
+ def trace_url(span)
37
+ dsn = @cfg.dsno
38
+ host = dsn.host.delete_prefix('api.')
39
+ trace_id = span.context.hex_trace_id
40
+ "#{dsn.scheme}://#{host}/#{dsn.project_id}/search?q=#{trace_id}"
41
+ end
42
+
43
+ private
44
+
45
+ def setup_tracing
46
+ exp = Uptrace::Trace::Exporter.new(@cfg)
47
+
48
+ OpenTelemetry::SDK.configure do |c|
49
+ bsp = OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new(exporter: exp, max_queue_size: 1000, max_export_batch_size: 1000, schedule_delay: 5_000)
50
+ c.add_span_processor(bsp)
51
+
52
+ c.service_name = @cfg.service_name
53
+ c.service_version = @cfg.service_version
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Uptrace
4
+ # Uptrace DSN
5
+ class DSN
6
+ KEYS = %w[scheme host project_id token].freeze
7
+
8
+ attr_reader :dsn, :port, *KEYS
9
+
10
+ def initialize(dsn)
11
+ raise ArgumentError, "uptrace: DSN can't be empty" if dsn.empty?
12
+
13
+ begin
14
+ uri = URI.parse(dsn)
15
+ rescue URI::InvalidURIError => e
16
+ raise ArgumentError, %(uptrace: can't parse DSN=#{dsn.inspect}: #{e})
17
+ end
18
+
19
+ @dsn = dsn
20
+ @project_id = uri.path.delete_prefix('/')
21
+ @token = uri.user
22
+ @host = uri.host
23
+ @port = uri.port
24
+ @scheme = uri.scheme
25
+
26
+ KEYS.each do |k|
27
+ v = public_send(k)
28
+ raise ArgumentError, %(uptrace: DSN does not have #{k} (DSN=#{dsn.inspect})) if v.nil? || v.empty?
29
+ end
30
+ end
31
+
32
+ def to_s
33
+ @dsn
34
+ end
35
+ end
36
+ end
@@ -1,12 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'uptrace/dsn'
4
+
3
5
  module Uptrace
4
6
  module Trace
5
7
  # Config is a configuration for Uptrace span exporter.
6
8
  class Config
7
- # @return [String] a data source name to connect to uptrace.dev.
8
- # @api public
9
+ # @return [string] a data source name to connect to uptrace.dev.
9
10
  attr_accessor :dsn
11
+
12
+ # @return [string] `service.name` resource attribute.
13
+ attr_accessor :service_name
14
+
15
+ # @return [string] `service.name` resource attribute.
16
+ attr_accessor :service_version
17
+
18
+ # @return [boolean] disables the exporter.
19
+ attr_accessor :disabled
20
+
21
+ def initialize
22
+ @dsn = ENV.fetch('UPTRACE_DSN', '')
23
+ end
24
+
25
+ def dsno
26
+ @dsno ||= DSN.new(@dsn)
27
+ end
10
28
  end
11
29
  end
12
30
  end
@@ -1,104 +1,124 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'uri'
4
+ require 'net/http'
5
+ require 'json'
4
6
 
7
+ require 'opentelemetry/sdk'
5
8
  require 'msgpack'
6
- require 'lz4-ruby'
9
+ require 'zstd-ruby'
7
10
 
8
11
  module Uptrace
9
12
  module Trace
10
- # @!visibility private
11
- ExpoSpan = Struct.new(
12
- :id,
13
- :parentId,
14
- :name,
15
- :kind,
16
- :startTime,
17
- :endTime,
18
- :statusCode,
19
- :statusMessage,
20
- :attrs,
21
- :events,
22
- :links,
23
- :resource
24
- )
25
-
26
13
  # Exporter is a span exporter for OpenTelemetry.
27
14
  class Exporter
15
+ SUCCESS = OpenTelemetry::SDK::Trace::Export::SUCCESS
16
+ FAILURE = OpenTelemetry::SDK::Trace::Export::FAILURE
17
+ TIMEOUT = OpenTelemetry::SDK::Trace::Export::TIMEOUT
18
+ private_constant(:SUCCESS, :FAILURE, :TIMEOUT)
19
+
28
20
  ##
29
21
  # @param [Config] cfg
30
22
  #
31
23
  def initialize(cfg)
32
24
  @cfg = cfg
33
25
 
34
- begin
35
- @uri = URI.parse(cfg.dsn)
36
- rescue URI::InvalidURIError => e
37
- @disabled = true
38
- Uptrace.logger.error("can't parse dsn=#{cfg.dsn}: #{e}")
39
- else
40
- @endpoint = "#{@uri.scheme}://#{@uri.host}/api/v1/tracing#{@uri.path}/spans"
41
- end
26
+ dsn = @cfg.dsno
27
+ @endpoint = "/api/v1/tracing/#{dsn.project_id}/spans"
28
+
29
+ @http = Net::HTTP.new(dsn.host, 443)
30
+ @http.use_ssl = true
31
+ @http.open_timeout = 5
32
+ @http.read_timeout = 5
33
+ @http.keep_alive_timeout = 30
42
34
  end
43
35
 
44
- def export(spans)
45
- return if @disabled
36
+ # Called to export sampled {OpenTelemetry::SDK::Trace::SpanData} structs.
37
+ #
38
+ # @param [Enumerable<OpenTelemetry::SDK::Trace::SpanData>] spans the
39
+ # list of recorded {OpenTelemetry::SDK::Trace::SpanData} structs to be
40
+ # exported.
41
+ # @param [optional Numeric] timeout An optional timeout in seconds.
42
+ # @return [Integer] the result of the export.
43
+ def export(spans, timeout: nil)
44
+ return SUCCESS if @disabled
45
+ return FAILURE if @shutdown
46
46
 
47
- traces = {}
47
+ out = []
48
48
 
49
49
  spans.each do |span|
50
- trace = traces[span.trace_id]
50
+ out.push(uptrace_span(span))
51
+ end
51
52
 
52
- if trace.nil?
53
- trace = []
54
- traces[span.trace_id] = trace
55
- end
53
+ send({ spans: out }, timeout: timeout)
54
+ end
56
55
 
57
- expose = expo_span(span)
58
- trace.push(expose)
59
- end
56
+ # Called when {OpenTelemetry::SDK::Trace::Tracer#shutdown} is called, if
57
+ # this exporter is registered to a {OpenTelemetry::SDK::Trace::Tracer}
58
+ # object.
59
+ #
60
+ # @param [optional Numeric] timeout An optional timeout in seconds.
61
+ def shutdown(timeout: nil) # rubocop:disable Lint/UnusedMethodArgument
62
+ @shutdown = true
63
+ @http.finish if @http.started?
60
64
  end
61
65
 
62
66
  private
63
67
 
64
- def send(traces)
65
- req = build_request(traces: traces)
66
- connection.request(req)
67
- end
68
-
69
68
  ##
70
- # @return [ExpoSpan]
69
+ # @return [hash]
71
70
  #
72
- def expo_span(span)
73
- expose = ExpoSpan.new
71
+ def uptrace_span(span)
72
+ out = {
73
+ id: span.span_id.unpack1('Q'),
74
+ traceId: span.trace_id,
74
75
 
75
- expose.id = span.id
76
- expose.parentId = span.parent_span_id
76
+ name: span.name,
77
+ kind: kind_as_str(span.kind),
78
+ startTime: as_unix_nano(span.start_timestamp),
79
+ endTime: as_unix_nano(span.end_timestamp),
77
80
 
78
- expose.name = span.name
79
- expose.kind = span.kind
80
- expose.startTime = span.start_timestamp.to_i
81
- expose.endTime = span.end_timestamp.to_i
82
- expose.statusCode = span.status.canonical_code
83
- expose.statusMessage = span.status.description
84
- expose.attrs = span.attributes
81
+ resource: uptrace_resource(span.resource),
82
+ attrs: span.attributes,
85
83
 
86
- expose
84
+ statusCode: status_code_as_str(span.status.code),
85
+ statusMessage: span.status.description,
86
+
87
+ tracer: uptrace_tracer(span.instrumentation_library)
88
+ }
89
+
90
+ out['parentId'] = span.parent_span_id.unpack1('Q') if span.parent_span_id
91
+
92
+ out['events'] = uptrace_events(span.events) unless span.events.nil?
93
+ out['links'] = uptrace_links(span.links) unless span.links.nil?
94
+
95
+ out
87
96
  end
88
97
 
89
- ##
90
- # @return [Net::HTTP]
91
- #
92
- def connection
93
- unless @conn
94
- @conn = Net::HTTP.new(@uri.host, @uri.port)
95
- @conn.use_ssl = @uri.is_a?(URI::HTTPS)
96
- @conn.open_timeout = 5
97
- @conn.read_timeout = 5
98
- @conn.keep_alive_timeout = 30
98
+ def send(data, timeout: nil) # rubocop:disable Lint/UnusedMethodArgument
99
+ req = build_request(data)
100
+
101
+ begin
102
+ resp = @http.request(req)
103
+ rescue Net::OpenTimeout, Net::ReadTimeout
104
+ return FAILURE
99
105
  end
100
106
 
101
- @conn
107
+ case resp
108
+ when Net::HTTPOK
109
+ resp.body # Read and discard body
110
+ SUCCESS
111
+ when Net::HTTPBadRequest
112
+ data = JSON.parse(resp.body)
113
+ Uptrace.logger.error("status=#{data['status']}: #{data['message']}")
114
+ FAILURE
115
+ when Net::HTTPInternalServerError
116
+ resp.body
117
+ FAILURE
118
+ else
119
+ @http.finish
120
+ FAILURE
121
+ end
102
122
  end
103
123
 
104
124
  ##
@@ -106,18 +126,107 @@ module Uptrace
106
126
  # @return [Net::HTTP::Post]
107
127
  #
108
128
  def build_request(data)
109
- data = data.to_msgpack
110
- data = LZ4.compress data
129
+ data = MessagePack.pack(data)
130
+ data = Zstd.compress(data, 3)
111
131
 
112
132
  req = Net::HTTP::Post.new(@endpoint)
113
- req['Authorization'] = @uri.user
114
- req['Content-Type'] = 'application/msgpack'
115
- req['Content-Encoding'] = 'lz4'
116
- req['Connection'] = 'keep-alive'
133
+ req.add_field('Authorization', "Bearer #{@cfg.dsno.token}")
134
+ req.add_field('Content-Type', 'application/msgpack')
135
+ req.add_field('Content-Encoding', 'zstd')
136
+ req.add_field('Connection', 'keep-alive')
117
137
  req.body = data
118
138
 
119
139
  req
120
140
  end
141
+
142
+ # @param [SpanKind] kind
143
+ # @return [String]
144
+ def kind_as_str(kind)
145
+ case kind
146
+ when OpenTelemetry::Trace::SpanKind::SERVER
147
+ 'server'
148
+ when OpenTelemetry::Trace::SpanKind::CLIENT
149
+ 'client'
150
+ when OpenTelemetry::Trace::SpanKind::PRODUCER
151
+ 'producer'
152
+ when OpenTelemetry::Trace::SpanKind::CONSUMER
153
+ 'consumer'
154
+ else
155
+ 'internal'
156
+ end
157
+ end
158
+
159
+ ##
160
+ # @param [Integer] timestamp
161
+ # @return [Integer]
162
+ #
163
+ def as_unix_nano(timestamp)
164
+ (timestamp.to_r * 1_000_000_000).to_i
165
+ end
166
+
167
+ ##
168
+ # @param [Integer] code
169
+ # @return [String]
170
+ #
171
+ def status_code_as_str(code)
172
+ case code
173
+ when OpenTelemetry::Trace::Status::OK
174
+ 'ok'
175
+ when OpenTelemetry::Trace::Status::ERROR
176
+ 'error'
177
+ else
178
+ 'unset'
179
+ end
180
+ end
181
+
182
+ ##
183
+ # @param [OpenTelemetry::SDK::Resources::Resource] resource
184
+ # @return [Hash]
185
+ #
186
+ def uptrace_resource(resource)
187
+ out = {}
188
+ resource.attribute_enumerator.map { |key, value| out[key] = value }
189
+ out
190
+ end
191
+
192
+ def uptrace_events(events)
193
+ out = []
194
+ events.each do |event|
195
+ out.push(
196
+ {
197
+ name: event.name,
198
+ attrs: event.attributes,
199
+ time: as_unix_nano(event.timestamp)
200
+ }
201
+ )
202
+ end
203
+ out
204
+ end
205
+
206
+ def uptrace_links(links)
207
+ out = []
208
+ links.each do |link|
209
+ out.push(
210
+ {
211
+ trace_id => link.span_context.trace_id,
212
+ span_id => link.span_context.span_id.unpack1('Q'),
213
+ attrs => link.attributes
214
+ }
215
+ )
216
+ end
217
+ out
218
+ end
219
+
220
+ ##
221
+ # @param [OpenTelemetry::SDK::InstrumentationLibrary] il
222
+ # @return [Hash]
223
+ #
224
+ def uptrace_tracer(il)
225
+ {
226
+ name: il.name,
227
+ version: il.version
228
+ }
229
+ end
121
230
  end
122
231
  end
123
232
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Uptrace
4
- VERSION = '0.1.0'
4
+ VERSION = '0.2.0'
5
5
  end
data/lib/uptrace.rb CHANGED
@@ -8,8 +8,10 @@ module Uptrace
8
8
 
9
9
  attr_accessor :logger
10
10
 
11
- self.logger = Logger.new(STDOUT)
11
+ self.logger = Logger.new($stdout)
12
12
  end
13
13
 
14
14
  require 'uptrace/version'
15
+ require 'uptrace/dsn'
16
+ require 'uptrace/client'
15
17
  require 'uptrace/trace'
metadata CHANGED
@@ -1,43 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uptrace
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
  - Uptrace Authors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-04 00:00:00.000000000 Z
11
+ date: 2021-02-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: lz4-ruby
14
+ name: msgpack
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.3.3
19
+ version: '1.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.3.3
26
+ version: '1.3'
27
27
  - !ruby/object:Gem::Dependency
28
- name: msgpack
28
+ name: opentelemetry-sdk
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.3'
33
+ version: 0.14.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: '1.3'
40
+ version: 0.14.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: zstd-ruby
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 1.4.5.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 1.4.5.0
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: bundler
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -86,14 +100,42 @@ dependencies:
86
100
  requirements:
87
101
  - - "~>"
88
102
  - !ruby/object:Gem::Version
89
- version: 0.73.0
103
+ version: 1.10.0
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 1.10.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: rubocop-minitest
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 0.10.2
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 0.10.2
125
+ - !ruby/object:Gem::Dependency
126
+ name: rubocop-rake
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 0.5.1
90
132
  type: :development
91
133
  prerelease: false
92
134
  version_requirements: !ruby/object:Gem::Requirement
93
135
  requirements:
94
136
  - - "~>"
95
137
  - !ruby/object:Gem::Version
96
- version: 0.73.0
138
+ version: 0.5.1
97
139
  - !ruby/object:Gem::Dependency
98
140
  name: yard
99
141
  requirement: !ruby/object:Gem::Requirement
@@ -133,6 +175,8 @@ files:
133
175
  - LICENSE
134
176
  - README.md
135
177
  - lib/uptrace.rb
178
+ - lib/uptrace/client.rb
179
+ - lib/uptrace/dsn.rb
136
180
  - lib/uptrace/metric.rb
137
181
  - lib/uptrace/trace.rb
138
182
  - lib/uptrace/trace/config.rb
@@ -157,7 +201,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
157
201
  - !ruby/object:Gem::Version
158
202
  version: '0'
159
203
  requirements: []
160
- rubygems_version: 3.1.2
204
+ rubygems_version: 3.1.4
161
205
  signing_key:
162
206
  specification_version: 4
163
207
  summary: Uptrace Ruby exporter for OpenTelemetry