Skip to content

Commit b5cc3a0

Browse files
committed
refactor(telemetry): rename slogadapter module to slog
Signed-off-by: Joshua Temple <joshua.temple@stablekernel.com>
1 parent 6b0ebe9 commit b5cc3a0

10 files changed

Lines changed: 75 additions & 64 deletions

File tree

go.work

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ use (
66
./telemetry
77
./telemetry/datadog
88
./telemetry/otel
9-
./telemetry/slogadapter
9+
./telemetry/slog
1010
)

magefiles/magefile.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import (
2828
// modules is the list of Go modules in the suite, by directory. As new modules
2929
// land (broker, store, sink), add them here and every target picks them
3030
// up automatically.
31-
var modules = []string{"state", "telemetry", "telemetry/slogadapter", "telemetry/otel", "telemetry/datadog"}
31+
var modules = []string{"state", "telemetry", "telemetry/slog", "telemetry/otel", "telemetry/datadog"}
3232

3333
// Pinned tool versions — keep in sync with .github/workflows/ci.yml.
3434
const (

telemetry/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ and this module adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.
1717
SDK.
1818
- Attributes backed by the standard library's `slog.Value`, giving type-safe,
1919
zero-allocation scalar attributes (`Any` is the opt-in boxing escape hatch).
20-
- A `slog` adapter (`telemetry/slogadapter`) that emits spans and metrics as
20+
- A `slog` adapter (`telemetry/slog`) that emits spans and metrics as
2121
structured logs with no conversion.
2222

2323
[Unreleased]: https://github.com/stablekernel/crucible/compare/telemetry/v0.1.0...HEAD

telemetry/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,17 +108,17 @@ optional sub-modules so the core never imports a vendor SDK.
108108

109109
| Adapter | Status | Deps |
110110
| ---------------------- | -------- | ---- |
111-
| [`telemetry/slogadapter`](slogadapter/README.md) | shipped | stdlib `log/slog` only — emits spans/metrics as structured logs |
111+
| [`telemetry/slog`](slog/README.md) | shipped | stdlib `log/slog` only — emits spans/metrics as structured logs |
112112
| [`telemetry/otel`](otel/README.md) | shipped | OpenTelemetry SDK (in its own `go.mod`) |
113113
| [`telemetry/datadog`](datadog/README.md) | shipped | `dd-trace-go` / `datadog-go` (in their own `go.mod`) |
114114

115115
Each adapter implements the same interfaces and is wired by a consumer via
116-
`WithTracer`/`WithMeter` exactly like `slogadapter`. `Span.SetStatus` maps to the
116+
`WithTracer`/`WithMeter` exactly like the `slog` adapter. `Span.SetStatus` maps to the
117117
otel status code / Datadog error flag; `ResolveInstrument` exposes the
118118
unit/description an adapter needs to construct its backend instrument. Attributes
119119
are converted with a `switch` over `attr.Value.Kind()` (the `slog.Value` kind),
120120
reading the typed accessor for each scalar kind and `Value.Any()` only for the
121-
`KindAny` escape hatch. The `slogadapter` is conversion-free because `Attr` is
121+
`KindAny` escape hatch. The `slog` adapter is conversion-free because `Attr` is
122122
already `slog.Attr`.
123123

124124
## Stability

telemetry/doc.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,15 +88,15 @@
8888
// Adapters translate this interface to a concrete backend and ship as separate,
8989
// optional sub-modules so the core never imports a vendor SDK:
9090
//
91-
// - telemetry/slogadapter — a standard-library log/slog adapter (zero external
91+
// - telemetry/slog — a standard-library log/slog adapter (zero external
9292
// deps) that emits spans and metrics as structured logs. Shipped here; it
9393
// proves the seam end to end. Because Attr is slog.Attr, this adapter is
9494
// conversion-free: attributes pass straight to the slog handler.
9595
// - telemetry/otel, telemetry/datadog — deferred. Each would live in its own
9696
// sub-module with its own go.mod that requires the vendor SDK, implement the
9797
// same interfaces (Span.SetStatus -> otel status / dd error flag,
9898
// ResolveInstrument -> instrument unit/description), and be wired by a
99-
// consumer via WithTracer/WithMeter exactly like slogadapter. They convert
99+
// consumer via WithTracer/WithMeter exactly like the slog adapter. They convert
100100
// each attribute with a switch over Attr.Value.Kind (the slog.Value kind),
101101
// reading the typed accessor for each scalar kind and Value.Any only for the
102102
// KindAny escape hatch.
Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
# crucible/telemetry/slogadapter
1+
# crucible/telemetry/slog
22

33
A standard-library `log/slog` adapter for
44
[`crucible/telemetry`](../README.md). Emits spans and metric instruments as
55
structured log records, with **zero external dependencies**.
66

7-
Import path: `github.com/stablekernel/crucible/telemetry/slogadapter`
7+
Import path: `github.com/stablekernel/crucible/telemetry/slog`
88

99
## What it is
1010

11-
`slogadapter` implements the `telemetry.Tracer` and `telemetry.Meter` interfaces
11+
This adapter implements the `telemetry.Tracer` and `telemetry.Meter` interfaces
1212
on top of Go's `log/slog`. It is the reference adapter — it proves the telemetry
1313
seam end to end without pulling in any vendor SDK — and is useful for
1414
development, tests, and environments where structured logs are the only
@@ -24,14 +24,25 @@ adapter against the same interfaces.
2424

2525
## Usage
2626

27+
The package name is `slog`, which collides with the standard library's
28+
`log/slog`. Import it under an alias (e.g. `crucibleslog`) in any file that also
29+
imports `log/slog`:
30+
2731
```go
32+
import (
33+
"log/slog"
34+
35+
"github.com/stablekernel/crucible/telemetry"
36+
crucibleslog "github.com/stablekernel/crucible/telemetry/slog"
37+
)
38+
2839
logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
2940
Level: slog.LevelDebug, // span/metric records are emitted at DEBUG
3041
}))
3142

3243
tel := telemetry.Nop().Apply(
33-
telemetry.WithTracer(slogadapter.NewTracer(slogadapter.WithLogger(logger))),
34-
telemetry.WithMeter(slogadapter.NewMeter(slogadapter.WithLogger(logger))),
44+
telemetry.WithTracer(crucibleslog.NewTracer(crucibleslog.WithLogger(logger))),
45+
telemetry.WithMeter(crucibleslog.NewMeter(crucibleslog.WithLogger(logger))),
3546
)
3647
```
3748

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
package slogadapter_test
1+
package slog_test
22

33
import (
44
"context"
55
"log/slog"
66
"os"
77

88
"github.com/stablekernel/crucible/telemetry"
9-
"github.com/stablekernel/crucible/telemetry/slogadapter"
9+
crucibleslog "github.com/stablekernel/crucible/telemetry/slog"
1010
)
1111

1212
// Example wires the slog adapter into a consuming module's telemetry Provider,
@@ -28,8 +28,8 @@ func Example() {
2828
}))
2929

