Skip to content

Commit ea65d09

Browse files
committed
Add Proof of Concept instrumentation for Solid Process
1 parent 46c87d7 commit ea65d09

File tree

3 files changed

+79
-1
lines changed

3 files changed

+79
-1
lines changed

config/initializers/solid_process.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,17 @@
99
require "solid/process/event_logs/json_logger_listener"
1010
# require "solid/process/event_logs/basic_logger_listener"
1111

12+
require "solid/process/active_support_publisher"
13+
14+
require "open_telemetry_tracer"
15+
OpenTelemetryTracer.subscribe
16+
1217
# Solid::Process::EventLogs::BasicLoggerListener.logger = Rails.logger
1318

1419
Solid::Result.configuration do |config|
1520
config.event_logs.listener = Solid::Result::EventLogs::Listeners[
1621
Solid::Process::EventLogs::JsonLoggerListener,
17-
Solid::Process::EventLogs::Record::Listener
22+
Solid::Process::EventLogs::Record::Listener,
23+
Solid::Process::ActiveSupportPublisher
1824
]
1925
end

lib/open_telemetry_tracer.rb

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
module OpenTelemetryTracer
2+
SolidResultTracer = ::OpenTelemetry.tracer_provider.tracer("solid-result")
3+
4+
module ProcessListener
5+
def self.start(name, _id, payload)
6+
scope = payload[:scope]
7+
8+
span = SolidResultTracer.start_span("#{scope[:name]}#call", attributes: {
9+
"desc" => scope[:desc].inspect
10+
})
11+
12+
token = OpenTelemetry::Context.attach(::OpenTelemetry::Trace.context_with_span(span))
13+
payload.merge!(__otel: {span:, token:})
14+
end
15+
16+
def self.finish(_name, _id, payload)
17+
otel = payload.delete(:__otel)
18+
19+
otel => { span:, token: }
20+
21+
span.finish
22+
OpenTelemetry::Context.detach(token)
23+
end
24+
end
25+
26+
module AndThenListener
27+
def self.start(name, _id, payload)
28+
payload => { scope:, and_then: }
29+
30+
span = SolidResultTracer.start_span("#{scope[:name]}##{and_then[:method_name] || "block"}", attributes: {
31+
"type" => and_then[:type].to_s,
32+
"arg" => and_then[:arg].inspect
33+
})
34+
35+
token = OpenTelemetry::Context.attach(::OpenTelemetry::Trace.context_with_span(span))
36+
payload.merge!(__otel: {span:, token:})
37+
end
38+
39+
def self.finish(_name, _id, payload)
40+
otel = payload.delete(:__otel)
41+
42+
otel => { span:, token: }
43+
44+
span.finish
45+
OpenTelemetry::Context.detach(token)
46+
end
47+
end
48+
49+
def self.subscribe
50+
ActiveSupport::Notifications.monotonic_subscribe("start_process.solid_process", ProcessListener)
51+
ActiveSupport::Notifications.monotonic_subscribe("and_then.solid_process", AndThenListener)
52+
end
53+
end
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
class Solid::Process::ActiveSupportPublisher
2+
include Solid::Result::EventLogs::Listener
3+
4+
def self.around_event_logs?
5+
true
6+
end
7+
8+
def self.around_and_then?
9+
true
10+
end
11+
12+
def around_event_logs(scope:, &)
13+
ActiveSupport::Notifications.instrument("start_process.solid_process", scope:, &)
14+
end
15+
16+
def around_and_then(scope:, and_then:, **, &)
17+
ActiveSupport::Notifications.instrument("and_then.solid_process", scope:, and_then:, &)
18+
end
19+
end

0 commit comments

Comments
 (0)