One of my goals for Brut was to make observabililty/instrumentation built-in via OTel. In fact, I’m trying to make it so that there is no logging, just OTel. I’m not quite there, but OTel is working much better now.
As mentioned previously, OTel is not well documented and most of what’s there is geared toward using OTel as a client and not incorporating it into a framework.
I had it working pretty well for web requests, but really wanted to see a trace where a web requested queued a Sidekiq job, and then the trace included that job’s behavior.
A lot of OTel config says to do use_all, but this is generally a mistake IMO. Configuration code isn’t often edited, so it doesn’t benefit from slick batteries-included DSLs that do it all. It’s often much better to have it explicitly laid out so you can see what’s what and now what you can change and where.
Here is how Sidekiq is set up:
if defined?(OpenTelemetry::Instrumentation::Sidekiq)
c.use 'OpenTelemetry::Instrumentation::Sidekiq', {
span_naming: :job_class,
propagation_style: :child, # <--- default is "link"
}
else
SemanticLogger[self.class].info "OpenTelemetry::Instrumentation::Sidekiq is not loaded, so Sidekiq traces will not be captured"
end
The default “propagation style” is “link”, which I think is intende to link the trace that queued a job to the trace that processes it. In practice, this doesn’t seem to actually create the link or the link doesn’t show up (at least Honeycomb and otel-desktop-viewer - OTel is extremely hard to debug). Setting the style to “child” puts the processing trace as a child of the original trace.
[As with many things, I spent weeks putting it off and got it working in like 15 minutes.]
Here’s screenshots from local otel-desktop-viewer showing a web request that leads to a job queue that is then processed:


