Module: Bitfab::Traceable

Defined in:
lib/bitfab/traceable.rb

Overview

Mixin for declarative span tracing on instance methods.

Examples:

Bitfab.configure(api_key: "...")

class OrderService
  include Bitfab::Traceable
  bitfab_function "order-processing"

  bitfab_span :process_order, type: "function"
  def process_order(order_id)
    { total: 100 }
  end

  bitfab_span :validate_order, name: "Validate", type: "guardrail"
  def validate_order(order_id)
    { valid: true }
  end
end

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Class Method Details

.included(base) ⇒ Object



25
26
27
# File 'lib/bitfab/traceable.rb', line 25

def self.included(base)
  base.extend(ClassMethods)
end

.wrap(klass, method_name, trace_function_key:, name: nil, type: "custom", mock_on_replay: false, client: nil) ⇒ Object

Wrap an existing method on an external class with span tracing. Use this to trace third-party library calls without modifying their source.

Examples:

Bitfab::Traceable.wrap(OpenAI::Client, :chat,
  trace_function_key: "openai", name: "Chat", type: "llm")

Parameters:

  • klass (Class, Module)

    the class to wrap

  • method_name (Symbol)

    the method to wrap

  • trace_function_key (String)

    the trace function key

  • name (String, nil) (defaults to: nil)

    explicit span name (defaults to method name)

  • type (String) (defaults to: "custom")

    span type: llm, agent, function, guardrail, handoff, custom

  • mock_on_replay (Boolean) (defaults to: false)

    mark this span for the “marked” mock strategy. When true, ‘client.replay(… mock: “marked”)` returns this span’s historical output instead of executing the wrapped method.

  • client (Bitfab::Client, nil) (defaults to: nil)

    route spans through this specific client instead of the global ‘Bitfab.client`. When nil (default), the wrapper resolves `Bitfab.client` at each call (so `Bitfab.configure` / `reset!` between calls keeps working). Used by `Bitfab::Client#get_function` to preserve the bound client through the fluent wrapper, matching Python’s ‘BitfabFunction.span()` and TypeScript’s ‘BitfabFunction.withSpan()`.



50
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/bitfab/traceable.rb', line 50

def self.wrap(klass, method_name, trace_function_key:, name: nil, type: "custom",
  mock_on_replay: false, client: nil)
  span_name = name || method_name.to_s
  method_name_str = method_name.to_s
  bound_client = client

  wrapper = Module.new do
    define_method(method_name) do |*args, **kwargs, &block|
      target_client = bound_client || Bitfab.client
      target_client.send(:execute_span,
        trace_function_key:,
        span_name:,
        span_type: type,
        function_name: method_name_str,
        args:,
        kwargs:,
        mock_on_replay:) do
        super(*args, **kwargs, &block)
      end
    end
  end

  klass.prepend(wrapper)
end