Ztorrent/internal/logger/logger.go

107 lines
1.8 KiB
Go

package logger
import (
"fmt"
"sync"
"time"
)
type Level int
const (
LevelDebug Level = iota
LevelInfo
LevelWarn
LevelError
)
func (l Level) String() string {
switch l {
case LevelDebug:
return "DEBUG"
case LevelInfo:
return "INFO"
case LevelWarn:
return "WARN"
case LevelError:
return "ERROR"
default:
return "UNKNOWN"
}
}
type Entry struct {
Time time.Time
Level Level
Category string
Message string
}
type RingBuffer struct {
mu sync.RWMutex
entries []Entry
head int
count int
size int
}
func NewRingBuffer(size int) *RingBuffer {
return &RingBuffer{
entries: make([]Entry, size),
size: size,
}
}
func (b *RingBuffer) Add(e Entry) {
b.mu.Lock()
defer b.mu.Unlock()
b.entries[b.head] = e
b.head = (b.head + 1) % b.size
if b.count < b.size {
b.count++
}
}
func (b *RingBuffer) Snapshot() []Entry {
b.mu.RLock()
defer b.mu.RUnlock()
result := make([]Entry, b.count)
for i := 0; i < b.count; i++ {
idx := (b.head - b.count + i + b.size) % b.size
result[i] = b.entries[idx]
}
return result
}
// Global logger instance
var (
GlobalBuffer = NewRingBuffer(1000)
)
func logf(level Level, category string, format string, v ...interface{}) {
msg := fmt.Sprintf(format, v...)
GlobalBuffer.Add(Entry{
Time: time.Now(),
Level: level,
Category: category,
Message: msg,
})
}
func Debug(category string, format string, v ...interface{}) {
logf(LevelDebug, category, format, v...)
}
func Info(category string, format string, v ...interface{}) {
logf(LevelInfo, category, format, v...)
}
func Warn(category string, format string, v ...interface{}) {
logf(LevelWarn, category, format, v...)
}
func Error(category string, format string, v ...interface{}) {
logf(LevelError, category, format, v...)
}