gitlab-labkit 1.4.0 → 1.5.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.
@@ -0,0 +1,218 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "base64"
4
+ require "cgi"
5
+ require "active_support"
6
+ require "active_support/core_ext"
7
+
8
+ require "opentelemetry/sdk"
9
+ require "opentelemetry/exporter/otlp"
10
+
11
+ module Labkit
12
+ module Tracing
13
+ # OpenTelemetryFactory will configure OpenTelemetry distributed tracing
14
+ class OpenTelemetryFactory
15
+ OTLP_SCHEME = "otlp"
16
+
17
+ # The default endpoint for OTLP HTTP exporter
18
+ DEFAULT_HTTP_ENDPOINT = "http://localhost:4318/v1/traces"
19
+
20
+ class << self
21
+ # @param service_name [String] The service name for the tracer
22
+ # @param connection_string [String] The connection string (e.g., "otlp://localhost:4318")
23
+ # @yield [config] Optional configuration block for OpenTelemetry SDK customization
24
+ # @yieldparam config [OpenTelemetry::SDK::Configurator] The SDK configurator
25
+ # @return [Tracer, nil] The configured tracer or nil if initialization fails
26
+ def create_tracer(service_name, connection_string, &)
27
+ return unless connection_string.present?
28
+
29
+ options = parse_otlp_connection_string(connection_string)
30
+ # The service_name parameter from GITLAB_TRACING takes precedence over the application one
31
+ service_name = options[:service_name] if options[:service_name]
32
+
33
+ # parse exporter headers as necessary
34
+ headers = build_headers(options)
35
+
36
+ # Get sampler and exporter from GITLAB_TRACING
37
+ sampler = get_sampler(options[:sampler], options[:sampler_param])
38
+ exporter = get_exporter(options[:http_endpoint], options[:udp_endpoint], headers)
39
+
40
+ # Build base resource
41
+ base_resource = OpenTelemetry::SDK::Resources::Resource.create(
42
+ OpenTelemetry::SemanticConventions::Resource::SERVICE_NAME => service_name
43
+ )
44
+
45
+ configure(service_name, base_resource, sampler, exporter, &)
46
+
47
+ extra_params = options.except(
48
+ :sampler,
49
+ :sampler_param,
50
+ :http_endpoint,
51
+ :udp_endpoint,
52
+ :strict_parsing,
53
+ :debug,
54
+ :service_name
55
+ )
56
+
57
+ if extra_params.present?
58
+ message = "opentelemetry tracer: invalid option: #{extra_params.keys.join(', ')}"
59
+
60
+ raise message if options[:strict_parsing]
61
+
62
+ warn message
63
+ end
64
+
65
+ OpenTelemetry.tracer_provider.tracer(service_name)
66
+ end
67
+
68
+ private
69
+
70
+ def configure(service_name, base_resource, sampler, exporter)
71
+ if block_given?
72
+ OpenTelemetry::SDK.configure do |c|
73
+ c.service_name = service_name
74
+ c.resource = base_resource
75
+
76
+ processor = create_span_processor(exporter)
77
+ c.add_span_processor(processor) if processor
78
+
79
+ yield(c)
80
+ end
81
+
82
+ # SDK.configure doesn't expose sampler configuration directly
83
+ # We need to replace the tracer provider to set the sampler
84
+ # This is a known limitation of the OpenTelemetry Ruby SDK
85
+ current_provider = OpenTelemetry.tracer_provider
86
+ return unless current_provider.is_a?(OpenTelemetry::SDK::Trace::TracerProvider)
87
+
88
+ # Create new provider with sampler, preserving resource from SDK.configure
89
+ create_and_configure_provider(current_provider.resource, sampler, exporter)
90
+ else
91
+ create_and_configure_provider(base_resource, sampler, exporter)
92
+ end
93
+ end
94
+
95
+ def create_span_processor(exporter)
96
+ return nil unless exporter
97
+
98
+ if exporter.is_a?(OpenTelemetry::SDK::Trace::Export::ConsoleSpanExporter)
99
+ OpenTelemetry::SDK::Trace::Export::SimpleSpanProcessor.new(exporter)
100
+ else
101
+ OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new(exporter)
102
+ end
103
+ end
104
+
105
+ def create_and_configure_provider(resource, sampler, exporter)
106
+ tracer_provider = OpenTelemetry::SDK::Trace::TracerProvider.new(
107
+ resource: resource,
108
+ sampler: sampler
109
+ )
110
+
111
+ processor = create_span_processor(exporter)
112
+ tracer_provider.add_span_processor(processor) if processor
113
+
114
+ OpenTelemetry.tracer_provider = tracer_provider
115
+ end
116
+
117
+ def build_headers(options)
118
+ return {} unless options&.key?(:http_endpoint)
119
+
120
+ endpoint = options[:http_endpoint]
121
+ return {} unless endpoint
122
+
123
+ parsed = URI.parse(endpoint)
124
+
125
+ headers = {}
126
+ user = parsed.user
127
+ password = parsed.password
128
+ if user.present? && password.present?
129
+ credentials = Base64.strict_encode64("#{CGI.unescape(user)}:#{CGI.unescape(password)}")
130
+ headers["Authorization"] = "Basic #{credentials}"
131
+ end
132
+
133
+ headers
134
+ end
135
+
136
+ def get_sampler(sampler_type, sampler_param)
137
+ case sampler_type
138
+ when "probabilistic"
139
+ sampler_rate = sampler_param ? sampler_param.to_f : Factory::DEFAULT_PROBABILISTIC_RATE
140
+ OpenTelemetry::SDK::Trace::Samplers::TraceIdRatioBased.new(sampler_rate)
141
+ when "const"
142
+ if sampler_param == "1"
143
+ OpenTelemetry::SDK::Trace::Samplers::ALWAYS_ON
144
+ else
145
+ OpenTelemetry::SDK::Trace::Samplers::ALWAYS_OFF
146
+ end
147
+ else
148
+ OpenTelemetry::SDK::Trace::Samplers::TraceIdRatioBased.new(Factory::DEFAULT_PROBABILISTIC_RATE)
149
+ end
150
+ end
151
+
152
+ def get_exporter(http_endpoint, udp_endpoint, headers)
153
+ # OpenTelemetry doesn't support UDP, warn if specified
154
+ # https://github.com/open-telemetry/opentelemetry-collector/discussions/6016
155
+ warn "opentelemetry tracer: UDP endpoint not supported, ignoring udp_endpoint option" if udp_endpoint.present?
156
+
157
+ # Check for console exporter (for development/testing)
158
+ return get_console_exporter if http_endpoint&.include?("://console")
159
+
160
+ get_http_exporter(http_endpoint, headers) if http_endpoint.present?
161
+ end
162
+
163
+ def get_http_exporter(endpoint, headers)
164
+ OpenTelemetry::Exporter::OTLP::Exporter.new(
165
+ endpoint: endpoint,
166
+ headers: headers
167
+ )
168
+ end
169
+
170
+ def get_console_exporter
171
+ OpenTelemetry::SDK::Trace::Export::ConsoleSpanExporter.new
172
+ end
173
+
174
+ def parse_otlp_connection_string(connection_string)
175
+ parsed = URI.parse(connection_string)
176
+
177
+ # Parse query parameters for additional options
178
+ options = parse_query(parsed.query)
179
+
180
+ # Handle console exporter (special case - no endpoint needed)
181
+ if parsed.host == "console"
182
+ options[:http_endpoint] = "http://console"
183
+ return options
184
+ end
185
+
186
+ endpoint = build_otlp_endpoint(parsed)
187
+ options[:http_endpoint] = endpoint
188
+
189
+ options
190
+ end
191
+
192
+ def build_otlp_endpoint(uri)
193
+ # Reconstruct the endpoint URL with scheme, host, port, and path
194
+ scheme = uri.scheme == OTLP_SCHEME ? "http" : uri.scheme
195
+ host = uri.host
196
+ port = uri.port
197
+ path = uri.path.empty? ? "" : uri.path
198
+
199
+ # Include userinfo (username:password) if present
200
+ userinfo = uri.userinfo ? "#{uri.userinfo}@" : ""
201
+
202
+ # Build the endpoint
203
+ endpoint = "#{scheme}://#{userinfo}#{host}"
204
+ endpoint += ":#{port}" if port
205
+ endpoint += path
206
+
207
+ endpoint
208
+ end
209
+
210
+ def parse_query(query)
211
+ return {} unless query
212
+
213
+ CGI.parse(query).symbolize_keys.transform_values(&:first)
214
+ end
215
+ end
216
+ end
217
+ end
218
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cgi"
4
+
5
+ module Labkit
6
+ module Tracing
7
+ class OpenTracingFactory
8
+ OPENTRACING_SCHEME = "opentracing"
9
+
10
+ def self.create_tracer(service_name, connection_string)
11
+ return unless connection_string.present?
12
+
13
+ opentracing_details = parse_connection_string(connection_string)
14
+ driver_name = opentracing_details[:driver_name]
15
+
16
+ case driver_name
17
+ when "jaeger"
18
+ JaegerFactory.create_tracer(service_name, opentracing_details[:options])
19
+ else
20
+ raise "Unknown driver: #{driver_name}"
21
+ end
22
+ end
23
+
24
+ def self.parse_connection_string(connection_string)
25
+ parsed = URI.parse(connection_string)
26
+
27
+ raise "Invalid tracing connection string" unless valid_uri?(parsed)
28
+
29
+ { driver_name: parsed.host, options: parse_query(parsed.query) }
30
+ end
31
+ private_class_method :parse_connection_string
32
+
33
+ def self.parse_query(query)
34
+ return {} unless query
35
+
36
+ CGI.parse(query).symbolize_keys.transform_values(&:first)
37
+ end
38
+ private_class_method :parse_query
39
+
40
+ def self.valid_uri?(uri)
41
+ return false unless uri
42
+
43
+ uri.scheme == OPENTRACING_SCHEME && uri.host.to_s =~ /^[a-z0-9_]+$/ && uri.path.empty?
44
+ end
45
+ private_class_method :valid_uri?
46
+ end
47
+ end
48
+ end
@@ -18,7 +18,7 @@ module Labkit
18
18
  def call(env)
