zotregistry.dev/zot@v1.4.4-0.20240314164342-eec277e14d20/pkg/log/log.go (about) 1 package log 2 3 import ( 4 "os" 5 "runtime" 6 "strconv" 7 "strings" 8 "sync" 9 "time" 10 11 "github.com/rs/zerolog" 12 ) 13 14 const defaultPerms = 0o0600 15 16 //nolint:gochecknoglobals 17 var loggerSetTimeFormat sync.Once 18 19 // Logger extends zerolog's Logger. 20 type Logger struct { 21 zerolog.Logger 22 } 23 24 func (l Logger) Println(v ...interface{}) { 25 l.Logger.Error().Msg("panic recovered") //nolint: check-logs 26 } 27 28 func NewLogger(level, output string) Logger { 29 loggerSetTimeFormat.Do(func() { 30 zerolog.TimeFieldFormat = time.RFC3339Nano 31 }) 32 33 lvl, err := zerolog.ParseLevel(level) 34 if err != nil { 35 panic(err) 36 } 37 38 zerolog.SetGlobalLevel(lvl) 39 40 var log zerolog.Logger 41 42 if output == "" { 43 log = zerolog.New(os.Stdout) 44 } else { 45 file, err := os.OpenFile(output, os.O_APPEND|os.O_WRONLY|os.O_CREATE, defaultPerms) 46 if err != nil { 47 panic(err) 48 } 49 log = zerolog.New(file) 50 } 51 52 return Logger{Logger: log.Hook(goroutineHook{}).With().Caller().Timestamp().Logger()} 53 } 54 55 func NewAuditLogger(level, output string) *Logger { 56 loggerSetTimeFormat.Do(func() { 57 zerolog.TimeFieldFormat = time.RFC3339Nano 58 }) 59 60 lvl, err := zerolog.ParseLevel(level) 61 if err != nil { 62 panic(err) 63 } 64 65 zerolog.SetGlobalLevel(lvl) 66 67 var auditLog zerolog.Logger 68 69 if output == "" { 70 auditLog = zerolog.New(os.Stdout) 71 } else { 72 auditFile, err := os.OpenFile(output, os.O_APPEND|os.O_WRONLY|os.O_CREATE, defaultPerms) 73 if err != nil { 74 panic(err) 75 } 76 77 auditLog = zerolog.New(auditFile) 78 } 79 80 return &Logger{Logger: auditLog.With().Timestamp().Logger()} 81 } 82 83 // GoroutineID adds goroutine-id to logs to help debug concurrency issues. 84 func GoroutineID() int { 85 var buf [64]byte 86 n := runtime.Stack(buf[:], false) 87 idField := strings.Fields(strings.TrimPrefix(string(buf[:n]), "goroutine "))[0] 88 89 id, err := strconv.Atoi(idField) 90 if err != nil { 91 return -1 92 } 93 94 return id 95 } 96 97 type goroutineHook struct{} 98 99 func (h goroutineHook) Run(e *zerolog.Event, level zerolog.Level, _ string) { 100 if level != zerolog.NoLevel { 101 e.Int("goroutine", GoroutineID()) 102 } 103 }