Module: TypedOperation::Instrumentation
- Defined in:
- lib/typed_operation/instrumentation.rb,
lib/typed_operation/instrumentation/trace.rb,
lib/typed_operation/instrumentation/tree_formatter.rb
Overview
Provides runtime tracing and debugging capabilities for operations.
Usage:
# Trace a single operation call
result = MyOperation.explain(param: value)
# Prints execution tree to stdout, returns the operation result
# Trace with partial application
result = MyOperation.with(partial: value).explain(rest: value)
# Trace a block of code (captures all instrumented operations)
TypedOperation::Instrumentation.explaining do
MyOperation.call(params)
AnotherOperation.call(other_params)
end
# Configure output and color
TypedOperation::Instrumentation.with_output(my_io, color: false) do
MyOperation.explain(param: value)
end
Defined Under Namespace
Modules: Explainable, Traceable Classes: BlockExecution, Trace, TreeFormatter
Constant Summary collapse
- THREAD_KEY =
: Symbol
:typed_operation_trace_stack- CHAIN_CONTEXT_KEY =
: Symbol
:typed_operation_chain_context- OUTPUT_KEY =
: Symbol
:typed_operation_output- COLOR_KEY =
: Symbol
:typed_operation_color
Class Method Summary collapse
-
.clear_trace! ⇒ Object
: () -> void.
-
.color ⇒ Object
: () -> bool.
-
.current_trace ⇒ Object
: () -> Trace?.
-
.explaining(&block) ⇒ Object
Execute a block with tracing enabled, printing the trace tree afterward.
-
.output ⇒ Object
: () -> IO.
-
.pop_trace ⇒ Object
: () -> Trace?.
-
.push_trace(trace) ⇒ Object
: (Trace) -> void.
-
.set_chain_context(pass_mode:, extracted_params: nil, fallback_used: false) ⇒ Object
: (pass_mode: Symbol, ?extracted_params: Array?, ?fallback_used: bool) -> void.
-
.take_chain_context ⇒ Object
: () -> Hash[Symbol, untyped]?.
-
.tracing? ⇒ Boolean
: () -> bool.
-
.with_output(io, color: nil, &block) ⇒ Object
Execute a block with custom output and color settings.
Class Method Details
.clear_trace! ⇒ Object
: () -> void
113 114 115 116 |
# File 'lib/typed_operation/instrumentation.rb', line 113 def clear_trace! Thread.current[THREAD_KEY] = nil Thread.current[CHAIN_CONTEXT_KEY] = nil end |
.color ⇒ Object
: () -> bool
81 82 83 84 |
# File 'lib/typed_operation/instrumentation.rb', line 81 def color val = Thread.current[COLOR_KEY] val.nil? || val end |
.current_trace ⇒ Object
: () -> Trace?
87 88 89 90 |
# File 'lib/typed_operation/instrumentation.rb', line 87 def current_trace stack = Thread.current[THREAD_KEY] stack&.last end |
.explaining(&block) ⇒ Object
Execute a block with tracing enabled, printing the trace tree afterward. : [T] () { () -> T } -> T
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/typed_operation/instrumentation.rb', line 51 def explaining(&block) trace_root = Trace.new(operation_class: BlockExecution, params: {}) push_trace(trace_root) result = nil exception = nil begin result = block.call rescue => e exception = e end trace_root.finish!(result: result, exception: exception) pop_trace formatter = TreeFormatter.new(color: color) trace_root.children.each do |child_trace| output.puts formatter.format(child_trace) end raise exception if exception result end |
.output ⇒ Object
: () -> IO
76 77 78 |
# File 'lib/typed_operation/instrumentation.rb', line 76 def output Thread.current[OUTPUT_KEY] || $stdout end |
.pop_trace ⇒ Object
: () -> Trace?
106 107 108 109 110 |
# File 'lib/typed_operation/instrumentation.rb', line 106 def pop_trace stack = Thread.current[THREAD_KEY] stack&.pop Thread.current[THREAD_KEY] = nil if stack&.empty? end |
.push_trace(trace) ⇒ Object
: (Trace) -> void
98 99 100 101 102 103 |
# File 'lib/typed_operation/instrumentation.rb', line 98 def push_trace(trace) Thread.current[THREAD_KEY] ||= [] parent = current_trace parent&.add_child(trace) Thread.current[THREAD_KEY].push(trace) end |
.set_chain_context(pass_mode:, extracted_params: nil, fallback_used: false) ⇒ Object
: (pass_mode: Symbol, ?extracted_params: Array?, ?fallback_used: bool) -> void
119 120 121 122 123 124 125 |
# File 'lib/typed_operation/instrumentation.rb', line 119 def set_chain_context(pass_mode:, extracted_params: nil, fallback_used: false) Thread.current[CHAIN_CONTEXT_KEY] = { pass_mode: pass_mode, extracted_params: extracted_params, fallback_used: fallback_used } end |
.take_chain_context ⇒ Object
: () -> Hash[Symbol, untyped]?
128 129 130 131 132 |
# File 'lib/typed_operation/instrumentation.rb', line 128 def take_chain_context ctx = Thread.current[CHAIN_CONTEXT_KEY] Thread.current[CHAIN_CONTEXT_KEY] = nil ctx end |
.tracing? ⇒ Boolean
: () -> bool
93 94 95 |
# File 'lib/typed_operation/instrumentation.rb', line 93 def tracing? !current_trace.nil? end |
.with_output(io, color: nil, &block) ⇒ Object
Execute a block with custom output and color settings. : [T] (IO, ?color: bool?) { () -> T } -> T
38 39 40 41 42 43 44 45 46 47 |
# File 'lib/typed_operation/instrumentation.rb', line 38 def with_output(io, color: nil, &block) old_output = Thread.current[OUTPUT_KEY] old_color = Thread.current[COLOR_KEY] Thread.current[OUTPUT_KEY] = io Thread.current[COLOR_KEY] = color yield ensure Thread.current[OUTPUT_KEY] = old_output Thread.current[COLOR_KEY] = old_color end |