feat: 装配线看板修正、统一密钥Hardman_2026、操作日志追溯、日志按天存储
Dashboard 移除 CNC/清洗机等不存在设备,改为纯装配线看板(扫码枪+拧紧枪+人工);JWT/内部token统一为 Hardman_2026 写入各 etc/*.yaml,MES 建表 DSN 改读 yaml;event_log 增加 workOrderNo/operator,BOM/备料/PLC下发/拧紧/扫码报工/半成品/AGV 全链路埋点,日志页支持工单号/操作人筛选;MES/WMS 日志按天存储(dailyWriter),WMS SetWriter 用 logx.NewWriter 适配
This commit is contained in:
@@ -5,6 +5,7 @@ type LogConf struct {
|
||||
Format string `json:",default=text"` // 日志格式: text, json
|
||||
TimeFormat string `json:",default=2006-01-02 15:04:05"` // 时间格式
|
||||
Filename string `json:",default=spcm.log"` // 日志文件名
|
||||
Daily bool `json:",default=true"` // 按天存储: 文件名追加日期,跨天自动切换
|
||||
MaxSize int `json:",default=100"` // 单个日志文件最大大小(MB)
|
||||
MaxBackups int `json:",default=10"` // 保留的旧日志文件数量
|
||||
MaxAge int `json:",default=30"` // 日志文件保留天数
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"gopkg.in/natefinch/lumberjack.v2"
|
||||
)
|
||||
|
||||
// dailyWriter 按天滚动的日志写入器:
|
||||
// 文件名格式 base-2006-01-02.log,跨天自动切换新文件;
|
||||
// 单日内超 MaxSize 仍由 lumberjack 备份(base-2006-01-02-<ts>.log);
|
||||
// 超过 MaxAge 天的日志文件在跨天时清理。
|
||||
type dailyWriter struct {
|
||||
mu sync.Mutex
|
||||
conf LogConf
|
||||
date string
|
||||
lj *lumberjack.Logger
|
||||
}
|
||||
|
||||
func newDailyWriter(conf LogConf) *dailyWriter {
|
||||
return &dailyWriter{conf: conf}
|
||||
}
|
||||
|
||||
func (w *dailyWriter) filename(date string) string {
|
||||
ext := filepath.Ext(w.conf.Filename)
|
||||
base := strings.TrimSuffix(w.conf.Filename, ext)
|
||||
return base + "-" + date + ext
|
||||
}
|
||||
|
||||
func (w *dailyWriter) Write(p []byte) (int, error) {
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
|
||||
today := time.Now().Format("2006-01-02")
|
||||
if w.lj == nil || today != w.date {
|
||||
if w.lj != nil {
|
||||
_ = w.lj.Close()
|
||||
}
|
||||
w.date = today
|
||||
w.lj = &lumberjack.Logger{
|
||||
Filename: w.filename(today),
|
||||
MaxSize: w.conf.MaxSize,
|
||||
MaxBackups: w.conf.MaxBackups,
|
||||
MaxAge: w.conf.MaxAge,
|
||||
Compress: w.conf.Compress,
|
||||
}
|
||||
w.cleanup()
|
||||
}
|
||||
return w.lj.Write(p)
|
||||
}
|
||||
|
||||
func (w *dailyWriter) Close() error {
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
if w.lj != nil {
|
||||
return w.lj.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// cleanup 清理超过 MaxAge 天的按天日志文件
|
||||
func (w *dailyWriter) cleanup() {
|
||||
if w.conf.MaxAge <= 0 {
|
||||
return
|
||||
}
|
||||
dir := filepath.Dir(w.conf.Filename)
|
||||
ext := filepath.Ext(w.conf.Filename)
|
||||
base := strings.TrimSuffix(filepath.Base(w.conf.Filename), ext)
|
||||
entries, err := os.ReadDir(dir)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
cutoff := time.Now().AddDate(0, 0, -w.conf.MaxAge)
|
||||
for _, e := range entries {
|
||||
if e.IsDir() || !strings.HasPrefix(e.Name(), base+"-") || !strings.HasSuffix(e.Name(), ext) {
|
||||
continue
|
||||
}
|
||||
datePart := strings.TrimSuffix(strings.TrimPrefix(e.Name(), base+"-"), ext)
|
||||
t, err := time.ParseInLocation("2006-01-02", datePart, time.Local)
|
||||
if err != nil {
|
||||
continue // 非按天命名的历史备份,交给 lumberjack 策略
|
||||
}
|
||||
if t.Before(cutoff) {
|
||||
_ = os.Remove(filepath.Join(dir, e.Name()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
_ io.WriteCloser = (*dailyWriter)(nil)
|
||||
_ io.Writer = (*dailyWriter)(nil)
|
||||
)
|
||||
@@ -46,16 +46,21 @@ func NewLogger(conf LogConf) *Logger {
|
||||
conf.Filename = filepath.Join(workdir, conf.Filename)
|
||||
}
|
||||
|
||||
// 创建lumberjack日志滚动器
|
||||
lumberjackLogger := &lumberjack.Logger{
|
||||
Filename: conf.Filename,
|
||||
MaxSize: conf.MaxSize,
|
||||
MaxBackups: conf.MaxBackups,
|
||||
MaxAge: conf.MaxAge,
|
||||
Compress: conf.Compress,
|
||||
} // 创建写入器
|
||||
// 创建日志写入器:默认按天存储;Daily=false 时退回单文件按大小滚动
|
||||
var fileWriter io.Writer
|
||||
if conf.Daily {
|
||||
fileWriter = newDailyWriter(conf)
|
||||
} else {
|
||||
fileWriter = &lumberjack.Logger{
|
||||
Filename: conf.Filename,
|
||||
MaxSize: conf.MaxSize,
|
||||
MaxBackups: conf.MaxBackups,
|
||||
MaxAge: conf.MaxAge,
|
||||
Compress: conf.Compress,
|
||||
}
|
||||
}
|
||||
|
||||
var writer io.Writer = lumberjackLogger
|
||||
var writer io.Writer = fileWriter
|
||||
if conf.Console {
|
||||
writer = io.MultiWriter(writer, os.Stdout)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user