19
19
  method = env[REQUEST_METHOD]
20
20
 
21
- context = TracingUtils.tracer.extract(OpenTracing::FORMAT_RACK, env)
21
+ context = TracingUtils.tracer.extract_context(env, format: OpenTracing::FORMAT_RACK)
22
22
  tags = { "component" => "rack", "span.kind" => "server", "http.method" => method, "http.url" => self.class.build_sanitized_url_from_env(env) }
23
23
 
24
24
  TracingUtils.with_tracing(operation_name: "http:#{method}", child_of: context, tags: tags) do |span|
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Labkit
4
+ module Tracing
5
+ class Railtie < ::Rails::Railtie
6
+ initializer "labkit.tracing.insert_middleware", after: :load_config_initializers do |app|
7
+ next unless Labkit::Tracing.enabled?
8
+
9
+ # Insert after Labkit::Middleware::Rack for proper correlation ID propagation.
10
+ app.middleware.insert_after Labkit::Middleware::Rack, Labkit::Tracing::RackMiddleware
11
+ ::Rails.logger.info "Labkit::Tracing::RackMiddleware automatically inserted after Labkit::Middleware::Rack"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -10,64 +10,67 @@ module Labkit
10
10
  class TracingUtils
11
11
  # Convience method for running a block with a span
