instana 1.217.0 → 2.0.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.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +101 -225
  3. data/.tekton/.currency/scripts/generate_report.py +194 -22
  4. data/.tekton/pipeline.yaml +65 -152
  5. data/.tekton/prepuller-restart-service-account.yaml +31 -0
  6. data/.tekton/ruby-tracer-prepuller-cronjob.yaml +20 -0
  7. data/.tekton/ruby-tracer-prepuller.yaml +27 -26
  8. data/.tekton/task.yaml +31 -27
  9. data/Gemfile +5 -0
  10. data/README.md +2 -1
  11. data/Rakefile +1 -1
  12. data/examples/otel.rb +98 -0
  13. data/examples/tracing.rb +1 -0
  14. data/gemfiles/rails_61.gemfile +1 -0
  15. data/gemfiles/rails_70.gemfile +1 -0
  16. data/instana.gemspec +5 -0
  17. data/lib/instana/base.rb +4 -2
  18. data/lib/instana/instrumentation/action_cable.rb +8 -4
  19. data/lib/instana/instrumentation/action_controller.rb +2 -4
  20. data/lib/instana/instrumentation/action_mailer.rb +1 -1
  21. data/lib/instana/instrumentation/action_view.rb +4 -4
  22. data/lib/instana/instrumentation/active_job.rb +26 -13
  23. data/lib/instana/instrumentation/active_record.rb +1 -1
  24. data/lib/instana/instrumentation/aws_sdk_dynamodb.rb +1 -1
  25. data/lib/instana/instrumentation/aws_sdk_lambda.rb +1 -1
  26. data/lib/instana/instrumentation/aws_sdk_s3.rb +1 -1
  27. data/lib/instana/instrumentation/aws_sdk_sns.rb +1 -1
  28. data/lib/instana/instrumentation/aws_sdk_sqs.rb +1 -1
  29. data/lib/instana/instrumentation/dalli.rb +1 -1
  30. data/lib/instana/instrumentation/excon.rb +2 -2
  31. data/lib/instana/instrumentation/graphql.rb +3 -3
  32. data/lib/instana/instrumentation/grpc.rb +14 -13
  33. data/lib/instana/instrumentation/mongo.rb +3 -3
  34. data/lib/instana/instrumentation/net-http.rb +5 -4
  35. data/lib/instana/instrumentation/rack.rb +36 -4
  36. data/lib/instana/instrumentation/redis.rb +1 -1
  37. data/lib/instana/instrumentation/resque.rb +10 -8
  38. data/lib/instana/instrumentation/rest-client.rb +4 -4
  39. data/lib/instana/instrumentation/sequel.rb +3 -3
  40. data/lib/instana/instrumentation/shoryuken.rb +4 -1
  41. data/lib/instana/instrumentation/sidekiq-client.rb +21 -19
  42. data/lib/instana/instrumentation/sidekiq-worker.rb +22 -21
  43. data/lib/instana/instrumented_logger.rb +1 -1
  44. data/lib/instana/samplers/result.rb +32 -0
  45. data/lib/instana/samplers/samplers.rb +76 -0
  46. data/lib/instana/serverless.rb +4 -2
  47. data/lib/instana/setup.rb +4 -5
  48. data/lib/instana/trace/export.rb +36 -0
  49. data/lib/instana/{tracing → trace}/processor.rb +19 -15
  50. data/lib/instana/trace/span.rb +532 -0
  51. data/lib/instana/{tracing → trace}/span_context.rb +17 -8
  52. data/lib/instana/trace/span_kind.rb +51 -0
  53. data/lib/instana/trace/span_limits.rb +63 -0
  54. data/lib/instana/{tracer.rb → trace/tracer.rb} +106 -54
  55. data/lib/instana/trace/tracer_provider.rb +198 -0
  56. data/lib/instana/trace.rb +74 -0
  57. data/lib/instana/util.rb +11 -0
  58. data/lib/instana/version.rb +1 -1
  59. data/test/frameworks/sinatra_test.rb +2 -1
  60. data/test/instrumentation/aws_test.rb +7 -7
  61. data/test/instrumentation/dalli_test.rb +8 -8
  62. data/test/instrumentation/excon_test.rb +3 -3
  63. data/test/instrumentation/graphql_test.rb +4 -4
  64. data/test/instrumentation/grpc_test.rb +8 -8
  65. data/test/instrumentation/mongo_test.rb +1 -1
  66. data/test/instrumentation/net_http_test.rb +6 -6
  67. data/test/instrumentation/rails_action_cable_test.rb +2 -2
  68. data/test/instrumentation/rails_action_mailer_test.rb +1 -1
  69. data/test/instrumentation/rails_active_job_test.rb +1 -1
  70. data/test/instrumentation/rails_active_record_database_missing_test.rb +2 -3
  71. data/test/instrumentation/rails_active_record_test.rb +8 -7
  72. data/test/instrumentation/redis_test.rb +7 -7
  73. data/test/instrumentation/resque_test.rb +5 -5
  74. data/test/instrumentation/rest_client_test.rb +1 -2
  75. data/test/instrumentation/sequel_test.rb +12 -6
  76. data/test/instrumentation/sidekiq-client_test.rb +2 -2
  77. data/test/instrumentation/sidekiq-worker_test.rb +2 -2
  78. data/test/{tracing → trace}/custom_test.rb +32 -25
  79. data/test/{tracing → trace}/id_management_test.rb +0 -2
  80. data/test/{tracing → trace}/instrumented_logger_test.rb +1 -1
  81. data/test/{tracing → trace}/processor_test.rb +6 -6
  82. data/test/{tracing → trace}/span_context_test.rb +3 -3
  83. data/test/{tracing → trace}/span_test.rb +7 -7
  84. data/test/{tracing → trace}/tracer_async_test.rb +43 -30
  85. data/test/trace/tracer_provider_test.rb +148 -0
  86. data/test/{tracing → trace}/tracer_test.rb +48 -37
  87. metadata +105 -32
  88. data/examples/opentracing.rb +0 -35
  89. data/lib/instana/open_tracing/carrier.rb +0 -7
  90. data/lib/instana/open_tracing/instana_tracer.rb +0 -99
  91. data/lib/instana/tracing/span.rb +0 -431
  92. data/lib/opentracing.rb +0 -32
  93. data/test/tracing/opentracing_test.rb +0 -382
