Module: Sashiko::Rails

Defined in:
lib/sashiko/rails.rb

Overview

Rails integration helpers. Loaded explicitly:

require "sashiko/rails"
Sashiko::Rails.install!(notifications: /^my_app\./)

The pieces are independent — you can require this file and pick only the helpers you need. None of them monkey-patch Rails.

Defined Under Namespace

Modules: TracedJob

Class Method Summary collapse

Class Method Details

.async(name, kind: :internal, attributes: nil, tracer: nil) ⇒ Object

Run ‘block` in a Thread that preserves the current OTel Context, wrapped in a span named `name`. Use this anywhere vanilla `Thread.new` would normally drop the trace context — controllers, jobs, rake tasks, anywhere.

def index
  Sashiko::Rails.async("orders.fetch_external") do
    ExternalAPI.fetch(...)
  end
end

Returns the Thread; call ‘.join` or `.value` as usual. The optional `tracer:` keyword bypasses Sashiko.tracer.



26
27
28
29
30
31
32
# File 'lib/sashiko/rails.rb', line 26

def async(name, kind: :internal, attributes: nil, tracer: nil)
  Sashiko::Context.thread do
    (tracer || Sashiko.tracer).in_span(name.to_s, kind:, attributes:) do
      yield
    end
  end
end

.bridge_notifications(pattern, tracer: nil) ⇒ Object

Subscribe an ActiveSupport::Notifications pattern and emit one OTel span per matched event. The event’s payload becomes span attributes (string keys, stringified values). Useful for bridging custom ‘instrument(…)` calls in your code into the OTel pipeline without re-instrumenting every call site.

ActiveSupport::Notifications.instrument("my_app.lookup", id: 42) { ... }
Sashiko::Rails.bridge_notifications(/^my_app\./)

The optional ‘tracer:` keyword bypasses Sashiko.tracer.



44
45
46
47
48
49
50
51
52
53
54
# File 'lib/sashiko/rails.rb', line 44

def bridge_notifications(pattern, tracer: nil)
  unless defined?(::ActiveSupport::Notifications)
    raise "ActiveSupport::Notifications is not available — load `active_support/notifications` first"
  end
  target_tracer = tracer || Sashiko.tracer
  ::ActiveSupport::Notifications.subscribe(pattern) do |name, start, finish, _id, payload|
    attrs = stringify_payload(payload)
    span = target_tracer.start_span(name, attributes: attrs, start_timestamp: start)
    span.finish(end_timestamp: finish)
  end
end

.install!(notifications: nil, tracer: nil) ⇒ Object

Top-level install hook. Currently delegates to ‘bridge_notifications` if a pattern is supplied. Add other global setup here as Sashiko::Rails grows.



59
60
61
62
# File 'lib/sashiko/rails.rb', line 59

def install!(notifications: nil, tracer: nil)
  bridge_notifications(notifications, tracer:) if notifications
  true
end