1package log
2
3import (
4 "fmt"
5 "log/slog"
6 "os"
7 "runtime/debug"
8 "sync"
9 "time"
10
11 "gopkg.in/natefinch/lumberjack.v2"
12)
13
14var initOnce sync.Once
15
16func Init(logFile string, debug bool) {
17 initOnce.Do(func() {
18 logRotator := &lumberjack.Logger{
19 Filename: logFile,
20 MaxSize: 10, // Max size in MB
21 MaxBackups: 0, // Number of backups
22 MaxAge: 30, // Days
23 Compress: false, // Enable compression
24 }
25
26 level := slog.LevelInfo
27 if debug {
28 level = slog.LevelDebug
29 }
30
31 logger := slog.NewJSONHandler(logRotator, &slog.HandlerOptions{
32 Level: level,
33 AddSource: true,
34 })
35
36 slog.SetDefault(slog.New(logger))
37 })
38}
39
40func RecoverPanic(name string, cleanup func()) {
41 if r := recover(); r != nil {
42 // Create a timestamped panic log file
43 timestamp := time.Now().Format("20060102-150405")
44 filename := fmt.Sprintf("crush-panic-%s-%s.log", name, timestamp)
45
46 file, err := os.Create(filename)
47 if err == nil {
48 defer file.Close()
49
50 // Write panic information and stack trace
51 fmt.Fprintf(file, "Panic in %s: %v\n\n", name, r)
52 fmt.Fprintf(file, "Time: %s\n\n", time.Now().Format(time.RFC3339))
53 fmt.Fprintf(file, "Stack Trace:\n%s\n", debug.Stack())
54
55 // Execute cleanup function if provided
56 if cleanup != nil {
57 cleanup()
58 }
59 }
60 }
61}