12
12
  def self.with_tracing(operation_name:, tags:, child_of: nil)
13
- scope = tracer.start_active_span(operation_name, child_of: child_of, tags: tags)
14
- span = scope.span
13
+ tracer.in_span(operation_name, child_of: child_of, tags: tags) do |span|
14
+ log_common_fields_on_span(span, operation_name)
15
15
 
16
- log_common_fields_on_span(span, operation_name)
17
-
18
- begin
19
- yield span
20
- rescue StandardError => e
21
- log_exception_on_span(span, e)
22
- raise e
23
- ensure
24
- scope.close
16
+ begin
17
+ yield span
18
+ rescue StandardError => e
19
+ log_exception_on_span(span, e)
20
+ raise e
21
+ end
25
22
  end
26
23
  end
27
24
 
28
25
  # Obtain a tracer instance
26
+ #
27
+ # Returns the appropriate tracer based on connection string configuration:
28
+ # - OpenTelemetry (OTLP): When GITLAB_TRACING uses otlp:// scheme
29
+ # - OpenTracing: When GITLAB_TRACING uses opentracing:// scheme or not set
30
+ #
31
+ # For OpenTelemetry, the tracer's instrumentation scope name is determined by:
32
+ # - The service_name passed to Factory.create_tracer
33
+ # - Falls back to DEFAULT_SERVICE_NAME if Factory was not used
34
+ #
35
+ # Both OpenTelemetry and OpenTracing provide no-op tracers by default:
36
+ # - OpenTelemetry: Uses ProxyTracerProvider until SDK is configured
37
+ # - OpenTracing: Uses default no-op global_tracer
38
+ #
39
+ # This allows spans to be created but not exported when tracing is not initialized,
40
+ # letting the application run safely while producing no trace data.
29
41
  def self.tracer
