mirror of
https://git.sr.ht/~ashkeel/strimertul
synced 2024-09-30 02:40:33 +00:00
112 lines
2.4 KiB
Go
112 lines
2.4 KiB
Go
package main
|
|
|
|
import (
|
|
"os"
|
|
"time"
|
|
|
|
"git.sr.ht/~ashkeel/containers/sync"
|
|
|
|
"go.uber.org/zap"
|
|
"go.uber.org/zap/zapcore"
|
|
"gopkg.in/natefinch/lumberjack.v2"
|
|
)
|
|
|
|
const LogHistory = 50
|
|
|
|
var (
|
|
logger *zap.Logger
|
|
lastLogs *sync.Slice[LogEntry]
|
|
incomingLogs chan LogEntry
|
|
)
|
|
|
|
func initLogger(level zapcore.Level) {
|
|
lastLogs = sync.NewSlice[LogEntry]()
|
|
incomingLogs = make(chan LogEntry, 100)
|
|
logStorage := NewLogStorage(level)
|
|
consoleLogger := zapcore.NewCore(
|
|
zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig()),
|
|
zapcore.Lock(os.Stderr),
|
|
level,
|
|
)
|
|
fileLogger := zapcore.NewCore(
|
|
zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()),
|
|
zapcore.AddSync(&lumberjack.Logger{
|
|
Filename: logFilename,
|
|
MaxSize: 20,
|
|
MaxBackups: 3,
|
|
MaxAge: 28,
|
|
}),
|
|
level,
|
|
)
|
|
core := zapcore.NewTee(
|
|
consoleLogger,
|
|
fileLogger,
|
|
logStorage,
|
|
)
|
|
logger = zap.New(core, zap.AddCaller())
|
|
}
|
|
|
|
type LogEntry struct {
|
|
Caller string `json:"caller"`
|
|
Time string `json:"time"`
|
|
Level string `json:"level"`
|
|
Message string `json:"message"`
|
|
Data string `json:"data"`
|
|
}
|
|
|
|
type LogStorage struct {
|
|
zapcore.LevelEnabler
|
|
fields []zapcore.Field
|
|
encoder zapcore.Encoder
|
|
}
|
|
|
|
func NewLogStorage(enabler zapcore.LevelEnabler) *LogStorage {
|
|
return &LogStorage{
|
|
LevelEnabler: enabler,
|
|
encoder: zapcore.NewJSONEncoder(zap.NewDevelopmentEncoderConfig()),
|
|
}
|
|
}
|
|
|
|
func (core *LogStorage) With(fields []zapcore.Field) zapcore.Core {
|
|
clone := *core
|
|
clone.fields = append(clone.fields, fields...)
|
|
return &clone
|
|
}
|
|
|
|
func (core *LogStorage) Check(entry zapcore.Entry, checked *zapcore.CheckedEntry) *zapcore.CheckedEntry {
|
|
if core.Enabled(entry.Level) {
|
|
return checked.AddCore(entry, core)
|
|
}
|
|
return checked
|
|
}
|
|
|
|
func (core *LogStorage) Write(entry zapcore.Entry, fields []zapcore.Field) error {
|
|
buf, err := core.encoder.EncodeEntry(entry, append(core.fields, fields...))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
logEntry := LogEntry{
|
|
Caller: entry.Caller.String(),
|
|
Time: entry.Time.Format(time.RFC3339),
|
|
Level: entry.Level.String(),
|
|
Message: entry.Message,
|
|
Data: buf.String(),
|
|
}
|
|
lastLogs.Push(logEntry)
|
|
if lastLogs.Size() > LogHistory {
|
|
lastLogs.Splice(0, 1)
|
|
}
|
|
incomingLogs <- logEntry
|
|
return nil
|
|
}
|
|
|
|
func (core *LogStorage) Sync() error {
|
|
return nil
|
|
}
|
|
|
|
func parseAsFields(fields map[string]any) (result []zapcore.Field) {
|
|
for k, v := range fields {
|
|
result = append(result, zap.Any(k, v))
|
|
}
|
|
return
|
|
}
|