uptrace 0.1.0 → 0.2.4

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: 525b8e2ad45dd955af7095839bfdf024e29b11309e8a0103b36bddb7980f3c41
4
+ data.tar.gz: 0766a2822dad2acb536aeccba788ac898ce7474ae4d74de355577de544772a4b
5
5
  SHA512:
6
- metadata.gz: d6f4ae143df5432535606e745907a7dd8ac9e22d9ac08280826b457ad6fd15d9c16fc368baab5616ec655fa0d9a9596edb7dfd0c7802563fe70e1b4cad2aa70d
7
- data.tar.gz: 29156234fe786b7ceefa118511153fea5afbc2e4fe7890cdc32eac0cb6d6274a40e6630a3c4fee95aa94203c876438434c17e87f8a443260f480c2b6d437b85a
6
+ metadata.gz: 36c69755595e07ffee78a62f3f1633fdd62def2d910b50876e8ffc4e2791800869d98f61b338bb2e30a01280610cc5fbeabe58a0f17214b5f2377031c2801f07
7
+ data.tar.gz: f33956036979a79d2f39e05f8a30f3008ffd967a828a048d88b187867e562bd013cecf9b0958584dc885142341633848739c3fc05dded624c8c16dc7ee8d7848
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.
data/RELEASE.md ADDED
@@ -0,0 +1,7 @@
1
+ Bump version and then run:
2
+
3
+ ```shell
4
+ gem build uptrace.gemspec
5
+ bundle install
6
+ gem push uptrace-0.2.0.gem
7
+ ```
data/lib/uptrace.rb CHANGED
@@ -7,9 +7,31 @@ module Uptrace
7
7
  extend self
8
8
 
9
9
  attr_accessor :logger
10
+ attr_writer :client
10
11
 
11
- self.logger = Logger.new(STDOUT)
12
+ self.logger = Logger.new($stdout)
13
+
14
+ # @return [Object, Client] registered client or a default no-op implementation of the client.
15
+ def client
16
+ @client ||= Client.new
17
+ end
18
+
19
+ def trace_url(span)
20
+ client.trace_url(span)
21
+ end
22
+
23
+ def configure_tracing(c, dsn: '')
24
+ upclient = if dsn.empty?
25
+ client
26
+ else
27
+ Client.new(dsn: dsn)
28
+ end
29
+
30
+ c.add_span_processor(upclient.span_processor) unless upclient.disabled?
31
+ end
12
32
  end
13
33
 
14
34
  require 'uptrace/version'
35
+ require 'uptrace/dsn'
36
+ require 'uptrace/client'
15
37
  require 'uptrace/trace'
