Skip to content

Commit 9c00caa

Browse files
committed
feat(cli): implement structured logging
1 parent 6001434 commit 9c00caa

4 files changed

Lines changed: 31 additions & 12 deletions

File tree

cmd/cli/main.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"flag"
66
"fmt"
7+
"log/slog"
78
"os"
89
"time"
910

@@ -14,6 +15,20 @@ import (
1415
"github.com/batovpasha/aws-cw-log-sampler/internal/sample"
1516
)
1617

18+
type contextHandler struct {
19+
slog.Handler
20+
}
21+
type ctxKey string
22+
23+
const traceIDKey ctxKey = "trace_id"
24+
25+
func (h *contextHandler) Handle(ctx context.Context, r slog.Record) error {
26+
if traceId, ok := ctx.Value(traceIDKey).(string); ok {
27+
r.AddAttrs(slog.String(string(traceIDKey), traceId))
28+
}
29+
return h.Handler.Handle(ctx, r)
30+
}
31+
1732
func main() {
1833
fs := flag.CommandLine
1934
flags := cli.RegisterCommonFlags(fs)
@@ -30,7 +45,12 @@ func main() {
3045
os.Exit(1)
3146
}
3247

33-
ctx := context.Background()
48+
h := slog.NewJSONHandler(os.Stdout, nil)
49+
logger := slog.New(&contextHandler{Handler: h})
50+
slog.SetDefault(logger)
51+
traceID := time.Now().UTC().Format(time.RFC3339)
52+
ctx := context.WithValue(context.Background(), traceIDKey, traceID)
53+
3454
cfg, err := config.LoadDefaultConfig(ctx)
3555
if err != nil {
3656
fmt.Fprintln(os.Stderr, err)

internal/cloudwatchlogs/cloudwatchlogs.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ Outer:
4141
return nil, fmt.Errorf("describe log streams: %w", err)
4242
}
4343
if len(output.LogStreams) == 0 {
44-
fmt.Println("no streams found in", logGroupName)
4544
break
4645
}
4746

internal/sample/rand_log_streams.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package sample
33
import (
44
"context"
55
"fmt"
6-
"log"
6+
"log/slog"
77
"math/rand/v2"
88
"sync/atomic"
99
"time"
@@ -36,7 +36,7 @@ func SampleByRandLogStreams(
3636
g.Go(func() error {
3737
processed, err := processLogGroup(ctx, client, cutoff, srcGroup, dstGroup, randLogStreamsNumber)
3838
if err != nil {
39-
fmt.Printf("error processing log group %s: %v\n", srcGroup, err)
39+
slog.WarnContext(ctx, "error processing log group", "log_group", srcGroup, "error", err)
4040
return nil
4141
}
4242
processedLogStreams.Add(processed)
@@ -45,7 +45,7 @@ func SampleByRandLogStreams(
4545
}
4646

4747
_ = g.Wait()
48-
log.Printf("processed %d log streams\n", processedLogStreams.Load())
48+
slog.InfoContext(ctx, "complete log stream processing", "number", processedLogStreams.Load())
4949
}
5050

5151
func processLogGroup(
@@ -60,17 +60,17 @@ func processLogGroup(
6060
return processed, fmt.Errorf("describe log streams: %w", err)
6161
}
6262
if len(allStreams) == 0 {
63-
fmt.Println("no log streams found")
63+
slog.InfoContext(ctx, "no log streams found")
6464
return processed, nil
6565
}
66-
fmt.Printf("number of log streams: %d\n", len(allStreams))
66+
slog.InfoContext(ctx, "list log streams", "number", len(allStreams))
6767

6868
randStreams := pickRandomLogStreams(allStreams, randLogStreamsNumber)
6969
randStreamNames := make([]string, len(randStreams))
7070
for i, s := range randStreams {
7171
randStreamNames[i] = aws.ToString(s.LogStreamName)
7272
}
73-
fmt.Printf("randomly selected streams: %v\n", randStreamNames)
73+
slog.InfoContext(ctx, "pick random log streams", "number", len(randStreamNames))
7474

7575
for _, srcStreamName := range randStreamNames {
7676
// logGroupName/streamName/year/month/day/hour/minutes - almost the same format as CloudWatch Data Protection uses
@@ -80,8 +80,8 @@ func processLogGroup(
8080
srcStreamName,
8181
time.Now().UTC().Format("2006/01/02/15/04"),
8282
)
83-
fmt.Println("destination stream name:", dstStreamName)
8483

84+
slog.InfoContext(ctx, "copy log streams", "src_stream", srcStreamName, "dst_stream", dstStreamName)
8585
err = cloudwatchlogs.CopyLogStream(
8686
ctx,
8787
client,
@@ -91,7 +91,7 @@ func processLogGroup(
9191
dstStreamName,
9292
)
9393
if err != nil {
94-
fmt.Printf("error copying log stream %s: %v\n", srcStreamName, err)
94+
slog.WarnContext(ctx, "error copying log stream", "error", err)
9595
continue
9696
}
9797
processed++

internal/sample/sample.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package sample
33
import (
44
"context"
55
"fmt"
6-
"log"
6+
"log/slog"
77

88
"github.com/batovpasha/aws-cw-log-sampler/internal/cloudwatchlogs"
99
)
@@ -27,7 +27,7 @@ func Sample(ctx context.Context, client *cloudwatchlogs.Client, cfg *Config) err
2727
if err != nil {
2828
return fmt.Errorf("list log groups: %w", err)
2929
}
30-
log.Println("number of log groups:", len(srcGroups))
30+
slog.InfoContext(ctx, "list log groups", "number", len(srcGroups))
3131

3232
switch cfg.Type {
3333
case TypeRandLogStreams:

0 commit comments

Comments
 (0)