3030
tel := telemetry.Nop().Apply(
31-
telemetry.WithTracer(slogadapter.NewTracer(slogadapter.WithLogger(logger))),
32-
telemetry.WithMeter(slogadapter.NewMeter(slogadapter.WithLogger(logger))),
31+
telemetry.WithTracer(crucibleslog.NewTracer(crucibleslog.WithLogger(logger))),
32+
telemetry.WithMeter(crucibleslog.NewMeter(crucibleslog.WithLogger(logger))),
3333
)
3434

3535
ctx, span := tel.Tracer.Start(context.Background(), "sink.Sink")
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module github.com/stablekernel/crucible/telemetry/slogadapter
1+
module github.com/stablekernel/crucible/telemetry/slog
22

33
go 1.25
44

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
// Package slogadapter implements the Crucible telemetry interfaces on top of the
1+
// Package slog implements the Crucible telemetry interfaces on top of the
22
// standard library's log/slog. It proves the telemetry seam end to end using
33
// zero external dependencies: spans and metric instruments are emitted as
44
// structured log records.
55
//
6-
// Import path: github.com/stablekernel/crucible/telemetry/slogadapter
6+
// Import path: github.com/stablekernel/crucible/telemetry/slog
77
//
88
// It is intended for development, tests, and environments where structured logs
99
// are the only observability sink. For production tracing/metrics backends, use
@@ -22,11 +22,11 @@
2222
//
2323
// All durations are sourced from an injectable clock so emission is
2424
// deterministic in tests.
25-
package slogadapter
25+
package slog
2626

