Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
83ac0e3900
|
|||
|
9304bed55b
|
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/),
|
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).
|
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
|
## [0.9.0] - 2026-03-18
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
@@ -17,7 +35,7 @@ and this module adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.
|
|||||||
|
|
||||||
### Design Notes
|
### 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
|
- 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
|
- 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
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ Sets the three OTel global providers so that all micro-libs using the OTel globa
|
|||||||
|
|
||||||
## Tier & Dependencies
|
## Tier & Dependencies
|
||||||
|
|
||||||
**Tier 5** (application bootstrap only). Must never be imported by framework libraries (Tier 0–4).
|
**Tier 1** (no micro-lib dependencies; external OTel SDK only). Must never be imported by framework libraries.
|
||||||
|
|
||||||
Depends on:
|
Depends on:
|
||||||
- `go.opentelemetry.io/otel` and sub-packages — API and SDK
|
- `go.opentelemetry.io/otel` and sub-packages — API and SDK
|
||||||
@@ -21,7 +21,7 @@ No micro-lib dependencies. No `launcher` dependency — telemetry has no Compone
|
|||||||
|
|
||||||
## Key Design Decisions
|
## Key Design Decisions
|
||||||
|
|
||||||
- **Tier 5 / app-only** (ADR-001): Libraries use only the OTel API (no-op default). This module activates the real SDK. Importing it from a library is a mistake.
|
- **Tier 1 / app-only** (ADR-001): Libraries use only the OTel API (no-op default). This module activates the real SDK. Importing it from a library is a mistake.
|
||||||
- **Three-signal OTLP bootstrap** (ADR-002): `New(ctx, cfg)` sets up traces → Tempo, metrics → Mimir, logs → Loki, all over a single OTLP gRPC endpoint. W3C TraceContext + Baggage propagation is set globally.
|
- **Three-signal OTLP bootstrap** (ADR-002): `New(ctx, cfg)` sets up traces → Tempo, metrics → Mimir, logs → Loki, all over a single OTLP gRPC endpoint. W3C TraceContext + Baggage propagation is set globally.
|
||||||
- **Global provider strategy** (ADR-003): Libraries call `otel.Tracer(...)` / `otel.Meter(...)` / `global.Logger(...)`. After `telemetry.New`, those calls route to the real SDK with no library changes required.
|
- **Global provider strategy** (ADR-003): Libraries call `otel.Tracer(...)` / `otel.Meter(...)` / `global.Logger(...)`. After `telemetry.New`, those calls route to the real SDK with no library changes required.
|
||||||
- **No `launcher.Component`**: Telemetry is not a lifecycle component. The caller defers the returned shutdown function directly in `main`. This keeps the module dependency graph minimal and the interface simple.
|
- **No `launcher.Component`**: Telemetry is not a lifecycle component. The caller defers the returned shutdown function directly in `main`. This keeps the module dependency graph minimal and the interface simple.
|
||||||
|
|||||||
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
|
module code.nochebuena.dev/go/telemetry
|
||||||
|
|
||||||
go 1.25.0
|
go 1.26
|
||||||
|
|
||||||
require (
|
require (
|
||||||
go.opentelemetry.io/otel v1.42.0
|
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)
|
global.SetLoggerProvider(lp)
|
||||||
|
|
||||||
shutdown := func(ctx context.Context) error {
|
shutdown := func(ctx context.Context) error {
|
||||||
return errors.Join(
|
var errs []error
|
||||||
tp.Shutdown(ctx),
|
if err := tp.Shutdown(ctx); err != nil {
|
||||||
mp.Shutdown(ctx),
|
errs = append(errs, &providerErr{"trace", err})
|
||||||
lp.Shutdown(ctx),
|
}
|
||||||
)
|
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
|
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.
|
// newResource builds an OTel resource with service identity and environment attributes.
|
||||||
func newResource(cfg Config) *resource.Resource {
|
func newResource(cfg Config) *resource.Resource {
|
||||||
r, _ := resource.Merge(
|
r, _ := resource.Merge(
|
||||||
|
|||||||
Reference in New Issue
Block a user