Module: Bitfab
- Defined in:
- lib/bitfab.rb,
lib/bitfab/otel.rb,
lib/bitfab/client.rb,
lib/bitfab/replay.rb,
lib/bitfab/version.rb,
lib/bitfab/constants.rb,
lib/bitfab/serialize.rb,
lib/bitfab/traceable.rb,
lib/bitfab/transport.rb,
lib/bitfab/warn_once.rb,
lib/bitfab/db_snapshot.rb,
lib/bitfab/http_client.rb,
lib/bitfab/span_context.rb,
lib/bitfab/mock_override.rb,
lib/bitfab/replay_branch.rb
Defined Under Namespace
Modules: DbSnapshot, MockOverride, Otel, Replay, ReplayContext, Serialize, SpanContext, TraceState, Traceable, Transport Classes: BitfabFunction, Client, CurrentSpan, CurrentTrace, HttpClient, NoOpCurrentSpan, NoOpCurrentTrace, ReplayBranch
Constant Summary collapse
- NO_OP_SPAN =
NoOpCurrentSpan.new.freeze
- NO_OP_TRACE =
NoOpCurrentTrace.new.freeze
- MOCK_STRATEGIES =
Replay mock strategies. Mirrors the Python and TypeScript SDKs.
- "marked" : only spans declared with mock_on_replay: true return historical output; everything else runs real code (default)
- "none" : every child span runs real code
- "all" : every child span returns its historical output
%w[none all marked].freeze
- VERSION =
"0.34.0"- DEFAULT_SERVICE_URL =
"https://bitfab.ai"- REPLAY_CONTEXT_KEY =
:__bitfab_replay_context- BITFAB_PROGRESS_PREFIX =
Wire prefix the Bitfab plugin scans for on stderr to report live progress while a replay runs. One trailing space, then the progress object as JSON.
"@@bitfab:progress "
Class Method Summary collapse
-
._reset_warn_once ⇒ Object
Test-only: clear the dedup set so a warning can fire again.
-
.client ⇒ Object
Returns the global client, raising if not configured.
-
.client_or_nil ⇒ Object
Returns the global client, or nil if not configured.
-
.configure(api_key: nil, service_url: nil, enabled: true, strict: false) ⇒ Object
Configure the global Bitfab client.
-
.current_replay_branch ⇒ ReplayBranch?
Get the database branch the current replay item is running against.
-
.current_span ⇒ CurrentSpan, NoOpCurrentSpan
Get a handle to the current active span.
-
.current_trace ⇒ CurrentTrace, NoOpCurrentTrace
Get a handle to the current active trace.
-
.flush_traces(timeout: 30) ⇒ Object
Wait for queued spans and trace completions to reach the server, within one total deadline.
-
.report_replay_progress(progress) ⇒ Object
A ready-made on_progress callback for replay: writes one @@bitfab:progress line per trace to stderr, which the Bitfab plugin polls to report live progress while the replay runs in the background, so replay scripts never hand-format the protocol.
-
.reset! ⇒ Object
Reset the global client (primarily for testing).
- .warn_once(key, message) ⇒ Object
Class Method Details
._reset_warn_once ⇒ Object
Test-only: clear the dedup set so a warning can fire again.
31 32 33 |
# File 'lib/bitfab/warn_once.rb', line 31 def _reset_warn_once @warn_once_mutex.synchronize { @warn_once_seen.clear } end |
.client ⇒ Object
Returns the global client, raising if not configured.
76 77 78 |
# File 'lib/bitfab.rb', line 76 def client @client or raise "Bitfab not configured. Call Bitfab.configure(api_key: '...') first." end |
.client_or_nil ⇒ Object
Returns the global client, or nil if not configured. Used on the traced call path so a method invoked before Bitfab.configure runs untraced rather than crashing the host app with a "not configured" error.
83 84 85 |
# File 'lib/bitfab.rb', line 83 def client_or_nil @client end |
.configure(api_key: nil, service_url: nil, enabled: true, strict: false) ⇒ Object
Configure the global Bitfab client.
71 72 73 |
# File 'lib/bitfab.rb', line 71 def configure(api_key: nil, service_url: nil, enabled: true, strict: false) @client = Client.new(api_key:, service_url:, enabled:, strict:) end |
.current_replay_branch ⇒ ReplayBranch?
Get the database branch the current replay item is running against.
Call this from inside a method being replayed with
client.replay(db_branch: ...) and point your database client at
branch.database_url so the replay reads the data as it was at trace
time:
branch = Bitfab.current_replay_branch
url = branch ? branch.database_url : ENV["DATABASE_URL"]
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/bitfab.rb', line 117 def current_replay_branch ctx = ReplayContext.current return nil unless ctx lease = ctx[:db_branch_lease] return nil unless lease # Surface the Bitfab trace ID (what the customer sees in the dashboard), # not the external one. Falling back to the external ID keeps replays from # external sources working until that path is fully wired. trace_id = ctx[:source_bitfab_trace_id] || ctx[:input_source_trace_id] return nil unless trace_id ReplayBranch.new(lease, trace_id, ctx) end |
.current_span ⇒ CurrentSpan, NoOpCurrentSpan
Get a handle to the current active span.
Call this from inside a traced method to get a span handle that allows setting metadata at runtime.
98 99 100 101 102 103 |
# File 'lib/bitfab.rb', line 98 def current_span entry = SpanContext.current return NO_OP_SPAN unless entry CurrentSpan.new(entry) end |
.current_trace ⇒ CurrentTrace, NoOpCurrentTrace
Get a handle to the current active trace.
Call this from inside a traced method to get a trace handle that allows setting trace-level context at runtime.
139 140 141 142 143 144 |
# File 'lib/bitfab.rb', line 139 def current_trace entry = SpanContext.current return NO_OP_TRACE unless entry CurrentTrace.new(entry[:trace_id]) end |
.flush_traces(timeout: 30) ⇒ Object
Wait for queued spans and trace completions to reach the server, within one total deadline. Returns true when everything landed in time.
304 305 306 |
# File 'lib/bitfab/http_client.rb', line 304 def flush_traces(timeout: 30) Transport.flush_trace_transports([timeout, 0].max) end |
.report_replay_progress(progress) ⇒ Object
A ready-made on_progress callback for replay: writes one @@bitfab:progress line per trace to stderr, which the Bitfab plugin polls to report live progress while the replay runs in the background, so replay scripts never hand-format the protocol. stdout stays the ReplayResult JSON. Never raises (progress must not crash a run). The progress hash's item is forwarded verbatim through to_json, so the plugin sees the source trace id, local replay trace id, outputs, error, and duration of the item that just settled.
160 161 162 163 164 |
# File 'lib/bitfab.rb', line 160 def report_replay_progress(progress) warn "#{BITFAB_PROGRESS_PREFIX}#{progress.to_json}" rescue nil end |
.reset! ⇒ Object
Reset the global client (primarily for testing).
88 89 90 |
# File 'lib/bitfab.rb', line 88 def reset! @client = nil end |
.warn_once(key, message) ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/bitfab/warn_once.rb', line 17 def warn_once(key, ) @warn_once_mutex.synchronize do return if @warn_once_seen.include?(key) @warn_once_seen.add(key) end begin warn "Bitfab: #{}" rescue Exception # rubocop:disable Lint/RescueException # Logging must never crash the host app (e.g. a closed $stderr). end end |