30
- OpenTracing.global_tracer
42
+ @tracer ||=
43
+ if Tracing.otlp_connection?
44
+ require "opentelemetry/sdk"
45
+
46
+ otel_tracer = OpenTelemetry.tracer_provider.tracer(Tracing.configured_service_name)
47
+ Adapters::OpentelemetryTracer.new(otel_tracer)
48
+ else
49
+ Adapters::OpentracingTracer.new(OpenTracing.global_tracer)
50
+ end
31
51
  end
32
52
 
33
53
  # Generate a span retrospectively
34
54
  def self.postnotify_span(operation_name, start_time, end_time, tags: nil, child_of: nil, exception: nil)
35
- span = OpenTracing.start_span(operation_name, start_time: start_time, tags: tags, child_of: child_of)
55
+ span = tracer.start_span(operation_name, child_of: child_of, tags: tags, start_time: start_time)
36
56
 
37
57
  log_common_fields_on_span(span, operation_name)
38
58
  log_exception_on_span(span, exception) if exception
39
59
 
40
- span.finish(end_time: end_time)
60
+ span.finish(end_timestamp: end_time)
41
61
  end
42
62
 
43
63
  # Add common fields to a span
44
64
  def self.log_common_fields_on_span(span, operation_name)
45
65
  correlation_id = Labkit::Correlation::CorrelationId.current_id
66
+
46
67
  span.set_tag("correlation_id", correlation_id) if correlation_id
47
- span.log_kv(stack: caller.join('\n')) if include_stacktrace?(operation_name)
68
+ span.log_event("stack", stack: caller.join('\n')) if include_stacktrace?(operation_name)
48
69
  end
49
70
 
50
71
  # Add exception logging to a span
51
72
  def self.log_exception_on_span(span, exception)
52
- return if exception.blank?
53
-
54
- span.set_tag("error", true)
55
- span.log_kv(**kv_tags_for_exception(exception))
56
- end
57
-
58
- # Generate key-value tags for an exception
59
- def self.kv_tags_for_exception(exception)
60
- case exception
61
- when Exception
62
- {
63
- :"event" => "error",
64
- :"error.kind" => exception.class.to_s,
65
- :"message" => Labkit::Logging::Sanitizer.sanitize_field(exception.message),
66
- :"stack" => exception.backtrace&.join('\n'),
67
- }
68
- else
69
- { :"event" => "error", :"error.kind" => exception.class.to_s, :"error.object" => Labkit::Logging::Sanitizer.sanitize_field(exception.to_s) }
70
- end
73
+ span.set_error(exception)
71
74
  end
72
75
 
73
76
  def self.include_stacktrace?(operation_name)
@@ -1,14 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_support/core_ext/module/attribute_accessors"
4
+
3
5
  module Labkit
4
6
  # Tracing provides distributed tracing functionality
5
7
  module Tracing
6
8
  autoload :AbstractInstrumenter, "labkit/tracing/abstract_instrumenter"
9
+ autoload :AutoInitialize, "labkit/tracing/auto_initialize"
7
10
  autoload :TracingCommon, "labkit/tracing/tracing_common"
8
11
  autoload :Factory, "labkit/tracing/factory"
9
12
  autoload :GRPC, "labkit/tracing/grpc"
10
13
  autoload :GRPCInterceptor, "labkit/tracing/grpc_interceptor" # Deprecated
11
14
  autoload :JaegerFactory, "labkit/tracing/jaeger_factory"
15
+ autoload :OpenTelemetryFactory, "labkit/tracing/open_telemetry_factory"
16
+ autoload :OpenTracingFactory, "labkit/tracing/open_tracing_factory"
12
17
  autoload :RackMiddleware, "labkit/tracing/rack_middleware"
13
18
  autoload :Rails, "labkit/tracing/rails"
