feat(telemetry)!: promote to v1.0.0 — named shutdown errors per provider, Go 1.26
Label each provider shutdown failure with its signal name (trace/metric/log). Errors remain joined via errors.Join; individual causes still unwrappable. Go directive bumped from 1.25 to 1.26. API committed as stable.
This commit is contained in:
1
.gitea/CODEOWNERS
Normal file
1
.gitea/CODEOWNERS
Normal file
@@ -0,0 +1 @@
|
||||
* @go/CoreDevelopers @go/Agents
|
||||
20
CHANGELOG.md
20
CHANGELOG.md
@@ -5,6 +5,24 @@ All notable changes to this module will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this module adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [1.0.0] - 2026-05-12
|
||||
|
||||
### Changed
|
||||
|
||||
- Go directive bumped from 1.25 to 1.26
|
||||
- Shutdown function now wraps each provider error with a `providerErr` type that
|
||||
prefixes the signal name (`"telemetry: trace provider shutdown: …"`,
|
||||
`"telemetry: metric provider shutdown: …"`, `"telemetry: log provider shutdown: …"`).
|
||||
The combined error is still joined with `errors.Join`; individual causes remain
|
||||
unwrappable via `errors.As`. Previously, the three errors were joined without labels.
|
||||
|
||||
### Stabilization
|
||||
|
||||
- API committed as stable. `Config`, `New`, and the shutdown function signature
|
||||
(`func(context.Context) error`) are unchanged from v0.9.0.
|
||||
|
||||
[1.0.0]: https://code.nochebuena.dev/go/telemetry/compare/v0.9.0...v1.0.0
|
||||
|
||||
## [0.9.0] - 2026-03-18
|
||||
|
||||
### Added
|
||||
@@ -17,7 +35,7 @@ and this module adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.
|
||||
|
||||
### Design Notes
|
||||
|
||||
- This module is Tier 5 (application bootstrap only) and must never be imported by framework libraries; those libraries use only the OTel API, which defaults to no-ops until `New` is called and sets the global providers
|
||||
- This module is Tier 1 (no micro-lib dependencies) and must never be imported by framework libraries; those libraries use only the OTel API, which defaults to no-ops until `New` is called and sets the global providers
|
||||
- All three signals share a single OTLP gRPC endpoint, matching the standard Grafana LGTM stack topology where Grafana Alloy receives all signals and fans them out to Tempo, Mimir, and Loki
|
||||
- The module intentionally does not implement `launcher.Component`; the returned shutdown function is deferred directly in `main`, keeping the dependency graph free of `launcher` and the interface as simple as a single function call
|
||||
|
||||
|
||||
5
COMMIT.md
Normal file
5
COMMIT.md
Normal file
@@ -0,0 +1,5 @@
|
||||
feat(telemetry)!: promote to v1.0.0 — named shutdown errors per provider, Go 1.26
|
||||
|
||||
Label each provider shutdown failure with its signal name (trace/metric/log).
|
||||
Errors remain joined via errors.Join; individual causes still unwrappable.
|
||||
Go directive bumped from 1.25 to 1.26. API committed as stable.
|
||||
46
RELEASE.md
Normal file
46
RELEASE.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# v1.0.0
|
||||
|
||||
> `code.nochebuena.dev/go/telemetry`
|
||||
|
||||
## Overview
|
||||
|
||||
`telemetry` bootstraps the full OpenTelemetry SDK with OTLP gRPC exporters targeting
|
||||
a Grafana Alloy collector. A single call to `New` sets all three OTel global providers
|
||||
(traces → Tempo, metrics → Mimir, logs → Loki) and returns a shutdown function the
|
||||
caller defers in `main`.
|
||||
|
||||
v1.0.0 adds named per-provider shutdown errors, bumps the Go directive to 1.26, and
|
||||
commits the API as stable. No micro-lib dependencies are added.
|
||||
|
||||
## What Changed Since v0.9.0
|
||||
|
||||
### Named per-provider shutdown errors
|
||||
|
||||
The shutdown function now labels each provider failure individually:
|
||||
|
||||
```
|
||||
telemetry: trace provider shutdown: <cause>
|
||||
telemetry: metric provider shutdown: <cause>
|
||||
telemetry: log provider shutdown: <cause>
|
||||
```
|
||||
|
||||
Errors are still joined with `errors.Join`; individual causes remain accessible via
|
||||
`errors.As`. Previously, provider shutdown failures were joined without labels, making
|
||||
it impossible to identify which signal pipeline failed.
|
||||
|
||||
### Go directive bumped to 1.26
|
||||
|
||||
## Full API (stable)
|
||||
|
||||
- `Config` — `ServiceName`, `ServiceVersion`, `Environment`, `OTLPEndpoint`, `OTLPInsecure`
|
||||
- `New(ctx, cfg) (func(context.Context) error, error)`
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
go get code.nochebuena.dev/go/telemetry@v1.0.0
|
||||
```
|
||||
|
||||
## Changelog
|
||||
|
||||
See [CHANGELOG.md](CHANGELOG.md#100---2026-05-12).
|
||||
2
go.mod
2
go.mod
@@ -1,6 +1,6 @@
|
||||
module code.nochebuena.dev/go/telemetry
|
||||
|
||||
go 1.25.0
|
||||
go 1.26
|
||||
|
||||
require (
|
||||
go.opentelemetry.io/otel v1.42.0
|
||||
|
||||
25
telemetry.go
25
telemetry.go
@@ -105,15 +105,30 @@ func New(ctx context.Context, cfg Config) (func(context.Context) error, error) {
|
||||
global.SetLoggerProvider(lp)
|
||||
|
||||
shutdown := func(ctx context.Context) error {
|
||||
return errors.Join(
|
||||
tp.Shutdown(ctx),
|
||||
mp.Shutdown(ctx),
|
||||
lp.Shutdown(ctx),
|
||||
)
|
||||
var errs []error
|
||||
if err := tp.Shutdown(ctx); err != nil {
|
||||
errs = append(errs, &providerErr{"trace", err})
|
||||
}
|
||||
if err := mp.Shutdown(ctx); err != nil {
|
||||
errs = append(errs, &providerErr{"metric", err})
|
||||
}
|
||||
if err := lp.Shutdown(ctx); err != nil {
|
||||
errs = append(errs, &providerErr{"log", err})
|
||||
}
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
return shutdown, nil
|
||||
}
|
||||
|
||||
// providerErr labels a shutdown error with the provider name.
|
||||
type providerErr struct {
|
||||
provider string
|
||||
err error
|
||||
}
|
||||
|
||||
func (e *providerErr) Error() string { return "telemetry: " + e.provider + " provider shutdown: " + e.err.Error() }
|
||||
func (e *providerErr) Unwrap() error { return e.err }
|
||||
|
||||
// newResource builds an OTel resource with service identity and environment attributes.
|
||||
func newResource(cfg Config) *resource.Resource {
|
||||
r, _ := resource.Merge(
|
||||
|
||||
Reference in New Issue
Block a user