summaryrefslogtreecommitdiffstats
path: root/logging/log.go
blob: 8e3078fc10ced8bd7a60bc91960a386938cb2684 (plain) (blame)
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))
}