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#
go get github.com/BAGOMBEKA-JOB-DEV/skyl/otelimport "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#
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:
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#
| Symbol | Purpose |
|---|---|
| Hook | Returns a skyl.Option registering the instrumentation |
| HTTPClient | Wraps a transport so trace context reaches the provider |
| Spans and metrics | The attribute and metric names emitted |
ScopeName identifies this instrumentation in the telemetry it produces:
github.com/BAGOMBEKA-JOB-DEV/skyl/otel.
Options#
| Option | Effect |
|---|---|
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. |