Module: Wurk::Telemetry
- Defined in:
- lib/wurk/telemetry.rb,
lib/wurk/telemetry/client_middleware.rb,
lib/wurk/telemetry/server_middleware.rb
Overview
Distributed tracing over the Redis hop: a producer span on enqueue whose W3C trace context rides the job hash, and a linked consumer span when a worker picks the job up.
This file is not loaded by require "wurk". Configuration#telemetry=
pulls it in, so an app that never opts in never requires opentelemetry-api
either — Wurk does not decide on a host's behalf when a third-party gem gets
loaded, and an app with the gem installed but tracing off keeps the exact
object graph, payload bytes and hot path it has today.
Opt in from the server config:
Wurk.configure_server do |config|
config.telemetry = true
end
Both halves must hold before anything registers: the gem has to be there (Telemetry.available?) and the host has to have asked (Configuration#telemetry?). Telemetry.enabled? is that gate.
There is no Sidekiq::Telemetry alias: upstream Sidekiq has no such
constant, so aliasing would invent a Sidekiq surface rather than mirror one
— same call as Wurk::Status (see lib/wurk/compat.rb).
Defined Under Namespace
Classes: ClientMiddleware, ServerMiddleware
Constant Summary collapse
- INSTRUMENTATION_NAME =
Instrumentation scope stamped on every span this gem emits.
'wurk'- REQUIRED_API =
The API the client/server middlewares call. A defined
::OpenTelemetryis not proof the gem is there — a host can own that constant itself, and anopentelemetry-apiold enough to predate these entry points would answer the constant check too. Asking for the surface at install time turns either case into "tracing stays off" rather than a NoMethodError on the first job of a deploy. %i[propagation tracer_provider].freeze
Class Method Summary collapse
-
.available? ⇒ Boolean
Not memoized.
-
.enabled?(config = Wurk.configuration) ⇒ Boolean
The registration gate — the host flag first, deliberately: an app that never opted in must not so much as resolve the OTel constant.
-
.install!(config = Wurk.configuration) ⇒ Object
Bring the middleware registrations in line with Telemetry.enabled?.
-
.tracer ⇒ Object
Memoized against the provider that produced it rather than once for the process:
OpenTelemetry::SDK.configureis routinely called after the code that will emit spans is loaded, andOpenTelemetry.tracer_provider=swaps the object — a tracer cached before that would silently export nothing for the life of the process.
Class Method Details
.available? ⇒ Boolean
Not memoized. A host is free to require opentelemetry after this file
(an initializer ordering Wurk before its tracing setup), and a false
cached at load would disable tracing for the life of the process with
nothing to point at.
63 64 65 66 67 |
# File 'lib/wurk/telemetry.rb', line 63 def available? return false unless defined?(::OpenTelemetry) REQUIRED_API.all? { |method| ::OpenTelemetry.respond_to?(method) } end |
.enabled?(config = Wurk.configuration) ⇒ Boolean
The registration gate — the host flag first, deliberately: an app that never opted in must not so much as resolve the OTel constant.
74 75 76 |
# File 'lib/wurk/telemetry.rb', line 74 def enabled?(config = Wurk.configuration) config.telemetry? && available? end |
.install!(config = Wurk.configuration) ⇒ Object
Bring the middleware registrations in line with enabled?. Called by Configuration#telemetry=, so the chain follows the flag in both directions: a host that turns tracing back off (a test, a capsule built for a client-only process) must stop stamping payloads, not just stop exporting.
Idempotent — Chain#add and the insert helpers all drop any prior entry for the same class first.
88 89 90 91 92 93 94 95 96 |
# File 'lib/wurk/telemetry.rb', line 88 def install!(config = Wurk.configuration) unless enabled?(config) config.client_middleware.remove(ClientMiddleware) return config.server_middleware.remove(ServerMiddleware) end config.client_middleware.add(ClientMiddleware) install_server(config.server_middleware) end |
.tracer ⇒ Object
Memoized against the provider that produced it rather than once for the
process: OpenTelemetry::SDK.configure is routinely called after the
code that will emit spans is loaded, and OpenTelemetry.tracer_provider=
swaps the object — a tracer cached before that would silently export
nothing for the life of the process. The check costs one equal? per
enqueue and re-resolves whenever the provider actually changes.
The pair is published in a single store so a concurrent reader sees either the old provider with its own tracer or the new one with its own, never a tracer attributed to the wrong provider.
108 109 110 111 112 113 114 |
# File 'lib/wurk/telemetry.rb', line 108 def tracer memo = @tracer provider = ::OpenTelemetry.tracer_provider return memo[1] if memo && memo[0].equal?(provider) (@tracer = [provider, provider.tracer(INSTRUMENTATION_NAME, Wurk::VERSION)].freeze)[1] end |