2727
import (
2828
"context"
29-
"log/slog"
29+
sl "log/slog"
3030
"sync/atomic"
3131
"time"
3232

@@ -35,7 +35,7 @@ import (
3535

3636
// config holds resolved Option state.
3737
type config struct {
38-
logger *slog.Logger
38+
logger *sl.Logger
3939
now func() time.Time
4040
nextID func() uint64
4141
}
@@ -46,7 +46,7 @@ type Option func(*config)
4646
// WithLogger sets the slog.Logger the adapter emits to. The default discards all
4747
// records (slog.New(slog.DiscardHandler)), keeping the adapter silent until a
4848
// real logger is supplied.
49-
func WithLogger(l *slog.Logger) Option {
49+
func WithLogger(l *sl.Logger) Option {
5050
return func(c *config) {
5151
if l != nil {
5252
c.logger = l
@@ -78,7 +78,7 @@ func WithIDFn(next func() uint64) Option {
7878
func resolve(opts ...Option) config {
7979
ctr := new(atomic.Uint64)
8080
c := config{
81-
logger: slog.New(slog.DiscardHandler),
81+
logger: sl.New(sl.DiscardHandler),
8282
now: time.Now,
8383
nextID: func() uint64 { return ctr.Add(1) },
8484
}
@@ -105,12 +105,12 @@ func (t *Tracer) Start(ctx context.Context, name string, attrs ...telemetry.Attr
105105
id := t.cfg.nextID()
106106
parent, hasParent := ctx.Value(spanIDKey{}).(uint64)
107107

108-
logAttrs := []any{slog.String("name", name), slog.Uint64("id", id)}
108+
logAttrs := []any{sl.String("name", name), sl.Uint64("id", id)}
109109
if hasParent {
110-
logAttrs = append(logAttrs, slog.Uint64("parent", parent))
110+
logAttrs = append(logAttrs, sl.Uint64("parent", parent))
111111
}
112112
logAttrs = append(logAttrs, attrArgs(attrs)...)
113-
t.cfg.logger.LogAttrs(ctx, slog.LevelDebug, "span.start", slog.Group("span", logAttrs...))
113+
t.cfg.logger.LogAttrs(ctx, sl.LevelDebug, "span.start", sl.Group("span", logAttrs...))
114114

115115
s := &span{
116116
cfg: t.cfg,
@@ -136,19 +136,19 @@ func (s *span) SetAttributes(attrs ...telemetry.Attr) {
136136
if s.ended {
137137
return
138138
}
139-
args := append([]any{slog.String("name", s.name), slog.Uint64("id", s.id)}, attrArgs(attrs)...)
140-
s.cfg.logger.LogAttrs(context.Background(), slog.LevelDebug, "span.attributes", slog.Group("span", args...))
139+
args := append([]any{sl.String("name", s.name), sl.Uint64("id", s.id)}, attrArgs(attrs)...)
140+
s.cfg.logger.LogAttrs(context.Background(), sl.LevelDebug, "span.attributes", sl.Group("span", args...))
141141
}
142142

143143
func (s *span) RecordError(err error) {
144144
if s.ended || err == nil {
145145
return
146146
}
147-
s.cfg.logger.LogAttrs(context.Background(), slog.LevelError, "span.error",
148-
slog.Group("span",
149-
slog.String("name", s.name),
150-
slog.Uint64("id", s.id),
151-
slog.String("error", err.Error()),
147+
s.cfg.logger.LogAttrs(context.Background(), sl.LevelError, "span.error",
148+
sl.Group("span",
149+
sl.String("name", s.name),
150+
sl.Uint64("id", s.id),
151+
sl.String("error", err.Error()),
152152
),
153153
)
154154
}
@@ -167,20 +167,20 @@ func (s *span) End() {
167167
}
168168
s.ended = true
169169
args := []any{
170-
slog.String("name", s.name),
171-
slog.Uint64("id", s.id),
172-
slog.String("status", statusString(s.status)),
173-
slog.Duration("elapsed", s.cfg.now().Sub(s.start)),
170+
sl.String("name", s.name),
171+
sl.Uint64("id", s.id),
172+
sl.String("status", statusString(s.status)),
173+
sl.Duration("elapsed", s.cfg.now().Sub(s.start)),
174174
}
175175
if s.statusMsg != "" {
176-
args = append(args, slog.String("status_msg", s.statusMsg))
176+
args = append(args, sl.String("status_msg", s.statusMsg))
177177
}
178-
s.cfg.logger.LogAttrs(context.Background(), slog.LevelDebug, "span.end", slog.Group("span", args...))
178+
s.cfg.logger.LogAttrs(context.Background(), sl.LevelDebug, "span.end", sl.Group("span", args...))
179179
}
180180

181181
// Meter is a telemetry.Meter backed by slog.
182182
type Meter struct {
183-
logger *slog.Logger
183+
logger *sl.Logger
184184
}
185185

186186
// NewMeter returns a slog-backed Meter.
@@ -203,30 +203,30 @@ func (m *Meter) Gauge(name string, opts ...telemetry.InstrumentOption) telemetry
203203

204204
// instrument backs Counter, Histogram, and Gauge: each logs a "metric" record.
205205
type instrument struct {
206-
logger *slog.Logger
206+
logger *sl.Logger
207207
name string
208208
kind string
209209
cfg telemetry.InstrumentConfig
210210
}
211211

212212
func (i *instrument) Add(ctx context.Context, n int64, attrs ...telemetry.Attr) {
213-
i.emit(ctx, slog.Int64("value", n), attrs)
213+
i.emit(ctx, sl.Int64("value", n), attrs)
214214
}
215215

216216
func (i *instrument) Record(ctx context.Context, v float64, attrs ...telemetry.Attr) {
217-
i.emit(ctx, slog.Float64("value", v), attrs)
217+
i.emit(ctx, sl.Float64("value", v), attrs)
218218
}
219219

220-
func (i *instrument) emit(ctx context.Context, value slog.Attr, attrs []telemetry.Attr) {
221-
args := []any{slog.String("name", i.name), slog.String("kind", i.kind), value}
220+
func (i *instrument) emit(ctx context.Context, value sl.Attr, attrs []telemetry.Attr) {
221+
args := []any{sl.String("name", i.name), sl.String("kind", i.kind), value}
222222
if i.cfg.Unit != "" {
223-
args = append(args, slog.String("unit", i.cfg.Unit))
223+
args = append(args, sl.String("unit", i.cfg.Unit))
224224
}
225225
if i.cfg.Description != "" {
226-
args = append(args, slog.String("description", i.cfg.Description))
226+
args = append(args, sl.String("description", i.cfg.Description))
227227
}
228228
args = append(args, attrArgs(attrs)...)
229-
i.logger.LogAttrs(ctx, slog.LevelDebug, "metric", slog.Group("metric", args...))
229+
i.logger.LogAttrs(ctx, sl.LevelDebug, "metric", sl.Group("metric", args...))
230230
}
231231

232232
// attrArgs nests the telemetry attributes under a single "attrs" group so their
@@ -241,7 +241,7 @@ func attrArgs(attrs []telemetry.Attr) []any {
241241
for i, a := range attrs {
242242
inner[i] = a
243243
}
244-
return []any{slog.Group("attrs", inner...)}
244+
return []any{sl.Group("attrs", inner...)}
245245
}
246246

247247
func statusString(c telemetry.StatusCode) string {

0 commit comments

Comments
 (0)