Files
u-desk/internal/common/filelog.go
T
lxy 75a42c0b6a 修复: 粘贴图失效与SFTP串台回退等一批问题
粘贴图根修(Ctrl+V直读系统剪贴板,不再依赖不可靠的paste事件)/SFTP串台双刀(拨号期禁回退本机+盘符路径自动回根)/PDF导出目录设置与文案带落盘路径/性能批(连接保存下载防重/md渲染防抖+预热/hljs按需加载/审计锁外置/快捷方式解析超时/webview-watch可停)/前端62类型错清零(含keyPath蛇形字段炸弹)/目录图标字段错位修复
2026-10-24 13:48:54 +08:00

90 lines
2.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package common
import (
"fmt"
"io"
"log/slog"
"os"
"path/filepath"
"sync"
"time"
)
// GetLogsDir 日志目录:~/.u-desk/logs(audit 日志同目录)
func GetLogsDir() string {
return filepath.Join(GetUserDataDir(), "logs")
}
// dailyFile 按天滚动的追加写文件:每次写时发现日期变化即切换新文件。
// 只做按天滚动,不搞大小上限/压缩/清理,崩溃取证够用。
type dailyFile struct {
mu sync.Mutex
dir string
naming func(t time.Time) string
f *os.File
day string
}
func newDailyFile(dir string, naming func(time.Time) string) *dailyFile {
return &dailyFile{dir: dir, naming: naming}
}
func (w *dailyFile) Write(p []byte) (int, error) {
w.mu.Lock()
defer w.mu.Unlock()
now := time.Now()
day := now.Format("2006-01-02")
if w.f != nil && day != w.day {
w.f.Close()
w.f = nil
}
if w.f == nil {
if err := os.MkdirAll(w.dir, 0755); err != nil {
return 0, err
}
f, err := os.OpenFile(filepath.Join(w.dir, w.naming(now)), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
return 0, err
}
w.f, w.day = f, day
}
return w.f.Write(p)
}
func (w *dailyFile) Close() error {
w.mu.Lock()
defer w.mu.Unlock()
if w.f == nil {
return nil
}
err := w.f.Close()
w.f = nil
return err
}
// FileLogOut 应用文件日志的底层写出器(stderr + 按天文件 MultiWriter)。
// SetupFileLogging 之后有效;供需要独立过滤级别的 logger 复用同一落盘目的地
// (如 wails 系统日志降到 Warn,业务 slog.Default() 保持 INFO 全量)。
var FileLogOut io.Writer = os.Stderr
// SetupFileLogging slog 双路落盘:stderr + ~/.u-desk/logs/app-YYYY-MM-DD.log。
// windowsgui 下 stderr 被丢弃,文件路是日志唯一可见载体;
// 文件侧打不开时静默降级为仅 stderr,不因日志失败阻断启动。
func SetupFileLogging() {
out := io.Writer(os.Stderr)
w := newDailyFile(GetLogsDir(), func(t time.Time) string {
return fmt.Sprintf("app-%s.log", t.Format("2006-01-02"))
})
// 预开当天文件探测文件侧可用性(Write 内部含懒开/换天逻辑)
if _, err := w.Write(nil); err == nil {
// 文件必须放 MultiWriter 首位:windowsgui 下 stderr 句柄无效,
// MultiWriter 按序短路,stderr 在前会吞掉后续文件路(真机零日志的根因)
out = io.MultiWriter(w, os.Stderr)
} else {
w.Close()
}
FileLogOut = out
slog.SetDefault(slog.New(slog.NewTextHandler(out, nil)))
}