@@ -0,0 +1,45 @@
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
+ # @param [string] dsn
9
+ def initialize(dsn: '')
10
+ dsn = ENV.fetch('UPTRACE_DSN', '') if dsn.empty?
11
+
12
+ begin
13
+ @dsn = DSN.new(dsn)
14
+ rescue ArgumentError => e
15
+ Uptrace.logger.error("Uptrace is disabled: #{e.message}")
16
+ @disabled = true
17
+
18
+ @dsn = DSN.new('https://TOKEN@api.uptrace.dev/PROJECT_ID')
19
+ end
20
+ end
21
+
22
+ def disabled?
23
+ @disabled
24
+ end
25
+
26
+ # @param [OpenTelemetry::Trace::Span] span
27
+ # @return [String]
28
+ def trace_url(span)
29
+ host = @dsn.host.delete_prefix('api.')
30
+ trace_id = span.context.hex_trace_id
31
+ "#{@dsn.scheme}://#{host}/search/#{@dsn.project_id}?q=#{trace_id}"
32
+ end
33
+
34
+ # @return [OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor]
35
+ def span_processor
36
+ exp = Uptrace::Trace::Exporter.new(@dsn)
37
+ OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new(
38
+ exp,
39
+ max_queue_size: 1000,
40
+ max_export_batch_size: 1000,
41
+ schedule_delay: 5_000
42
+ )
43
+ end
44
+ end
45
+ 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, "DSN can't be empty" if dsn.empty?
12
+
13
+ begin
14
+ uri = URI.parse(dsn)
15
+ rescue URI::InvalidURIError => e
16
+ raise ArgumentError, %(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, %(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,104 +1,125 @@
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
- def initialize(cfg)
32
- @cfg = cfg
33
-
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
23
+ def initialize(dsn)
24
+ @dsn = dsn
25
+ @endpoint = "/api/v1/tracing/#{@dsn.project_id}/spans"
26
+
27
+ @http = Net::HTTP.new(@dsn.host, 443)
28
+ @http.use_ssl = true
29
+ @http.open_timeout = 5
30
+ @http.read_timeout = 5
31
+ @http.keep_alive_timeout = 30
42
32
  end
43
33
 
44
- def export(spans)
45
- return if @disabled
34
+ # Called to export sampled {OpenTelemetry::SDK::Trace::SpanData} structs.
35
+ #
36
+ # @param [Enumerable<OpenTelemetry::SDK::Trace::SpanData>] spans the
37
+ # list of recorded {OpenTelemetry::SDK::Trace::SpanData} structs to be
38
+ # exported.
39
+ # @param [optional Numeric] timeout An optional timeout in seconds.
40
+ # @return [Integer] the result of the export.
41
+ def export(spans, timeout: nil)
42
+ return SUCCESS if @disabled
43
+ return FAILURE if @shutdown
46
44
 
47
- traces = {}
45
+ out = []
48
46
 
49
47
  spans.each do |span|
50
- trace = traces[span.trace_id]
48
+ out.push(uptrace_span(span))
49
+ end
51
50
 
52
- if trace.nil?
53
- trace = []
54
- traces[span.trace_id] = trace
55
- end
51
+ send({ spans: out }, timeout: timeout)
52
+ end
56
53
 
57
- expose = expo_span(span)
58
- trace.push(expose)
59
- end
54
+ # Called when {OpenTelemetry::SDK::Trace::Tracer#shutdown} is called, if
55
+ # this exporter is registered to a {OpenTelemetry::SDK::Trace::Tracer}
56
+ # object.
57
+ #
58
+ # @param [optional Numeric] timeout An optional timeout in seconds.
59
+ def shutdown(timeout: nil) # rubocop:disable Lint/UnusedMethodArgument
60
+ @shutdown = true
61
+ @http.finish if @http.started?
60
62
  end
61
63
 
62
64
  private
63
65
 
64
- def send(traces)
65
- req = build_request(traces: traces)
66
- connection.request(req)
67
- end
68
-
69
66
  ##
70
- # @return [ExpoSpan]
67
+ # @return [hash]
71
68
  #
72
- def expo_span(span)
73
- expose = ExpoSpan.new
69
+ def uptrace_span(span)
70
+ out = {
71
+ id: span.span_id.unpack1('Q'),
72
+ traceId: span.trace_id,
73
+
74
+ name: span.name,
75
+ kind: kind_as_str(span.kind),
76
+ startTime: as_unix_nano(span.start_timestamp),
77
+ endTime: as_unix_nano(span.end_timestamp),
78
+
79
+ resource: uptrace_resource(span.resource),
80
+ attrs: span.attributes
81
+ }
74
82
 
75
- expose.id = span.id
76
- expose.parentId = span.parent_span_id
83
+ out[:parentId] = span.parent_span_id.unpack1('Q') if span.parent_span_id
77
84
 
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
85
+ out[:events] = uptrace_events(span.events) unless span.events.nil?
86
+ out[:links] = uptrace_links(span.links) unless span.links.nil?
85
87
 
86
- expose
88
+ status = span.status
89
+ out[:statusCode] = status_code_as_str(status.code)
90
+ out[:statusMessage] = status.description unless status.description.empty?
91
+
92
+ il = span.instrumentation_library
93
+ out[:tracerName] = il.name
94
+ out[:tracerVersion] = il.name unless il.version.empty?
95
+
96
+ out
87
97
  end
88
98
 
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
99
+ def send(data, timeout: nil) # rubocop:disable Lint/UnusedMethodArgument
100
+ req = build_request(data)
101
+
102
+ begin
103
+ resp = @http.request(req)
104
+ rescue Net::OpenTimeout, Net::ReadTimeout
105
+ return FAILURE
99
106
  end
100
107
 
101
- @conn
108
+ case resp
109
+ when Net::HTTPOK
110
+ resp.body # Read and discard body
111
+ SUCCESS
112
+ when Net::HTTPBadRequest
113
+ data = JSON.parse(resp.body)
114
+ Uptrace.logger.error("status=#{data['status']}: #{data['message']}")
115
+ FAILURE
116
+ when Net::HTTPInternalServerError
117
+ resp.body
118
+ FAILURE
119
+ else
120
+ @http.finish
121
+ FAILURE
122
+ end
102
123
  end
103
124
 
104
125
  ##
@@ -106,18 +127,96 @@ module Uptrace
106
127
  # @return [Net::HTTP::Post]
107
128
  #
108
129
  def build_request(data)
109
- data = data.to_msgpack
110
- data = LZ4.compress data
130
+ data = MessagePack.pack(data)
131
+ data = Zstd.compress(data, 3)
111
132
 
112
133
  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'
134
+ req.add_field('Authorization', "Bearer #{@dsn.token}")
135
+ req.add_field('Content-Type', 'application/msgpack')
136
+ req.add_field('Content-Encoding', 'zstd')
137
+ req.add_field('Connection', 'keep-alive')
117
138
  req.body = data
118
139
 
119
140
  req
120
141
  end
142
+
143
+ # @param [SpanKind] kind
144
+ # @return [String]
145
+ def kind_as_str(kind)
146
+ case kind
147
+ when OpenTelemetry::Trace::SpanKind::SERVER
148
+ 'server'
149
+ when OpenTelemetry::Trace::SpanKind::CLIENT
150
+ 'client'
151
+ when OpenTelemetry::Trace::SpanKind::PRODUCER
152
+ 'producer'
153
+ when OpenTelemetry::Trace::SpanKind::CONSUMER
154
+ 'consumer'
155
+ else
156
+ 'internal'
157
+ end
158
+ end
159
+
160
+ ##
161
+ # @param [Integer] timestamp
162
+ # @return [Integer]
163
+ #
164
+ def as_unix_nano(timestamp)
165
+ (timestamp.to_r * 1_000_000_000).to_i
166
+ end
167
+
168
+ ##
169
+ # @param [Integer] code
170
+ # @return [String]
171
+ #
172
+ def status_code_as_str(code)
173
+ case code
174
+ when OpenTelemetry::Trace::Status::OK
175
+ 'ok'
176
+ when OpenTelemetry::Trace::Status::ERROR
177
+ 'error'
178
+ else
179
+ 'unset'
180
+ end
181
+ end
182
+
183
+ ##
184
+ # @param [OpenTelemetry::SDK::Resources::Resource] resource
185
+ # @return [Hash]
186
+ #
187
+ def uptrace_resource(resource)
188
+ out = {}
189
+ resource.attribute_enumerator.map { |key, value| out[key] = value }
190
+ out
191
+ end
192
+
193
+ def uptrace_events(events)
194
+ out = []
195
+ events.each do |event|
196
+ out.push(
197
+ {
198
+ name: event.name,
199
+ attrs: event.attributes,
200
+ time: as_unix_nano(event.timestamp)
201
+ }
202
+ )
203
+ end
204
+ out
205
+ end
206
+
207
+ def uptrace_links(links)
208
+ out = []
209
+ links.each do |link|
210
+ out.push(
211
+ {
212
+ trace_id => link.span_context.trace_id,
213
+ span_id => link.span_context.span_id.unpack1('Q'),
214
+ attrs => link.attributes
215
+ }
216
+ )
217
+ end
218
+ out
219
+ end
121
220
  end
122
221
  end
123
222
  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.4'
5
5
  end
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.4
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-03-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.15.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.15.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
@@ -132,10 +174,12 @@ files:
132
174
  - ".yardopts"
133
175
  - LICENSE
134
176
  - README.md
177
+ - RELEASE.md
135
178
  - lib/uptrace.rb
179
+ - lib/uptrace/client.rb
180
+ - lib/uptrace/dsn.rb
136
181
  - lib/uptrace/metric.rb
137
182
  - lib/uptrace/trace.rb
138
- - lib/uptrace/trace/config.rb
139
183
  - lib/uptrace/trace/exporter.rb
140
184
  - lib/uptrace/version.rb
141
185
  homepage: https://github.com/uptrace/uptrace-ruby
@@ -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
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Uptrace
4
- module Trace
5
- # Config is a configuration for Uptrace span exporter.
6
- class Config
7
- # @return [String] a data source name to connect to uptrace.dev.
8
- # @api public
9
- attr_accessor :dsn
10
- end
11
- end
12
- end