Skip to content
skyl

skyl/otel

OpenTelemetry instrumentation, as a fourth module. One line to wire up.

skyl/otel turns skyl's hook events into spans and metrics following the OpenTelemetry GenAI semantic conventions — so model traffic appears in your observability stack the same way any other dependency does, and looks the same whichever provider served it.

Installing#

Terminal
go get github.com/BAGOMBEKA-JOB-DEV/skyl/otel
import "github.com/BAGOMBEKA-JOB-DEV/skyl/otel"
import "github.com/BAGOMBEKA-JOB-DEV/skyl/otel"

Requires Go 1.25+, inherited from the OpenTelemetry SDK.

The whole integration#

goCompiles
client := skyl.New(openai.New(key), otel.Hook())
client := skyl.New(openai.New(key), otel.Hook())

That is traces and metrics. To get the trace context onto the outbound HTTP request as well, wrap the transport too:

goCompiles
client := skyl.New(
	openai.New(key, openai.WithHTTPClient(otel.HTTPClient(nil))),
	otel.Hook(),
)
client := skyl.New(
	openai.New(key, openai.WithHTTPClient(otel.HTTPClient(nil))),
	otel.Hook(),
)

A separate module#

It lives outside the core module because the OpenTelemetry SDK brings a dependency graph, and skyl's engineering rules give the core zero dependencies. Nobody who does not want OpenTelemetry pays for it — the same reasoning as ADR-0006 applies to the Anthropic SDK. Recorded as ADR-0007.

What is deliberately not recorded#

The API#

SymbolPurpose
HookReturns a skyl.Option registering the instrumentation
HTTPClientWraps a transport so trace context reaches the provider
Spans and metricsThe attribute and metric names emitted

ScopeName identifies this instrumentation in the telemetry it produces: github.com/BAGOMBEKA-JOB-DEV/skyl/otel.

Options#

OptionEffect
WithTracerProvider(tp)Use a specific tracer provider instead of the global one.
WithMeterProvider(mp)Use a specific meter provider instead of the global one.
WithoutSpans()Metrics only. Spans on a high-volume gateway are the expensive half.

Edit this page on GitHub