@@ -0,0 +1,532 @@
1
+ # (c) Copyright IBM Corp. 2025
2
+
3
+ require 'opentelemetry'
4
+ require 'instana/trace/span_kind'
5
+
6
+ module Instana
7
+ class Span < OpenTelemetry::Trace::Span
8
+ include SpanKind
9
+
10
+ attr_accessor :parent, :baggage, :is_root, :context
11
+
12
+ def initialize(name, parent_ctx = nil, _context = nil, parent_span = nil, _kind = nil, parent_span_id = nil, _span_limits = nil, _span_processors = nil, attributes = nil, _links = nil, start_timestamp = ::Instana::Util.now_in_ms, _resource = nil, _instrumentation_scope = nil) # rubocop:disable Lint/MissingSuper, Metrics/ParameterLists, Layout/LineLength
13
+ @attributes = {}
14
+
15
+ @ended = false
16
+ if parent_span.is_a?(::Instana::Span)
17
+ @parent = parent_span
18
+ end
19
+ if parent_ctx.is_a?(::Instana::Span)
20
+ @parent = parent_ctx
21
+ parent_ctx = parent_ctx.context
22
+ end
23
+
24
+ if parent_ctx.is_a?(::Instana::SpanContext)
25
+ @is_root = false
26
+
27
+ # If we have a parent trace, link to it
28
+ if parent_ctx.trace_id
29
+ @attributes[:t] = parent_ctx.trace_id # Trace ID
30
+ @attributes[:p] = parent_span_id || parent_ctx.span_id # Parent ID
31
+ else
32
+ @attributes[:t] = ::Instana::Trace.generate_trace_id
33
+ end
34
+
35
+ @attributes[:s] = ::Instana::Trace.generate_span_id # Span ID
36
+
37
+ @baggage = parent_ctx.baggage.dup
38
+ @level = parent_ctx.level
39
+ else
40
+ # No parent specified so we're starting a new Trace - this will be the root span
41
+ @is_root = true
42
+ @level = 1
43
+
44
+ id = ::Instana::Trace.generate_span_id
45
+ @attributes[:t] = id # Trace ID
46
+ @attributes[:s] = id # Span ID
47
+ end
48
+
49
+ @attributes[:data] = {}
50
+
51
+ if ENV.key?('INSTANA_SERVICE_NAME')
52
+ @attributes[:data][:service] = ENV['INSTANA_SERVICE_NAME']
53
+ end
54
+
55
+ # Entity Source
56
+ @attributes[:f] = ::Instana.agent.source
57
+ # Start time
58
+ @attributes[:ts] = if start_timestamp.is_a?(Time)
59
+ ::Instana::Util.time_to_ms(start_timestamp)
60
+ else
61
+ start_timestamp
62
+ end
63
+
64
+ # Check for custom tracing
65
+ if REGISTERED_SPANS.include?(name&.to_sym) # Todo remove the safe & operator once all the tests are adapted to new init structure
66
+ @attributes[:n] = name.to_sym
67
+ else
68
+ configure_custom(name)
69
+ end
70
+ set_tags(attributes)
71
+ ::Instana.processor.on_start(self)
72
+ # Attach a backtrace to all exit spans
73
+ add_stack if ::Instana.config[:collect_backtraces] && exit_span?
74
+ end
75
+
76
+ # Adds a backtrace to this span
77
+ #
78
+ # @param limit [Integer] Limit the backtrace to the top <limit> frames
79
+ #
80
+ def add_stack(limit: 30, stack: Kernel.caller)
81
+ cleaner = ::Instana.config[:backtrace_cleaner]
82
+ stack = cleaner.call(stack) if cleaner
83
+
84
+ @attributes[:stack] = stack
85
+ .map do |call|
86
+ file, line, *method = call.split(':')
87
+
88
+ {
89
+ c: file,
90
+ n: line,
91
+ m: method.join(' ')
92
+ }
93
+ end.take(limit > 40 ? 40 : limit)
94
+ end
95
+
96
+ # Log an error into the span
97
+ #
98
+ # @param e [Exception] The exception to be logged
99
+ #
100
+ def record_exception(error)
101
+ @attributes[:error] = true
102
+
103
+ @attributes[:ec] = if @attributes.key?(:ec)
104
+ @attributes[:ec] + 1
105
+ else
106
+ 1
107
+ end
108
+
109
+ # If a valid exception has been passed in, log the information about it
110
+ # In case of just logging an error for things such as HTTP client 5xx
111
+ # responses, an exception/backtrace may not exist.
112
+ if error
113
+ if error.backtrace.is_a?(Array)
114
+ add_stack(stack: error.backtrace)
115
+ end
116
+
117
+ if HTTP_SPANS.include?(@attributes[:n])
118
+ set_tags(:http => { :error => "#{error.class}: #{error.message}" })
119
+ elsif @attributes[:n] == :activerecord
120
+ @attributes[:data][:activerecord][:error] = error.message
121
+ else
122
+ log(:error, Time.now, message: error.message, parameters: error.class.to_s)
123
+ end
124
+ error.instance_variable_set(:@instana_logged, true)
125
+ end
126
+ self
127
+ end
128
+
129
+ # Configure this span to be a custom span per the
130
+ # SDK generic span type.
131
+ #
132
+ # Default to an intermediate kind span. Can be overridden by
133
+ # setting a span.kind tag.
134
+ #
135
+ # @param name [String] name of the span
136
+ # @param kvs [Hash] list of key values to be reported in the span
137
+ #
138
+ def configure_custom(name)
139
+ @attributes[:n] = :sdk
140
+ @attributes[:data] = { :sdk => { :name => name&.to_sym } } # Todo remove safe operator once other tests adapt to new init structure
141
+ @attributes[:data][:sdk][:custom] = { :tags => {}, :logs => {} }
142
+
143
+ if @is_root
144
+ # For custom root spans (via SDK or opentracing), default to entry type
145
+ @attributes[:k] = 1
146
+ @attributes[:data][:sdk][:type] = :entry
147
+ else
148
+ @attributes[:k] = 3
149
+ @attributes[:data][:sdk][:type] = :intermediate
150
+ end
151
+ self
152
+ end
153
+
154
+ # Closes out the span. This difference between this and
155
+ # the finish method tells us how the tracing is being
156
+ # performed (with OpenTracing or Instana default)
157
+ #
158
+ # @param end_time [Time] custom end time, if not now
159
+ # @return [Span]
160
+ #
161
+ def close(end_time = ::Instana::Util.now_in_ms)
162
+ if end_time.is_a?(Time)
163
+ end_time = ::Instana::Util.time_to_ms(end_time)
164
+ end
165
+
166
+ @attributes[:d] = end_time - @attributes[:ts]
167
+ @ended = true
168
+ # Add this span to the queue for reporting
169
+ ::Instana.processor.on_finish(self)
170
+
171
+ self
172
+ end
173
+
174
+ #############################################################
175
+ # Accessors
176
+ #############################################################
177
+
178
+ # Retrieve the context of this span.
179
+ #
180
+ # @return [Instana::SpanContext]
181
+ #
182
+ def context # rubocop:disable Lint/DuplicateMethods
183
+ @context ||= ::Instana::SpanContext.new(trace_id: @attributes[:t], span_id: @attributes[:s], level: @level, baggage: @baggage)
184
+ end
185
+
186
+ # Retrieve the ID for this span
187
+ #
188
+ # @return [Integer] the span ID
189
+ def id
190
+ @attributes[:s]
191
+ end
192
+
193
+ # Retrieve the Trace ID for this span
194
+ #
195
+ # @return [Integer] the Trace ID
196
+ def trace_id
197
+ @attributes[:t]
198
+ end
199
+
200
+ # Retrieve the parent ID of this span
201
+ #
202
+ # @return [Integer] parent span ID
203
+ def parent_id
204
+ @attributes[:p]
205
+ end
206
+
207
+ # Set the parent ID of this span
208
+ #
209
+ # @return [Integer] parent span ID
210
+ def parent_id=(id)
211
+ @attributes[:p] = id
212
+ end
213
+
214
+ # Get the name (operation) of this Span
215
+ #
216
+ # @return [String] or [Symbol] representing the span name
217
+ def name
218
+ if custom?
219
+ @attributes[:data][:sdk][:name]
220
+ else
221
+ @attributes[:n]
222
+ end
223
+ end
224
+
225
+ # Set the name (operation) for this Span
226
+ #
227
+ # @params name [String] or [Symbol]
228
+ #
229
+ def name=(name)
230
+ if custom?
231
+ @attributes[:data][:sdk][:name] = name
232
+ else
233
+ @attributes[:n] = name
234
+ end
235
+ end
236
+
237
+ # Get the duration value for this Span
238
+ #
239
+ # @return [Integer] the duration in milliseconds
240
+ def duration
241
+ @attributes[:d]
242
+ end
243
+
244
+ # Hash accessor to the internal @attributes hash
245
+ #
246
+ def [](key)
247
+ @attributes[key.to_sym]
248
+ end
249
+
250
+ # Hash setter to the internal @attributes hash
251
+ #
252
+ def []=(key, value)
253
+ @attributes[key.to_sym] = value
254
+ end
255
+
256
+ # Hash key query to the internal @attributes hash
257
+ #
258
+ def key?(key)
259
+ @attributes.key?(key.to_sym)
260
+ end
261
+
262
+ # Get the raw @attributes hash that summarizes this span
263
+ #
264
+ def raw
265
+ @attributes
266
+ end
267
+
268
+ # Indicates whether this span is a custom or registered Span
269
+ def custom?
270
+ @attributes[:n] == :sdk
271
+ end
272
+
273
+ def inspect
274
+ @attributes.inspect
275
+ end
276
+
277
+ # Check to see if the current span indicates an exit from application
278
+ # code and into an external service
279
+ def exit_span?
280
+ EXIT_SPANS.include?(@attributes[:n])
281
+ end
282
+
283
+ #############################################################
284
+ # OpenTracing Compatibility Methods
285
+ #############################################################
286
+
287
+ # Set the name of the operation
288
+ # Spec: OpenTracing API
289
+ #
290
+ # @params name [String] or [Symbol]
291
+ #
292
+ def operation_name=(name)
293
+ @attributes[:n] = name
294
+ end
295
+
296
+ # Set a tag value on this span
297
+ # Spec: OpenTracing API
298
+ #
299
+ # @param key [String] the key of the tag
300
+ # @param value [String, Numeric, Boolean] the value of the tag. If it's not
301
+ # a String, Numeric, or Boolean it will be encoded with to_s
302
+ #
303
+ def set_tag(key, value)
304
+ unless [Symbol, String].include?(key.class)
305
+ key = key.to_s
306
+ end
307
+
308
+ # If <value> is not a Symbol, String, Array, Hash or Numeric - convert to string
309
+ if ![Symbol, String, Array, TrueClass, FalseClass, Hash].include?(value.class) && !value.is_a?(Numeric)
310
+ value = value.to_s
311
+ end
312
+
313
+ if custom?
314
+ @attributes[:data][:sdk][:custom] ||= {}
315
+ @attributes[:data][:sdk][:custom][:tags] ||= {}
316
+ @attributes[:data][:sdk][:custom][:tags][key] = value
317
+
318
+ if key.to_sym == :'span.kind'
319
+ case value.to_sym
320
+ when ENTRY, SERVER, CONSUMER
321
+ @attributes[:data][:sdk][:type] = ENTRY
322
+ @attributes[:k] = 1
323
+ when EXIT, CLIENT, PRODUCER
324
+ @attributes[:data][:sdk][:type] = EXIT
325
+ @attributes[:k] = 2
326
+ else
327
+ @attributes[:data][:sdk][:type] = INTERMEDIATE
328
+ @attributes[:k] = 3
329
+ end
330
+ end
331
+ elsif value.is_a?(Hash) && @attributes[:data][key].is_a?(Hash)
332
+ @attributes[:data][key].merge!(value)
333
+ else
334
+ @attributes[:data][key] = value
335
+ end
336
+ self
337
+ end
338
+
339
+ # Helper method to add multiple tags to this span
340
+ #
341
+ # @params tags [Hash]
342
+ # @return [Span]
343
+ #
344
+ def set_tags(tags) # rubocop:disable Naming
345
+ return unless tags.is_a?(Hash)
346
+
347
+ tags.each do |k, v|
348
+ set_tag(k, v)
349
+ end
350
+ self
351
+ end
352
+
353
+ # Set a baggage item on the span
354
+ # Spec: OpenTracing API
355
+ #
356
+ # @param key [String] the key of the baggage item
357
+ # @param value [String] the value of the baggage item
358
+ # Todo Evalute if baggage is used anywhere in instana
359
+ def set_baggage_item(key, value)
360
+ @baggage ||= {}
361
+ @baggage[key] = value
362
+
363
+ # Init/Update the SpanContext item
364
+ if @context
365
+ @context.baggage = @baggage
366
+ else
367
+ @context ||= ::Instana::SpanContext.new(trace_id: @attributes[:t], span_id: @attributes[:s], level: @level, baggage: @baggage)
368
+ end
369
+ self
370
+ end
371
+
372
+ # Get a baggage item
373
+ # Spec: OpenTracing API
374
+ #
375
+ # @param key [String] the key of the baggage item
376
+ # @return Value of the baggage item
377
+ #
378
+ def get_baggage_item(key)
379
+ @baggage[key]
380
+ end
381
+
382
+ # Retrieve the hash of tags for this span
383
+ #
384
+ def tags(key = nil)
385
+ tags = if custom?
386
+ @attributes[:data][:sdk][:custom][:tags]
387
+ else
388
+ @attributes[:data]
389
+ end
390
+ key ? tags[key] : tags
391
+ end
392
+
393
+ # Add a log entry to this span
394
+ # Spec: OpenTracing API
395
+ #
396
+ # @param event [String] event name for the log
397
+ # @param timestamp [Time] time of the log
398
+ # @param fields [Hash] Additional information to log
399
+ #
400
+ def log(event = nil, timestamp = Time.now, **fields)
401
+ ts = ::Instana::Util.time_to_ms(timestamp).to_s
402
+ if custom?
403
+ @attributes[:data][:sdk][:custom][:logs][ts] = fields
404
+ @attributes[:data][:sdk][:custom][:logs][ts][:event] = event
405
+ else
406
+ set_tags(:log => fields)
407
+ end
408
+ rescue StandardError => e
409
+ Instana.logger.debug { "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" }
410
+ end
411
+
412
+ # Finish the {Span}
413
+ # Spec: OpenTracing API
414
+ #
415
+ # @param end_time [Time] custom end time, if not now
416
+ #
417
+ def finish(end_time = ::Instana::Util.now_in_ms)
418
+ close(end_time)
419
+ ::Instana.tracer.current_span = ::Instana.tracer.current_span&.parent || nil
420
+ self
421
+ end
422
+
423
+ # Return the flag whether this span is recording events
424
+ #
425
+ # @return [Boolean] true if this Span is active and recording information
426
+ # like events with the #add_event operation and attributes using
427
+ # #set_attribute.
428
+ def recording?
429
+ !@ended
430
+ end
431
+
432
+ # Set attribute
433
+ #
434
+ # Note that the OpenTelemetry project
435
+ # {https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/data-semantic-conventions.md
436
+ # documents} certain "standard attributes" that have prescribed semantic
437
+ # meanings.
438
+ #
439
+ # @param [String] key
440
+ # @param [String, Boolean, Numeric, Array<String, Numeric, Boolean>] value
441
+ # Values must be non-nil and (array of) string, boolean or numeric type.
442
+ # Array values must not contain nil elements and all elements must be of
443
+ # the same basic type (string, numeric, boolean).
444
+ #
445
+ # @return [self] returns itself
446
+ def set_attribute(key, value)
447
+ @attributes ||= {}
448
+ @attributes[key] = value
449
+ self
450
+ end
451
+ # alias []= set_attribute
452
+
453
+ # Add attributes
454
+ #
455
+ # Note that the OpenTelemetry project
456
+ # {https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/data-semantic-conventions.md
457
+ # documents} certain "standard attributes" that have prescribed semantic
458
+ # meanings.
459
+ #
460
+ # @param [Hash{String => String, Numeric, Boolean, Array<String, Numeric, Boolean>}] attributes
461
+ # Values must be non-nil and (array of) string, boolean or numeric type.
462
+ # Array values must not contain nil elements and all elements must be of
463
+ # the same basic type (string, numeric, boolean).
464
+ #
465
+ # @return [self] returns itself
466
+ def add_attributes(attributes)
467
+ @attributes ||= {}
468
+ @attributes.merge!(attributes)
469
+ self
470
+ end
471
+
472
+ # Add a link to a {Span}.
473
+ #
474
+ # Adding links at span creation using the `links` option is preferred
475
+ # to calling add_link later, because head sampling decisions can only
476
+ # consider information present during span creation.
477
+ #
478
+ # Example:
479
+ #
480
+ # span.add_link(OpenTelemetry::Trace::Link.new(span_to_link_from.context))
481
+ #
482
+ # Note that the OpenTelemetry project
483
+ # {https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/data-semantic-conventions.md
484
+ # documents} certain "standard attributes" that have prescribed semantic
485
+ # meanings.
486
+ #
487
+ # @param [OpenTelemetry::Trace::Link] the link object to add on the {Span}.
488
+ #
489
+ # @return [self] returns itself
490
+ # Todo add link logic later
491
+ def add_link(_link)
492
+ self
493
+ end
494
+
495
+ # Add an event to a {Span}.
496
+ #
497
+ # Example:
498
+ #
499
+ # span.add_event('event', attributes: {'eager' => true})
500
+ #
501
+ # Note that the OpenTelemetry project
502
+ # {https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/data-semantic-conventions.md
503
+ # documents} certain "standard event names and keys" which have
504
+ # prescribed semantic meanings.
505
+ #
506
+ # @param [String] name Name of the event.
507
+ # @param [optional Hash{String => String, Numeric, Boolean, Array<String, Numeric, Boolean>}]
508
+ # attributes One or more key:value pairs, where the keys must be
509
+ # strings and the values may be (array of) string, boolean or numeric
510
+ # type.
511
+ # @param [optional Time] timestamp Optional timestamp for the event.
512
+ #
513
+ # @return [self] returns itself
514
+ # Todo Add the vent logic later
515
+ def add_event(_name, attributes: nil, timestamp: nil) # rubocop:disable Lint/UnusedMethodArgument
516
+ self
517
+ end
518
+
519
+ # Sets the Status to the Span
520
+ #
521
+ # If used, this will override the default Span status. Default status is unset.
522
+ #
523
+ # Only the value of the last call will be recorded, and implementations
524
+ # are free to ignore previous calls.
525
+ #
526
+ # @param [Status] status The new status, which overrides the default Span
527
+ # status, which is OK.
528
+ #
529
+ # @return [void]
530
+ def status=(status); end
531
+ end
532
+ end
@@ -2,10 +2,8 @@
2
2
  # (c) Copyright Instana Inc. 2017
