mirror of
https://github.com/YspCoder/clawgo.git
synced 2026-04-15 01:37:31 +08:00
fix
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -37,7 +38,11 @@ var (
|
||||
)
|
||||
|
||||
type Logger struct {
|
||||
file *os.File
|
||||
file *os.File
|
||||
filePath string
|
||||
maxSizeBytes int64
|
||||
maxAgeDays int
|
||||
fileMu sync.Mutex
|
||||
}
|
||||
|
||||
type LogEntry struct {
|
||||
@@ -68,9 +73,25 @@ func GetLevel() LogLevel {
|
||||
}
|
||||
|
||||
func EnableFileLogging(filePath string) error {
|
||||
return EnableFileLoggingWithRotation(filePath, 20, 3)
|
||||
}
|
||||
|
||||
func EnableFileLoggingWithRotation(filePath string, maxSizeMB, maxAgeDays int) error {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
if maxSizeMB <= 0 {
|
||||
maxSizeMB = 20
|
||||
}
|
||||
if maxAgeDays <= 0 {
|
||||
maxAgeDays = 3
|
||||
}
|
||||
|
||||
dir := filepath.Dir(filePath)
|
||||
if err := os.MkdirAll(dir, 0755); err != nil {
|
||||
return fmt.Errorf("failed to create log directory: %w", err)
|
||||
}
|
||||
|
||||
file, err := os.OpenFile(filePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open log file: %w", err)
|
||||
@@ -81,6 +102,12 @@ func EnableFileLogging(filePath string) error {
|
||||
}
|
||||
|
||||
logger.file = file
|
||||
logger.filePath = filePath
|
||||
logger.maxSizeBytes = int64(maxSizeMB) * 1024 * 1024
|
||||
logger.maxAgeDays = maxAgeDays
|
||||
if err := logger.cleanupOldLogFiles(); err != nil {
|
||||
log.Println("Failed to clean up old log files:", err)
|
||||
}
|
||||
log.Println("File logging enabled:", filePath)
|
||||
return nil
|
||||
}
|
||||
@@ -92,6 +119,9 @@ func DisableFileLogging() {
|
||||
if logger.file != nil {
|
||||
logger.file.Close()
|
||||
logger.file = nil
|
||||
logger.filePath = ""
|
||||
logger.maxSizeBytes = 0
|
||||
logger.maxAgeDays = 0
|
||||
log.Println("File logging disabled")
|
||||
}
|
||||
}
|
||||
@@ -119,7 +149,9 @@ func logMessage(level LogLevel, component string, message string, fields map[str
|
||||
if logger.file != nil {
|
||||
jsonData, err := json.Marshal(entry)
|
||||
if err == nil {
|
||||
logger.file.WriteString(string(jsonData) + "\n")
|
||||
if err := logger.writeLine(append(jsonData, '\n')); err != nil {
|
||||
log.Println("Failed to write file log:", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,6 +175,88 @@ func logMessage(level LogLevel, component string, message string, fields map[str
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Logger) writeLine(line []byte) error {
|
||||
l.fileMu.Lock()
|
||||
defer l.fileMu.Unlock()
|
||||
|
||||
if l.file == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if l.maxSizeBytes > 0 {
|
||||
if err := l.rotateIfNeeded(int64(len(line))); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
_, err := l.file.Write(line)
|
||||
return err
|
||||
}
|
||||
|
||||
func (l *Logger) rotateIfNeeded(nextWrite int64) error {
|
||||
info, err := l.file.Stat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if info.Size()+nextWrite <= l.maxSizeBytes {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := l.file.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
backupPath := fmt.Sprintf("%s.%s", l.filePath, time.Now().UTC().Format("20060102-150405"))
|
||||
if err := os.Rename(l.filePath, backupPath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
file, err := os.OpenFile(l.filePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
l.file = file
|
||||
|
||||
return l.cleanupOldLogFiles()
|
||||
}
|
||||
|
||||
func (l *Logger) cleanupOldLogFiles() error {
|
||||
if l.maxAgeDays <= 0 || l.filePath == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
dir := filepath.Dir(l.filePath)
|
||||
base := filepath.Base(l.filePath)
|
||||
entries, err := os.ReadDir(dir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cutoff := time.Now().AddDate(0, 0, -l.maxAgeDays)
|
||||
for _, entry := range entries {
|
||||
if entry.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
name := entry.Name()
|
||||
// Only delete rotated files like clawgo.log.20260213-120000
|
||||
if !strings.HasPrefix(name, base+".") {
|
||||
continue
|
||||
}
|
||||
|
||||
info, err := entry.Info()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if info.ModTime().Before(cutoff) {
|
||||
_ = os.Remove(filepath.Join(dir, name))
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func formatComponent(component string) string {
|
||||
if component == "" {
|
||||
return ""
|
||||
|
||||
Reference in New Issue
Block a user