14
19
  autoload :Redis, "labkit/tracing/redis"
@@ -16,6 +21,21 @@ module Labkit
16
21
  autoload :Sidekiq, "labkit/tracing/sidekiq"
17
22
  autoload :TracingUtils, "labkit/tracing/tracing_utils"
18
23
 
24
+ module Adapters
25
+ autoload :BaseSpan, "labkit/tracing/adapters/base_span"
26
+ autoload :OpentelemetrySpan, "labkit/tracing/adapters/opentelemetry_span"
27
+ autoload :OpentracingSpan, "labkit/tracing/adapters/opentracing_span"
28
+ autoload :BaseTracer, "labkit/tracing/adapters/base_tracer"
29
+ autoload :OpentelemetryTracer, "labkit/tracing/adapters/opentelemetry_tracer"
30
+ autoload :OpentracingTracer, "labkit/tracing/adapters/opentracing_tracer"
31
+ end
32
+
33
+ DEFAULT_SERVICE_NAME = :'labkit-service'
34
+
35
+ # Module-level attribute for storing the configured service name
36
+ # Set by Factory.create_tracer when a tracer is created
37
+ mattr_accessor :configured_service_name, default: DEFAULT_SERVICE_NAME
38
+
19
39
  # Tracing is only enabled when the `GITLAB_TRACING` env var is configured.
20
40
  def self.enabled?
21
41
  connection_string.present?
@@ -25,13 +45,28 @@ module Labkit
25
45
  ENV["GITLAB_TRACING"]
26
46
  end
27
47
 
48
+ def self.otlp_connection?(connection_string = ENV["GITLAB_TRACING"])
49
+ connection_string.to_s.start_with?("#{OpenTelemetryFactory::OTLP_SCHEME}://")
50
+ end
51
+
52
+ def self.opentracing_connection?(connection_string = ENV["GITLAB_TRACING"])
53
+ connection_string.to_s.start_with?("#{OpenTracingFactory::OPENTRACING_SCHEME}://")
54
+ end
55
+
56
+ # Returns the tracing URL template from the GITLAB_TRACING_URL environment variable.
57
+ #
58
+ # @note This method is only useful with OpenTracing and Jaeger. It does not work with
59
+ # OpenTelemetry backends, as they expect trace_id (W3C standard) rather than
60
+ # correlation_id (GitLab-specific) for trace lookups.
61
+ #
62
+ # @return [String, nil] The URL template with placeholders for {{ correlation_id }} and {{ service }}
28
63
  def self.tracing_url_template
29
64
  ENV["GITLAB_TRACING_URL"]
30
65
  end
31
66
 
32
67
  # Check if the current request is being traced.
33
68
  def self.sampled?
34
- context = OpenTracing.active_span&.context
69
+ context = TracingUtils.tracer.active_span&.context
35
70
  context&.respond_to?(:sampled?) && context&.sampled?
36
71
  end
37
72
 
@@ -39,12 +74,36 @@ module Labkit
39
74
  @stacktrace_operations ||= Set.new(ENV["GITLAB_TRACING_INCLUDE_STACKTRACE"].to_s.split(",").map(&:strip))
40
75
  end
41
76
 
77
+ # Checks if tracing URL generation is enabled.
78
+ #
79
+ # @note This method is only useful with OpenTracing and Jaeger. It does not work with
80
+ # OpenTelemetry backends, as they expect trace_id (W3C standard) rather than
81
+ # correlation_id (GitLab-specific) for trace lookups.
82
+ #
83
+ # @return [Boolean] true if both tracing and URL template are configured
84
+ # @see tracing_url
42
85
  def self.tracing_url_enabled?
43
86
  enabled? && tracing_url_template.present?
44
87
  end
45
88
 
