Module: SwarmSDK::LogStream

Defined in:
lib/swarm_sdk/log_stream.rb

Overview

LogStream provides a module-level singleton for emitting log events.

This allows any component (tools, providers, agents) to emit structured log events without needing references to logger instances.

Usage

# Emit an event from anywhere in the SDK
LogStream.emit(
type: "user_prompt",
agent: :backend,
model: "claude-sonnet-4",
message_count: 5
)

Thread Safety

LogStream is thread-safe and fiber-safe:

  • Uses Fiber storage for per-request isolation in multi-threaded servers (Puma, Sidekiq)
  • Each thread/request has its own emitter instance
  • Child fibers inherit the emitter from their parent fiber
  • No cross-thread contamination of log events

Usage pattern:

  1. Set emitter BEFORE starting Async execution
  2. During Async execution, only emit() (reads emitter)
  3. Each event includes agent context for identification

Testing

# Inject a test emitter
LogStream.emitter = TestEmitter.new
# ... run tests ...
LogStream.reset!

Class Method Summary collapse

Class Method Details

.emit(**data) ⇒ void

This method returns an undefined value.

Emit a log event

Adds timestamp and forwards to the registered emitter. Auto-injects execution_id, swarm_id, and parent_swarm_id from Fiber storage. Explicit values in data override auto-injected ones.

Parameters:

  • data (Hash)

    Event data (type, agent, and event-specific fields)



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/swarm_sdk/log_stream.rb', line 49

def emit(**data)
  emitter = Fiber[:log_stream_emitter]
  return unless emitter

  # Auto-inject execution context from Fiber storage
  # Explicit values in data override auto-injected ones
  auto_injected = {
    execution_id: Fiber[:execution_id],
    swarm_id: Fiber[:swarm_id],
    parent_swarm_id: Fiber[:parent_swarm_id],
  }.compact

  entry = auto_injected.merge(data).merge(timestamp: Time.now.utc.iso8601(6)).compact

  emitter.emit(entry)
end

.emit_error(error, source:, context:, agent: nil, **metadata) ⇒ void

This method returns an undefined value.

Emit an internal error event

Provides consistent error event emission for all internal errors. These are errors that occur during execution but are handled gracefully (with fallback behavior) rather than causing failures.

Parameters:

  • error (Exception)

    The caught exception

  • source (String)

    Source module/class (e.g., "hook_triggers", "context_compactor")

  • context (String)

    Specific operation context (e.g., "swarm_stop", "summarization")

  • agent (Symbol, String, nil) (defaults to: nil)

    Agent name if applicable

  • metadata (Hash)

    Additional context data



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/swarm_sdk/log_stream.rb', line 109

def emit_error(error, source:, context:, agent: nil, **)
  emit(
    type: "internal_error",
    source: source,
    context: context,
    agent: agent,
    error_class: error.class.name,
    error_message: error.message,
    backtrace: error.backtrace&.first(5),
    **,
  )
rescue StandardError
  # Absolute fallback - if emit_error itself fails, don't break execution
  # This should never happen, but we must be defensive
  nil
end

.emitter#emit?

Get the current emitter

Returns:

  • (#emit, nil)

    Current emitter or nil if not set



79
80
81
# File 'lib/swarm_sdk/log_stream.rb', line 79

def emitter
  Fiber[:log_stream_emitter]
end

.emitter=(emitter) ⇒ void

This method returns an undefined value.

Set the emitter (for dependency injection in tests)

Stores emitter in Fiber storage for thread-safe, per-request isolation.

Parameters:

  • emitter (#emit)

    Object responding to emit(Hash)



72
73
74
# File 'lib/swarm_sdk/log_stream.rb', line 72

def emitter=(emitter)
  Fiber[:log_stream_emitter] = emitter
end

.enabled?Boolean

Check if logging is enabled

Returns:

  • (Boolean)

    true if an emitter is configured



93
94
95
# File 'lib/swarm_sdk/log_stream.rb', line 93

def enabled?
  !Fiber[:log_stream_emitter].nil?
end

.reset!void

This method returns an undefined value.

Reset the emitter (for test cleanup)



86
87
88
# File 'lib/swarm_sdk/log_stream.rb', line 86

def reset!
  Fiber[:log_stream_emitter] = nil
end