mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-02-19 21:00:52 +08:00
79 lines
1.5 KiB
Go
79 lines
1.5 KiB
Go
package tui
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"sync"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
// LogHook is a logrus hook that captures log entries and sends them to a channel.
|
|
type LogHook struct {
|
|
ch chan string
|
|
formatter log.Formatter
|
|
mu sync.Mutex
|
|
levels []log.Level
|
|
}
|
|
|
|
// NewLogHook creates a new LogHook with a buffered channel of the given size.
|
|
func NewLogHook(bufSize int) *LogHook {
|
|
return &LogHook{
|
|
ch: make(chan string, bufSize),
|
|
formatter: &log.TextFormatter{DisableColors: true, FullTimestamp: true},
|
|
levels: log.AllLevels,
|
|
}
|
|
}
|
|
|
|
// SetFormatter sets a custom formatter for the hook.
|
|
func (h *LogHook) SetFormatter(f log.Formatter) {
|
|
h.mu.Lock()
|
|
defer h.mu.Unlock()
|
|
h.formatter = f
|
|
}
|
|
|
|
// Levels returns the log levels this hook should fire on.
|
|
func (h *LogHook) Levels() []log.Level {
|
|
return h.levels
|
|
}
|
|
|
|
// Fire is called by logrus when a log entry is fired.
|
|
func (h *LogHook) Fire(entry *log.Entry) error {
|
|
h.mu.Lock()
|
|
f := h.formatter
|
|
h.mu.Unlock()
|
|
|
|
var line string
|
|
if f != nil {
|
|
b, err := f.Format(entry)
|
|
if err == nil {
|
|
line = strings.TrimRight(string(b), "\n\r")
|
|
} else {
|
|
line = fmt.Sprintf("[%s] %s", entry.Level, entry.Message)
|
|
}
|
|
} else {
|
|
line = fmt.Sprintf("[%s] %s", entry.Level, entry.Message)
|
|
}
|
|
|
|
// Non-blocking send
|
|
select {
|
|
case h.ch <- line:
|
|
default:
|
|
// Drop oldest if full
|
|
select {
|
|
case <-h.ch:
|
|
default:
|
|
}
|
|
select {
|
|
case h.ch <- line:
|
|
default:
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Chan returns the channel to read log lines from.
|
|
func (h *LogHook) Chan() <-chan string {
|
|
return h.ch
|
|
}
|