3
3
 
4
4
  module Instana
5
- class SpanContext
6
- attr_accessor :trace_id
7
- attr_accessor :span_id
8
- attr_accessor :baggage
5
+ class SpanContext < OpenTelemetry::Trace::SpanContext
6
+ attr_accessor :trace_id, :span_id, :baggage
9
7
  attr_reader :level
10
8
 
11
9
  # Create a new SpanContext
@@ -15,9 +13,20 @@ module Instana
15
13
  # @param level [Integer] default 1
16
14
  # @param baggage [Hash] baggage applied to this trace
17
15
  #
18
- def initialize(tid, sid, level = 1, baggage = {})
19
- @trace_id = tid
20
- @span_id = sid
16
+ def initialize( # rubocop:disable Lint/MissingSuper, Metrics/ParameterLists
17
+ trace_id: Trace.generate_trace_id,
18
+ span_id: Trace.generate_span_id,
19
+ trace_flags: OpenTelemetry::Trace::TraceFlags::DEFAULT, # Todo - implement traceflags
20
+ tracestate: OpenTelemetry::Trace::Tracestate::DEFAULT, # Todo - implement tracestates
21
+ remote: false,
22
+ level: 1,
23
+ baggage: {}
24
+ )
25
+ @trace_id = trace_id
26
+ @span_id = span_id
27
+ @trace_flags = trace_flags
28
+ @tracestate = tracestate
29
+ @remote = remote
21
30
  @level = Integer(level || 1)
