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
|
package util
import (
"context"
"fmt"
"log/slog"
"os"
)
type MultiHandler struct {
handlers []slog.Handler
}
func NewMultiHandler(handlers ...slog.Handler) *MultiHandler {
return &MultiHandler{handlers: handlers}
}
func (m *MultiHandler) Enabled(ctx context.Context, level slog.Level) bool {
for _, h := range m.handlers {
if h.Enabled(ctx, level) {
return true
}
}
return false
}
func (m *MultiHandler) Handle(ctx context.Context, record slog.Record) error {
for _, h := range m.handlers {
_ = h.Handle(ctx, record) // Process each handler, ignoring errors
}
return nil
}
func (m *MultiHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
newHandlers := make([]slog.Handler, len(m.handlers))
for i, h := range m.handlers {
newHandlers[i] = h.WithAttrs(attrs)
}
return &MultiHandler{handlers: newHandlers}
}
func (m *MultiHandler) WithGroup(name string) slog.Handler {
newHandlers := make([]slog.Handler, len(m.handlers))
for i, h := range m.handlers {
newHandlers[i] = h.WithGroup(name)
}
return &MultiHandler{handlers: newHandlers}
}
type options struct {
logName string
stdoutLevel slog.Level
fileLevel slog.Level
}
func SetupLogger(opts ...func(*options)) (*os.File, error) {
o := options{
logName: "logs/Default.log",
stdoutLevel: slog.LevelInfo,
fileLevel: slog.LevelDebug,
}
for _, opt := range opts {
opt(&o)
}
logFile, err := os.OpenFile(o.logName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o666)
if err != nil {
return nil, fmt.Errorf("no file opened for logs: %v", err)
}
stdoutHandler := slog.NewTextHandler(os.Stdout,
&slog.HandlerOptions{Level: o.stdoutLevel})
fileHandler := slog.NewJSONHandler(logFile,
&slog.HandlerOptions{Level: o.fileLevel})
logger := slog.New(NewMultiHandler(stdoutHandler, fileHandler))
slog.SetDefault(logger)
return logFile, err
}
func WithLogName(name string) func(*options) {
return func(o *options) {
o.logName = name
}
}
func WithStdoutLevel(level slog.Level) func(*options) {
return func(o *options) {
o.stdoutLevel = level
}
}
func WithFileLevel(level slog.Level) func(*options) {
return func(o *options) {
o.fileLevel = level
}
}
|