Introduces code.nochebuena.dev/einherjar/telemetry — the observability bootstrap starter for the Einherjar framework. Absorbs the telemetry package from micro-lib, migrating from OpenCensus to OpenTelemetry SDK v1.42. Bootstrap functions (not lifecycle.Component — telemetry must be initialized before the launcher starts, and its shutdown must run after all components stop): - New(ctx, cfg) (func(context.Context) error, error) — production mode; exports traces, metrics, and logs via OTLP over gRPC to the configured endpoint; returns a shutdown function to be deferred in main() - NewConsole(ctx, logger, cfg) (func(context.Context) error, error) — development mode; writes structured telemetry to the provided logging.Logger; no network dependency; suitable for local development and CI Config (EINHERJAR_OTEL_* env vars): ServiceName(required), ServiceVersion(unknown), Environment(development), OTLPEndpoint(required for New), OTLPInsecure(false) ConsoleConfig (EINHERJAR_OTEL_* env vars): ServiceName(required), ServiceVersion(unknown), Environment(development) - identifiable.go: package-level Module variable (observability.Identifiable) for version identification — telemetry bootstraps before the launcher; not registered as a lifecycle component
3.2 KiB
einherjar/telemetry
Huginn and Muninn fly each day over the world. They see everything. They report back.
code.nochebuena.dev/einherjar/telemetry is the OpenTelemetry bootstrap component of the Einherjar framework. It initializes traces, metrics, and structured logs via OTLP over gRPC — vendor-neutral, compatible with Grafana, Jaeger, Tempo, Datadog, and Honeycomb. A console mode is available for local development without a collector.
Telemetry is not a lifecycle.Component. It must be initialized before the launcher and shut down after all components stop — the returned shutdown function handles this cleanly with a defer.
Usage
Production (OTLP/gRPC)
import (
"code.nochebuena.dev/einherjar/telemetry"
"code.nochebuena.dev/einherjar/core/launcher"
"code.nochebuena.dev/einherjar/core/logz"
)
ctx := context.Background()
logger := logz.New(logz.Config{JSON: true})
// Initialize telemetry BEFORE the launcher.
// Defer the shutdown BEFORE launcher.Run() so it fires after the launcher stops.
shutdown, err := telemetry.New(ctx, telemetry.DefaultConfig())
if err != nil {
logger.Error("telemetry init failed", err)
os.Exit(1)
}
defer shutdown(ctx)
lc := launcher.New(logger)
lc.Append(db, cache, srv)
lc.Run()
Development (console / structured log output)
No collector required. Spans and metrics are emitted to the configured logging.Logger.
shutdown, err := telemetry.NewConsole(ctx, logger, telemetry.DefaultConsoleConfig())
if err != nil {
logger.Error("telemetry init failed", err)
os.Exit(1)
}
defer shutdown(ctx)
Environment variables
Production (telemetry.New)
| Variable | Required | Default | Description |
|---|---|---|---|
EINHERJAR_OTEL_SERVICE_NAME |
Yes | — | Service name reported to the collector |
EINHERJAR_OTEL_EXPORTER_ENDPOINT |
Yes | — | OTLP gRPC endpoint (e.g. otel-collector:4317) |
EINHERJAR_OTEL_SERVICE_VERSION |
No | unknown |
Service version tag |
EINHERJAR_OTEL_ENVIRONMENT |
No | development |
Deployment environment tag |
EINHERJAR_OTEL_EXPORTER_INSECURE |
No | false |
Disable TLS for the exporter (dev/local) |
Development (telemetry.NewConsole)
| Variable | Required | Default | Description |
|---|---|---|---|
EINHERJAR_OTEL_SERVICE_NAME |
Yes | — | Service name |
EINHERJAR_OTEL_SERVICE_VERSION |
No | unknown |
Service version tag |
EINHERJAR_OTEL_ENVIRONMENT |
No | development |
Deployment environment tag |
Dependency graph
contracts (zero dependencies)
↑
core
↑
telemetry (contracts, core, otel SDK + OTLP exporters)
↑
your app (initialized before launcher.Run)
Verification
cd telemetry/
go build ./...
go vet ./...
go test ./...
gofmt -l .
Odin gave an eye for wisdom. Observability is the eye that watches the living system.