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.



429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
# File 'lib/temporalio/contrib/open_telemetry.rb', line 429

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] #: TracingInterceptor?
  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?

  # If there is no span on the context and the user hasn't opted in to always creating, do not create. This
  # prevents orphans if there was no span originally created from the client start-workflow call.
  if ::OpenTelemetry::Trace.current_span == ::OpenTelemetry::Trace::Span::INVALID &&
     !root._always_create_workflow_spans
    return nil
  end

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

  # Create span, which has to be done with illegal call disabling because OTel asks for full exception message
  # which uses error highlighting and such which accesses File#path
  Temporalio::Workflow::Unsafe.illegal_call_tracing_disabled do
    time = Temporalio::Workflow.now.dup
    span = root.tracer.start_span(name, attributes:, links:, start_timestamp: time, kind:) # steep:ignore
    # Record exception if present
    span.record_exception(exception) if exception
    # Finish the span (returns self)
    span.finish(end_timestamp: time)
  end
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.



398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
# File 'lib/temporalio/contrib/open_telemetry.rb', line 398

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