22
31
  @baggage = baggage || {}
23
32
  end
@@ -55,7 +64,7 @@ module Instana
55
64
  end
56
65
 
57
66
  def valid?
58
- @baggage && @trace_id && !@trace_id.emtpy?
67
+ @baggage && @trace_id && !@trace_id.empty?
59
68
  end
60
69
 
61
70
  def active?
@@ -0,0 +1,51 @@
1
+ # (c) Copyright IBM Corp. 2025
2
+
3
+ module Instana
4
+ # Type of span. Can be used to specify additional relationships between spans in addition to a
5
+ # parent/child relationship. For API ergonomics, use of the symbols rather than the constants
6
+ # may be preferred. For example:
7
+ #
8
+ # span = tracer.on_start('op', kind: :client)
9
+ module SpanKind
10
+ # Instana specific spans
11
+ REGISTERED_SPANS = [:actioncontroller, :actionview, :activerecord, :excon,
12
+ :memcache, :'net-http', :rack, :render, :'rpc-client',
13
+ :'rpc-server', :'sidekiq-client', :'sidekiq-worker',
14
+ :redis, :'resque-client', :'resque-worker', :'graphql.server', :dynamodb, :s3, :sns, :sqs, :'aws.lambda.entry', :activejob, :log, :"mail.actionmailer",
15
+ :"aws.lambda.invoke", :mongo, :sequel].freeze
16
+ ENTRY_SPANS = [:rack, :'resque-worker', :'rpc-server', :'sidekiq-worker', :'graphql.server', :sqs,
17
+ :'aws.lambda.entry'].freeze
18
+ EXIT_SPANS = [:activerecord, :excon, :'net-http', :'resque-client',
19
+ :'rpc-client', :'sidekiq-client', :redis, :dynamodb, :s3, :sns, :sqs, :log, :"mail.actionmailer",
20
+ :"aws.lambda.invoke", :mongo, :sequel].freeze
21
+ HTTP_SPANS = [:rack, :excon, :'net-http'].freeze
22
+
23
+ # Default value. Indicates that the span is used internally.
24
+ INTERNAL = :internal
25
+
26
+ # Indicates that the span covers server-side handling of an RPC or other remote request.
27
+ SERVER = :server
28
+
29
+ # Indicates that the span covers the client-side wrapper around an RPC or other remote request.
30
+ CLIENT = :client
31
+
32
+ # Indicates that the span describes producer sending a message to a broker. Unlike client and
33
+ # server, there is no direct critical path latency relationship between producer and consumer
34
+ # spans.
35
+ PRODUCER = :producer
36
+
37
+ # Indicates that the span describes consumer receiving a message from a broker. Unlike client
38
+ # and server, there is no direct critical path latency relationship between producer and
39
+ # consumer spans.
40
+ CONSUMER = :consumer
41
+
42
+ # Indicates an entry span. Equivalant to Server or Consumer
43
+ ENTRY = :entry
44
+
45
+ # Indicates an exit span. Equivalant to Client or Producer
46
+ EXIT = :exit
47
+
48
+ # Indicates an intermediate span. This used when sdk is used to produce intermediate traces
49
+ INTERMEDIATE = :intermediate
50
+ end
51
+ end
@@ -0,0 +1,63 @@
1
+ # (c) Copyright IBM Corp. 2025
2
+
3
+ require 'opentelemetry-common'
4
+
5
+ module Instana
6
+ module Trace
7
+ # Class that holds global trace parameters.
8
+ class SpanLimits
9
+ # The global default max number of attributes per {Span}.
10
+ attr_reader :attribute_count_limit
11
+
12
+ # The global default max length of attribute value per {Span}.
13
+ attr_reader :attribute_length_limit
14
+
15
+ # The global default max number of {OpenTelemetry::SDK::Trace::Event}s per {Span}.
16
+ attr_reader :event_count_limit
17
+
18
+ # The global default max number of {OpenTelemetry::Trace::Link} entries per {Span}.
19
+ attr_reader :link_count_limit
20
+
21
+ # The global default max number of attributes per {OpenTelemetry::SDK::Trace::Event}.
22
+ attr_reader :event_attribute_count_limit
23
+
24
+ # The global default max length of attribute value per {OpenTelemetry::SDK::Trace::Event}.
25
+ attr_reader :event_attribute_length_limit
26
+
27
+ # The global default max number of attributes per {OpenTelemetry::Trace::Link}.
28
+ attr_reader :link_attribute_count_limit
29
+
30
+ # Returns a {SpanLimits} with the desired values.
31
+ #
32
+ # @return [SpanLimits] with the desired values.
33
+ # @raise [ArgumentError] if any of the max numbers are not positive.
34
+ def initialize(attribute_count_limit: Integer(OpenTelemetry::Common::Utilities.config_opt('OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT', 'OTEL_ATTRIBUTE_COUNT_LIMIT', default: 128)), # rubocop:disable Metrics/ParameterLists
35
+ attribute_length_limit: OpenTelemetry::Common::Utilities.config_opt('OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT', 'OTEL_RUBY_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT',
36
+ 'OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT'),
37
+ event_count_limit: Integer(OpenTelemetry::Common::Utilities.config_opt('OTEL_SPAN_EVENT_COUNT_LIMIT', default: 128)),
38
+ link_count_limit: Integer(OpenTelemetry::Common::Utilities.config_opt('OTEL_SPAN_LINK_COUNT_LIMIT', default: 128)),
39
+ event_attribute_count_limit: Integer(OpenTelemetry::Common::Utilities.config_opt('OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT', default: 128)),
40
+ event_attribute_length_limit: OpenTelemetry::Common::Utilities.config_opt('OTEL_EVENT_ATTRIBUTE_VALUE_LENGTH_LIMIT', 'OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT'),
41
+ link_attribute_count_limit: Integer(OpenTelemetry::Common::Utilities.config_opt('OTEL_LINK_ATTRIBUTE_COUNT_LIMIT', default: 128)))
42
+ raise ArgumentError, 'attribute_count_limit must be positive' unless attribute_count_limit.positive?
43
+ raise ArgumentError, 'attribute_length_limit must not be less than 32' unless attribute_length_limit.nil? || Integer(attribute_length_limit) >= 32
44
+ raise ArgumentError, 'event_count_limit must be positive' unless event_count_limit.positive?
45
+ raise ArgumentError, 'link_count_limit must be positive' unless link_count_limit.positive?
46
+ raise ArgumentError, 'event_attribute_count_limit must be positive' unless event_attribute_count_limit.positive?
47
+ raise ArgumentError, 'event_attribute_length_limit must not be less than 32' unless event_attribute_length_limit.nil? || Integer(event_attribute_length_limit) >= 32
48
+ raise ArgumentError, 'link_attribute_count_limit must be positive' unless link_attribute_count_limit.positive?
49
+
50
+ @attribute_count_limit = attribute_count_limit
51
+ @attribute_length_limit = attribute_length_limit.nil? ? nil : Integer(attribute_length_limit)
52
+ @event_count_limit = event_count_limit
53
+ @link_count_limit = link_count_limit
54
+ @event_attribute_count_limit = event_attribute_count_limit
55
+ @event_attribute_length_limit = event_attribute_length_limit.nil? ? nil : Integer(event_attribute_length_limit)
56
+ @link_attribute_count_limit = link_attribute_count_limit
57
+ end
58
+
59
+ # The default {SpanLimits}.
60
+ DEFAULT = new
61
+ end
62
+ end
63
+ end