Module: Temporalio::Contrib::OpenTelemetry::Workflow

Defined in:
lib/temporalio/contrib/open_telemetry.rb

Overview

Contains workflow methods that can be used for OpenTelemetry.

Class Method Summary collapse

Class Method Details

.completed_span(name, attributes: {}, links: nil, kind: nil, exception: nil, even_during_replay: false) ⇒ OpenTelemetry::Trace::Span?

Note:

WARNING: It is UNSAFE to rely on the result of this method as it may be different/absent on replay.

Create a completed span only if not replaying (or ‘even_during_replay` is true).

Parameters:

  • name (String)

    Span name.

  • attributes (Hash) (defaults to: {})

    Span attributes. These will have workflow and run ID automatically added.

  • links (Array, nil) (defaults to: nil)

    Span links.

  • kind (Symbol, nil) (defaults to: nil)

    Span kind.

  • exception (Exception, nil) (defaults to: nil)

    Exception to record on the span.

  • even_during_replay (Boolean) (defaults to: false)

    Set to true to record this span even during replay. Most users should never set this.

Returns:

  • (OpenTelemetry::Trace::Span, nil)

    Span if one was created. WARNING: It is UNSAFE to use this value.



417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
# File 'lib/temporalio/contrib/open_telemetry.rb', line 417

def self.completed_span(
  name,
  attributes: {},
  links: nil,
  kind: nil,
  exception: nil,
  even_during_replay: false
)
  # Get root interceptor, which also checks if in workflow
  root = Temporalio::Workflow.storage[:__temporal_opentelemetry_tracing_interceptor]
  raise 'Tracing interceptor not configured' unless root

  # Do nothing if replaying and not wanted during replay
  return nil if !even_during_replay && Temporalio::Workflow::Unsafe.replaying?

  # Do nothing if there is no span on the context. We do not want orphan spans coming from workflows, so we
  # require a parent (i.e. a current).
  # TODO(cretz): This matches Python behavior but not .NET behavior (which will create no matter what), is that
  # ok?
  return nil if ::OpenTelemetry::Trace.current_span == ::OpenTelemetry::Trace::Span::INVALID

  # Create attributes, adding user-defined ones
  attributes = { 'temporalWorkflowID' => Temporalio::Workflow.info.workflow_id,
                 'temporalRunID' => Temporalio::Workflow.info.run_id }.merge(attributes)

  # Create span
  time = Temporalio::Workflow.now
  timestamp = (time.to_i * 1_000_000_000) + time.nsec
  span = root.tracer.start_span(name, attributes:, links:, start_timestamp: timestamp, kind:) # steep:ignore
  # Record exception if present
  span.record_exception(exception) if exception
  # Finish the span (returns self)
  span.finish(end_timestamp: timestamp)
end

.with_completed_span(name, attributes: {}, links: nil, kind: nil, exception: nil, even_during_replay: false) { ... } ⇒ Object

Create a completed span and execute block with the span set on the context.

Parameters:

  • name (String)

    Span name.

  • attributes (Hash) (defaults to: {})

    Span attributes. These will have workflow and run ID automatically added.

  • links (Array, nil) (defaults to: nil)

    Span links.

  • kind (Symbol, nil) (defaults to: nil)

    Span kind.

  • exception (Exception, nil) (defaults to: nil)

    Exception to record on the span.

  • even_during_replay (Boolean) (defaults to: false)

    Set to true to record this span even during replay. Most users should never set this.

Yields:

  • Block to call. It is UNSAFE to expect any parameters in this block.

Returns:

  • (Object)

    Result of the block.



386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
# File 'lib/temporalio/contrib/open_telemetry.rb', line 386

def self.with_completed_span(
  name,
  attributes: {},
  links: nil,
  kind: nil,
  exception: nil,
  even_during_replay: false
)
  span = completed_span(name, attributes:, links:, kind:, exception:, even_during_replay:)
  if span
    ::OpenTelemetry::Trace.with_span(span) do # rubocop:disable Style/ExplicitBlockArgument
      # Yield with no parameters
      yield
    end
  else
    yield
  end
end