Ariver
2026-07-12 24f551a39eae849d891da26cc91f90d354e3a2db
C1.source/privatevoice.src/internal/logger/logger.go
@@ -14,23 +14,66 @@
   logFile *os.File
)
const (
   maxLogBytes   = 10 * 1024 * 1024
   maxLogBackups = 3
)
// Init initializes the file logger in the persistent app data directory.
func Init() {
   mu.Lock()
   if logFile != nil {
      logFile.Close()
      logFile = nil
   }
   mu.Unlock()
   dir := paths.AppSupportDir()
   if err := os.MkdirAll(dir, 0755); err != nil {
      fmt.Fprintf(os.Stderr, "failed to create log dir: %v\n", err)
      return
   }
   path := filepath.Join(dir, "app.log")
   if err := rotateIfNeeded(path); err != nil {
      fmt.Fprintf(os.Stderr, "failed to rotate log file: %v\n", err)
   }
   f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
   if err != nil {
      fmt.Fprintf(os.Stderr, "failed to open log file: %v\n", err)
      return
   }
   mu.Lock()
   defer mu.Unlock()
   logFile = f
}
func rotateIfNeeded(path string) error {
   info, err := os.Stat(path)
   if err != nil {
      if os.IsNotExist(err) {
         return nil
      }
      return err
   }
   if info.Size() < maxLogBytes {
      return nil
   }
   oldest := fmt.Sprintf("%s.%d", path, maxLogBackups)
   if err := os.Remove(oldest); err != nil && !os.IsNotExist(err) {
      return err
   }
   for i := maxLogBackups - 1; i >= 1; i-- {
      from := fmt.Sprintf("%s.%d", path, i)
      to := fmt.Sprintf("%s.%d", path, i+1)
      if err := os.Rename(from, to); err != nil && !os.IsNotExist(err) {
         return err
      }
   }
   return os.Rename(path, path+".1")
}
func write(level, format string, args ...interface{}) {
   msg := fmt.Sprintf(format, args...)
   ts := time.Now().Format("2006-01-02 15:04:05")