VideoConcat/wails/services/log.go
2026-01-10 19:00:52 +08:00

189 lines
4.2 KiB
Go

package services
import (
"fmt"
"log"
"os"
"path/filepath"
"runtime"
"strings"
"time"
)
var (
logDir string
isDevMode bool
logLevel string = "INFO" // DEBUG, INFO, WARN, ERROR
)
func init() {
// 检测是否为开发模式
// 通过环境变量 DEV 或可执行文件名判断
isDevMode = os.Getenv("DEV") == "true" ||
strings.Contains(os.Args[0], "dev") ||
strings.Contains(os.Args[0], ".dev")
// 开发模式下默认使用 DEBUG 级别
if isDevMode {
logLevel = "DEBUG"
log.SetFlags(log.LstdFlags | log.Lmicroseconds | log.Lshortfile)
} else {
log.SetFlags(log.LstdFlags)
}
// 设置日志目录
exePath, err := os.Executable()
if err != nil {
logDir = "./Log"
} else {
logDir = filepath.Join(filepath.Dir(exePath), "Log")
}
os.MkdirAll(logDir, 0755)
}
// SetLogLevel 设置日志级别
func SetLogLevel(level string) {
logLevel = strings.ToUpper(level)
}
// IsDevMode 返回是否为开发模式
func IsDevMode() bool {
return isDevMode
}
// shouldLog 判断是否应该记录该级别的日志
func shouldLog(level string) bool {
levels := map[string]int{
"DEBUG": 0,
"INFO": 1,
"WARN": 2,
"ERROR": 3,
}
currentLevel, ok := levels[logLevel]
if !ok {
currentLevel = 1
}
msgLevel, ok := levels[strings.ToUpper(level)]
if !ok {
msgLevel = 1
}
return msgLevel >= currentLevel
}
// getCallerInfo 获取调用者信息(仅在开发模式下)
func getCallerInfo() string {
if !isDevMode {
return ""
}
pc, file, line, ok := runtime.Caller(3)
if ok {
funcName := runtime.FuncForPC(pc).Name()
// 只取函数名,去掉包路径
parts := strings.Split(funcName, ".")
funcName = parts[len(parts)-1]
// 只取文件名
fileParts := strings.Split(file, "/")
fileName := fileParts[len(fileParts)-1]
return fmt.Sprintf("[%s:%d %s]", fileName, line, funcName)
}
return ""
}
// LogInfo 记录信息日志
func LogInfo(message string) {
if !shouldLog("INFO") {
return
}
callerInfo := getCallerInfo()
logMessage("INFO", callerInfo+" "+message)
}
// LogError 记录错误日志
func LogError(message string) {
if !shouldLog("ERROR") {
return
}
callerInfo := getCallerInfo()
logMessage("ERROR", callerInfo+" "+message)
}
// LogWarn 记录警告日志
func LogWarn(message string) {
if !shouldLog("WARN") {
return
}
callerInfo := getCallerInfo()
logMessage("WARN", callerInfo+" "+message)
}
// LogDebug 记录调试日志
func LogDebug(message string) {
if !shouldLog("DEBUG") {
return
}
callerInfo := getCallerInfo()
logMessage("DEBUG", callerInfo+" "+message)
}
// LogDebugf 格式化调试日志
func LogDebugf(format string, args ...interface{}) {
if !shouldLog("DEBUG") {
return
}
callerInfo := getCallerInfo()
message := fmt.Sprintf(format, args...)
logMessage("DEBUG", callerInfo+" "+message)
}
// LogInfof 格式化信息日志
func LogInfof(format string, args ...interface{}) {
if !shouldLog("INFO") {
return
}
callerInfo := getCallerInfo()
message := fmt.Sprintf(format, args...)
logMessage("INFO", callerInfo+" "+message)
}
// LogErrorf 格式化错误日志
func LogErrorf(format string, args ...interface{}) {
if !shouldLog("ERROR") {
return
}
callerInfo := getCallerInfo()
message := fmt.Sprintf(format, args...)
logMessage("ERROR", callerInfo+" "+message)
}
// LogWarnf 格式化警告日志
func LogWarnf(format string, args ...interface{}) {
if !shouldLog("WARN") {
return
}
callerInfo := getCallerInfo()
message := fmt.Sprintf(format, args...)
logMessage("WARN", callerInfo+" "+message)
}
// logMessage 写入日志消息
func logMessage(level, message string) {
timestamp := time.Now().Format("2006-01-02 15:04:05.000")
// 控制台输出(仅在开发模式下显示,避免发布版本弹窗)
if isDevMode {
log.Printf("[%s] %s %s", timestamp, level, message)
}
// 发布模式下不输出到控制台,只写入文件
// 文件输出(开发模式和发布模式都写入)
logFile := filepath.Join(logDir, fmt.Sprintf("log%s.log", time.Now().Format("20060102")))
file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
return
}
defer file.Close()
fileTimestamp := time.Now().Format("15:04:05.000")
file.WriteString(fmt.Sprintf("%s [%s] %s\n", fileTimestamp, level, message))
}