-
Notifications
You must be signed in to change notification settings - Fork 2
/
examples_test.go
145 lines (126 loc) · 4.61 KB
/
examples_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package slogctx_test
import (
"context"
"errors"
"log/slog"
"os"
slogctx "github.com/veqryn/slog-context"
)
func ExampleNewHandler() {
// This workflow lets us use slog as normal, while adding the ability to put
// slog attributes into the context which will then show up at the start or end
// of log lines.
//
// This is useful when you are not passing a *slog.Logger around to different
// functions (because you are making use of the default package-level slog),
// but you are passing a context.Context around.
//
// This can also be used when a library or vendor code you don't control is
// using the default log methods, default logger, or doesn't accept a slog
// Logger to all functions you wish to add attributes to.
//
// Attributes and key-value pairs like request-id, trace-id, user-id, etc, can
// be added to the context, and the *slogctx.Handler will make sure they
// are prepended to the start, or appended to the end, of any log lines using
// that context.
// Create the *slogctx.Handler middleware
h := slogctx.NewHandler(slog.NewJSONHandler(os.Stdout, nil), nil)
slog.SetDefault(slog.New(h))
ctx := context.Background()
// Prepend some slog attributes to the start of future log lines:
ctx = slogctx.Prepend(ctx, "prependKey", "prependValue")
// Append some slog attributes to the end of future log lines:
// Prepend and Append have the same args signature as slog methods,
// and can take a mix of slog.Attr and key-value pairs.
ctx = slogctx.Append(ctx, slog.String("appendKey", "appendValue"))
// Use the logger like normal:
slog.WarnContext(ctx, "main message", "mainKey", "mainValue")
/*
{
"time": "2023-11-15T18:43:23.290798-07:00",
"level": "WARN",
"msg": "main message",
"prependKey": "prependValue",
"mainKey": "mainValue",
"appendKey": "appendValue"
}
*/
// Use the logger like normal; add attributes, create groups, pass it around:
log := slog.With("rootKey", "rootValue")
log = log.WithGroup("someGroup")
log = log.With("subKey", "subValue")
// The prepended/appended attributes end up in all log lines that use that context
log.InfoContext(ctx, "main message", "mainKey", "mainValue")
/*
{
"time": "2023-11-14T00:37:03.805196-07:00",
"level": "INFO",
"msg": "main message",
"prependKey": "prependValue",
"rootKey": "rootValue",
"someGroup": {
"subKey": "subValue",
"mainKey": "mainValue",
"appendKey": "appendValue"
}
}
*/
}
func ExampleNewCtx() {
// This workflow has us pass the *slog.Logger around inside a context.Context.
// This lets us add attributes and groups to the logger, while naturally
// keeping the logger scoped just like the context itself is scoped.
//
// This eliminates the need to use the default package-level slog, and also
// eliminates the need to add a *slog.Logger as yet another argument to all
// functions.
//
// You can still get the Logger out of the context at any time, and pass it
// around manually if needed, but since contexts are already passed to most
// functions, passing the logger explicitly is now optional.
//
// Attributes and key-value pairs like request-id, trace-id, user-id, etc, can
// be added to the logger in the context, and as the context propagates the
// logger and its attributes will propagate with it, adding these to any log
// lines using that context.
h := slogctx.NewHandler(slog.NewJSONHandler(os.Stdout, nil), nil)
slog.SetDefault(slog.New(h))
// Store the logger inside the context:
ctx := slogctx.NewCtx(context.Background(), slog.Default())
// Get the logger back out again at any time, for manual usage:
log := slogctx.FromCtx(ctx)
log.Warn("warning")
/*
{
"time":"2023-11-14T00:53:46.361201-07:00",
"level":"INFO",
"msg":"warning"
}
*/
// Add attributes directly to the logger in the context:
ctx = slogctx.With(ctx, "rootKey", "rootValue")
// Create a group directly on the logger in the context:
ctx = slogctx.WithGroup(ctx, "someGroup")
// With and wrapper methods have the same args signature as slog methods,
// and can take a mix of slog.Attr and key-value pairs.
ctx = slogctx.With(ctx, slog.String("subKey", "subValue"), slog.Bool("someBool", true))
err := errors.New("an error")
// Access the logger in the context directly with handy wrappers for Debug/Info/Warn/Error/Log/LogAttrs:
slogctx.Error(ctx, "main message",
slogctx.Err(err),
slog.String("mainKey", "mainValue"))
/*
{
"time":"2023-11-14T00:53:46.363072-07:00",
"level":"ERROR",
"msg":"main message",
"rootKey":"rootValue",
"someGroup":{
"subKey":"subValue",
"someBool":true,
"err":"an error",
"mainKey":"mainValue"
}
}
*/
}