143 lines
3.2 KiB
Go
143 lines
3.2 KiB
Go
// Package logging 提供统一的日志功能
|
|
package logging
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"time"
|
|
)
|
|
|
|
// ==================== 日志级别 ====================
|
|
|
|
// Level 日志级别
|
|
type Level string
|
|
|
|
const (
|
|
LevelDebug Level = "DEBUG"
|
|
LevelInfo Level = "INFO"
|
|
LevelWarn Level = "WARN"
|
|
LevelError Level = "ERROR"
|
|
)
|
|
|
|
// ==================== 初始化 ====================
|
|
|
|
// Init 初始化日志系统
|
|
func Init(dir string) error {
|
|
if dir == "" {
|
|
dir = "log"
|
|
}
|
|
if err := os.MkdirAll(dir, 0755); err != nil {
|
|
return err
|
|
}
|
|
name := fmt.Sprintf("server-%s.log", time.Now().Format("20060102"))
|
|
p := filepath.Join(dir, name)
|
|
f, err := os.OpenFile(p, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
mw := io.MultiWriter(os.Stdout, f)
|
|
log.SetOutput(mw)
|
|
log.SetFlags(0)
|
|
return nil
|
|
}
|
|
|
|
// ==================== 结构化日志 ====================
|
|
|
|
// JSON 输出JSON格式日志
|
|
func JSON(level string, fields map[string]interface{}) {
|
|
m := map[string]interface{}{"level": level, "ts": time.Now().Format(time.RFC3339)}
|
|
for k, v := range fields {
|
|
m[k] = v
|
|
}
|
|
b, _ := json.Marshal(m)
|
|
log.Println(string(b))
|
|
}
|
|
|
|
// ==================== 便捷方法 ====================
|
|
|
|
// Debug 输出Debug级别日志
|
|
func Debug(event string, fields map[string]interface{}) {
|
|
if fields == nil {
|
|
fields = make(map[string]interface{})
|
|
}
|
|
fields["event"] = event
|
|
JSON(string(LevelDebug), fields)
|
|
}
|
|
|
|
// Info 输出Info级别日志
|
|
func Info(event string, fields map[string]interface{}) {
|
|
if fields == nil {
|
|
fields = make(map[string]interface{})
|
|
}
|
|
fields["event"] = event
|
|
JSON(string(LevelInfo), fields)
|
|
}
|
|
|
|
// Warn 输出Warn级别日志
|
|
func Warn(event string, fields map[string]interface{}) {
|
|
if fields == nil {
|
|
fields = make(map[string]interface{})
|
|
}
|
|
fields["event"] = event
|
|
JSON(string(LevelWarn), fields)
|
|
}
|
|
|
|
// Error 输出Error级别日志
|
|
func Error(event string, err error, fields map[string]interface{}) {
|
|
if fields == nil {
|
|
fields = make(map[string]interface{})
|
|
}
|
|
fields["event"] = event
|
|
if err != nil {
|
|
fields["error"] = err.Error()
|
|
}
|
|
// 添加调用位置信息
|
|
_, file, line, ok := runtime.Caller(1)
|
|
if ok {
|
|
fields["caller"] = fmt.Sprintf("%s:%d", filepath.Base(file), line)
|
|
}
|
|
JSON(string(LevelError), fields)
|
|
}
|
|
|
|
// ==================== 专用日志 ====================
|
|
|
|
// DBError 数据库错误日志
|
|
func DBError(action string, jobID uint64, err error) {
|
|
Error("db_error", err, map[string]interface{}{
|
|
"action": action,
|
|
"job_id": jobID,
|
|
})
|
|
}
|
|
|
|
// ExportProgress 导出进度日志
|
|
func ExportProgress(jobID uint64, totalRows int64) {
|
|
Info("progress_update", map[string]interface{}{
|
|
"job_id": jobID,
|
|
"total_rows": totalRows,
|
|
})
|
|
}
|
|
|
|
// ExportSQL 导出SQL日志
|
|
func ExportSQL(jobID uint64, datasource, mainTable, sql string, args []interface{}) {
|
|
Info("export_sql", map[string]interface{}{
|
|
"job_id": jobID,
|
|
"datasource": datasource,
|
|
"main_table": mainTable,
|
|
"sql": sql,
|
|
"args": args,
|
|
})
|
|
}
|
|
|
|
// FieldsRemoved 字段移除日志
|
|
func FieldsRemoved(event string, removed []string, reason string) {
|
|
Info(event, map[string]interface{}{
|
|
"removed": removed,
|
|
"reason": reason,
|
|
})
|
|
}
|