46
- # This will provide a link into the distributed tracing for the current trace,
47
- # if it has been captured.
89
+ # Generates a URL to view the current trace in a tracing UI.
90
+ #
91
+ # This method substitutes {{ correlation_id }} and {{ service }} placeholders in the
92
+ # GITLAB_TRACING_URL template with the current correlation ID and provided service name.
93
+ #
94
+ # @note This method is only useful with OpenTracing and Jaeger. It does not work with
95
+ # OpenTelemetry backends because:
96
+ # - Uses correlation_id (GitLab-specific request ID) instead of trace_id (W3C standard)
97
+ # - Modern tracing UIs (Jaeger with OTLP, Grafana Tempo, etc.) expect trace_id for lookups
98
+ # - Only Jaeger's legacy OpenTracing integration supports correlation_id-based URLs
99
+ #
100
+ # @param service_name [String] The name of the service to include in the URL
101
+ # @return [String, nil] The generated URL, or nil if tracing URL is not enabled
102
+ #
103
+ # @example With OpenTracing/Jaeger (supported)
104
+ # ENV["GITLAB_TRACING_URL"] = "https://jaeger.example.com/trace?correlationId={{ correlation_id }}"
105
+ # Labkit::Tracing.tracing_url("my-service")
106
+ # # => "https://jaeger.example.com/trace?correlationId=abc123"
48
107
  def self.tracing_url(service_name)
49
108
  return unless tracing_url_enabled?
50
109
 
@@ -53,8 +112,50 @@ module Labkit
53
112
  # Avoid using `format` since it can throw TypeErrors
54
113
  # which we want to avoid on unsanitised env var input
55
114
  tracing_url_template.to_s
56
- .gsub("{{ correlation_id }}", correlation_id)
57
- .gsub("{{ service }}", service_name)
115
+ .gsub("{{ correlation_id }}", correlation_id)
116
+ .gsub("{{ service }}", service_name)
117
+ end
118
+
119
+ # Returns the underlying tracer implementation from the tracing library in use.
120
+ # This provides direct access to the native tracer API when LabKit's abstraction
121
+ # is insufficient for advanced use cases.
122
+ #
123
+ # @example Using OpenTelemetry-specific APIs
124
+ # tracer = Labkit::Tracing.tracer
125
+ # tracer.in_span("custom-span") do |span|
126
+ # span.add_event("custom-event", attributes: { "key" => "value" })
127
+ # end
128
+ #
129
+ # @return [Object] The tracer implementation:
130
+ # - OpenTelemetry::SDK::Trace::Tracer when using OTLP connection
131
+ # - No-op tracer when tracing is not configured
132
+ def self.tracer
133
+ TracingUtils.tracer.tracer
134
+ end
135
+
136
+ # Returns the currently active span from OpenTelemetry.
137
+ # This provides direct access to the OpenTelemetry span API.
138
+ #
139
+ # @example Adding attributes to the current span
140
+ # span = Labkit::Tracing.current_span
141
+ # span.set_attribute("user.id", user.id) if span.recording?
142
+ #
143
+ # @example Adding events
144
+ # span = Labkit::Tracing.current_span
145
+ # span.add_event("cache_miss", attributes: { "key" => cache_key })
146
+ #
147
+ # @example Conditional expensive operations
148
+ # span = Labkit::Tracing.current_span
149
+ # if span.recording?
150
+ # span.set_attribute("expensive_data", compute_expensive_data)
151
+ # end
152
+ #
153
+ # @return [OpenTelemetry::Trace::Span, nil] The current span (may be a no-op span when tracing is disabled, or nil when using OpenTracing)
154
+ def self.current_span
155
+ return nil if opentracing_connection?
156
+
157
+ require "opentelemetry/sdk"
158
+ OpenTelemetry::Trace.current_span
58
159
  end
59
160
 
60
161
  # This will run a block with a span
@@ -68,3 +169,5 @@ module Labkit
68
169
  end
69
170
  end
70
171
  end
172
+
173
+ require "labkit/tracing/railtie" if defined?(Rails::Railtie)
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "singleton"
4
+
3
5
  module Labkit
4
6
  module UserExperienceSli
5
7
  # Fakes Labkit::UserExperienceSli::Experience.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitlab-labkit
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Newdigate
@@ -131,6 +131,48 @@ dependencies:
131
131
  - - "~>"
132
132
  - !ruby/object:Gem::Version
133
133
  version: 3.3.2
