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
|
package logging
import (
"context"
"io"
"log/slog"
"os"
"runtime"
)
type Config struct {
Level slog.Level `toml:"level"`
File string `toml:"file"`
}
func SetupLogger(cfg Config) *slog.Logger {
opts := &slog.HandlerOptions{Level: cfg.Level}
var handler slog.Handler
var writter io.Writer
writter = os.Stdout
if cfg.File != "" {
f, _ := os.OpenFile(cfg.File, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
writter = f
}
handler = slog.NewJSONHandler(writter, opts)
logger := slog.New(handler)
slog.SetDefault(logger)
return logger
}
type contextKeyType struct{}
var contextKey contextKeyType
func WithLogger(ctx context.Context, logger *slog.Logger) context.Context {
return context.WithValue(ctx, contextKey, logger)
}
func FromContext(ctx context.Context) *slog.Logger {
if logger, ok := ctx.Value(contextKey).(*slog.Logger); ok {
return logger
}
return slog.Default()
}
func RecoverLog(ctx context.Context, err any) {
logger := FromContext(ctx)
const size = 64 << 10
buf := make([]byte, size)
buf = buf[:runtime.Stack(buf, false)]
logger.Log(ctx, slog.LevelError, "Program Paniced", "error", err, "stack", string(buf))
}
|