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:
- Set emitter BEFORE starting Async execution
- During Async execution, only emit() (reads emitter)
- Each event includes agent context for identification
Testing
# Inject a test emitter
LogStream.emitter = TestEmitter.new
# ... run tests ...
LogStream.reset!
Class Method Summary collapse
-
.emit(**data) ⇒ void
Emit a log event.
-
.emit_error(error, source:, context:, agent: nil, **metadata) ⇒ void
Emit an internal error event.
-
.emitter ⇒ #emit?
Get the current emitter.
-
.emitter=(emitter) ⇒ void
Set the emitter (for dependency injection in tests).
-
.enabled? ⇒ Boolean
Check if logging is enabled.
-
.reset! ⇒ void
Reset the emitter (for test cleanup).
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.
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.
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., 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
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.
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
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 |