134
+ - !ruby/object:Gem::Dependency
135
+ name: opentelemetry-sdk
136
+ requirement: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - "~>"
139
+ - !ruby/object:Gem::Version
140
+ version: '1.10'
141
+ type: :runtime
142
+ prerelease: false
143
+ version_requirements: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - "~>"
146
+ - !ruby/object:Gem::Version
147
+ version: '1.10'
148
+ - !ruby/object:Gem::Dependency
149
+ name: opentelemetry-instrumentation-all
150
+ requirement: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - "~>"
153
+ - !ruby/object:Gem::Version
154
+ version: 0.89.1
155
+ type: :runtime
156
+ prerelease: false
157
+ version_requirements: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - "~>"
160
+ - !ruby/object:Gem::Version
161
+ version: 0.89.1
162
+ - !ruby/object:Gem::Dependency
163
+ name: opentelemetry-exporter-otlp
164
+ requirement: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - - "~>"
167
+ - !ruby/object:Gem::Version
168
+ version: 0.31.1
169
+ type: :runtime
170
+ prerelease: false
171
+ version_requirements: !ruby/object:Gem::Requirement
172
+ requirements:
173
+ - - "~>"
174
+ - !ruby/object:Gem::Version
175
+ version: 0.31.1
134
176
  - !ruby/object:Gem::Dependency
135
177
  name: opentracing
136
178
  requirement: !ruby/object:Gem::Requirement
@@ -359,6 +401,26 @@ dependencies:
359
401
  - - "~>"
360
402
  - !ruby/object:Gem::Version
361
403
  version: '2.0'
404
+ - !ruby/object:Gem::Dependency
405
+ name: railties
406
+ requirement: !ruby/object:Gem::Requirement
407
+ requirements:
408
+ - - ">="
409
+ - !ruby/object:Gem::Version
410
+ version: 5.0.0
411
+ - - "<"
412
+ - !ruby/object:Gem::Version
413
+ version: 8.1.0
414
+ type: :development
415
+ prerelease: false
416
+ version_requirements: !ruby/object:Gem::Requirement
417
+ requirements:
418
+ - - ">="
419
+ - !ruby/object:Gem::Version
420
+ version: 5.0.0
421
+ - - "<"
422
+ - !ruby/object:Gem::Version
423
+ version: 8.1.0
362
424
  - !ruby/object:Gem::Dependency
363
425
  name: rake
364
426
  requirement: !ruby/object:Gem::Requirement
@@ -540,7 +602,15 @@ files:
540
602
  - lib/labkit/rspec/matchers/user_experience_matchers.rb
541
603
  - lib/labkit/system.rb
542
604
  - lib/labkit/tracing.rb
605
+ - lib/labkit/tracing/README.md
543
606
  - lib/labkit/tracing/abstract_instrumenter.rb
607
+ - lib/labkit/tracing/adapters/base_span.rb
608
+ - lib/labkit/tracing/adapters/base_tracer.rb
609
+ - lib/labkit/tracing/adapters/opentelemetry_span.rb
610
+ - lib/labkit/tracing/adapters/opentelemetry_tracer.rb
611
+ - lib/labkit/tracing/adapters/opentracing_span.rb
612
+ - lib/labkit/tracing/adapters/opentracing_tracer.rb
613
+ - lib/labkit/tracing/auto_initialize.rb
544
614
  - lib/labkit/tracing/external_http.rb
545
615
  - lib/labkit/tracing/external_http/request_instrumenter.rb
546
616
  - lib/labkit/tracing/factory.rb
@@ -549,6 +619,8 @@ files:
549
619
  - lib/labkit/tracing/grpc/server_interceptor.rb
550
620
  - lib/labkit/tracing/grpc_interceptor.rb
551
621
  - lib/labkit/tracing/jaeger_factory.rb
622
+ - lib/labkit/tracing/open_telemetry_factory.rb
623
+ - lib/labkit/tracing/open_tracing_factory.rb
552
624
  - lib/labkit/tracing/rack_middleware.rb
553
625
  - lib/labkit/tracing/rails.rb
554
626
  - lib/labkit/tracing/rails/action_view.rb
@@ -566,6 +638,7 @@ files:
566
638
  - lib/labkit/tracing/rails/active_support/cache_read_instrumenter.rb
567
639
  - lib/labkit/tracing/rails/active_support/cache_write_instrumenter.rb
568
640
  - lib/labkit/tracing/rails/active_support/subscriber.rb
641
+ - lib/labkit/tracing/railtie.rb
569
642
  - lib/labkit/tracing/redis.rb
570
643
  - lib/labkit/tracing/redis/redis_interceptor.rb
571
644
  - lib/labkit/tracing/redis/redis_interceptor_helper.rb