Module: Sashiko::Traced
- Defined in:
- lib/sashiko/traced.rb
Overview
Declarative span instrumentation via Module#prepend.
class OrderService
extend Sashiko::Traced
trace :process, attributes: ->(order) { { "order.id" => order.id } }
def process(order); ...; end
end
Defined Under Namespace
Classes: Options
Class Method Summary collapse
- .build_attributes(args, kwargs, options) ⇒ Object
- .install_overlay(klass) ⇒ Object
-
.overlay_for(klass) ⇒ Object
One prepended module per target class; we redefine on top of it when the same method is re-traced.
- .weave(overlay, options) ⇒ Object
Instance Method Summary collapse
- #trace(method_name, name: nil, kind: :internal, attributes: nil, record_args: false, tracer: nil) ⇒ Object
-
#trace_all(matching:, kind: :internal, record_args: false, tracer: nil) ⇒ Object
Trace every instance method matching ‘pattern` defined ON this class.
Class Method Details
.build_attributes(args, kwargs, options) ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/sashiko/traced.rb', line 84 def build_attributes(args, kwargs, ) extra = case .attributes in Proc => fn then fn.arity.zero? ? fn.call : fn.call(*args, **kwargs) in Hash => h then h else nil end # Fast path: nothing dynamic. Return the pre-baked frozen Hash # directly — OTel SDK copies it before storing on the Span. return .static_attrs unless .record_args || extra attrs = .static_attrs.dup #: Hash[String, untyped] attrs["code.args.count"] = args.length + kwargs.length if .record_args extra&.each { |k, v| attrs[k.to_s] = v } attrs end |
.install_overlay(klass) ⇒ Object
63 64 65 66 67 68 |
# File 'lib/sashiko/traced.rb', line 63 def (klass) Module.new.tap do |m| klass.prepend(m) klass.instance_variable_set(:@__sashiko_overlay, m) end end |
.overlay_for(klass) ⇒ Object
One prepended module per target class; we redefine on top of it when the same method is re-traced. This keeps super chains intact.
61 |
# File 'lib/sashiko/traced.rb', line 61 def (klass) = klass.instance_variable_get(:@__sashiko_overlay) || Traced.(klass) |
.weave(overlay, options) ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/sashiko/traced.rb', line 70 def weave(, ) .define_method(.method_name) do |*args, **kwargs, &block| attrs = Traced.build_attributes(args, kwargs, ) tracer = .tracer || Sashiko.tracer tracer.in_span(.span_name, attributes: attrs, kind: .kind) do |span| super(*args, **kwargs, &block) rescue => e span.record_exception(e) span.status = OpenTelemetry::Trace::Status.error(e.) ::Kernel.raise end end end |
Instance Method Details
#trace(method_name, name: nil, kind: :internal, attributes: nil, record_args: false, tracer: nil) ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/sashiko/traced.rb', line 25 def trace(method_name, name: nil, kind: :internal, attributes: nil, record_args: false, tracer: nil) method_sym = method_name.to_sym class_name = self.name static_attrs = { "code.function" => method_sym.to_s } static_attrs["code.namespace"] = class_name if class_name static_attrs.freeze = Options.new( span_name: name || "#{class_name || "anon"}##{method_sym}", kind:, attributes:, record_args:, method_name: method_sym, class_name:, tracer:, static_attrs:, ) Traced.weave(Traced.(self), ) end |
#trace_all(matching:, kind: :internal, record_args: false, tracer: nil) ⇒ Object
Trace every instance method matching ‘pattern` defined ON this class. Must be called AFTER the method defs so they are visible to instance_methods(false).
49 50 51 52 53 54 55 56 |
# File 'lib/sashiko/traced.rb', line 49 def trace_all(matching:, kind: :internal, record_args: false, tracer: nil) = Traced.(self) already_overlaid = .instance_methods(false) instance_methods(false) .select { |m| m.to_s.match?(matching) } .reject { |m| already_overlaid.include?(m) } .each { |m| trace(m, kind:, record_args:, tracer:) } end |