feat: 合并Gin_Vue
This commit is contained in:
49
src/framework/logger/logger.go
Normal file
49
src/framework/logger/logger.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
var logWriter *Logger
|
||||
|
||||
// 初始程序日志
|
||||
func InitLogger() {
|
||||
env := viper.GetString("env")
|
||||
conf := viper.GetStringMap("logger")
|
||||
fileDir := conf["filedir"].(string)
|
||||
fileName := conf["filename"].(string)
|
||||
level := conf["level"].(int)
|
||||
maxDay := conf["maxday"].(int)
|
||||
maxSize := conf["maxsize"].(int)
|
||||
|
||||
newLog, err := NewLogger(env, fileDir, fileName, level, maxDay, maxSize)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to initialize logger: %v", err)
|
||||
}
|
||||
|
||||
logWriter = newLog
|
||||
}
|
||||
|
||||
// 关闭程序日志写入
|
||||
func Close() {
|
||||
logWriter.Close()
|
||||
}
|
||||
|
||||
func Infof(format string, v ...any) {
|
||||
logWriter.Infof(format, v...)
|
||||
}
|
||||
|
||||
func Warnf(format string, v ...any) {
|
||||
logWriter.Warnf(format, v...)
|
||||
}
|
||||
|
||||
func Errorf(format string, v ...any) {
|
||||
logWriter.Errorf(format, v...)
|
||||
}
|
||||
|
||||
// Fatalf 抛出错误并退出程序
|
||||
func Fatalf(format string, v ...any) {
|
||||
log.Fatalf(format, v...)
|
||||
}
|
||||
190
src/framework/logger/writer.go
Normal file
190
src/framework/logger/writer.go
Normal file
@@ -0,0 +1,190 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 日志器对象
|
||||
type Logger struct {
|
||||
env string // 运行环境
|
||||
filePath string // 文件路径
|
||||
fileName string // 文件名
|
||||
level int // 日志等级标识
|
||||
maxDay int // 保留最长天数
|
||||
maxSize int64 // 文件最大空间
|
||||
fileHandle *os.File // 文件实例
|
||||
logger *log.Logger // 日志实例
|
||||
logLevelMap map[int]string // 日志等级标识名
|
||||
logDay int // 日志当前日
|
||||
}
|
||||
|
||||
const (
|
||||
LOG_LEVEL_SILENT = iota
|
||||
LOG_LEVEL_INFO
|
||||
LOG_LEVEL_WARN
|
||||
LOG_LEVEL_ERROR
|
||||
)
|
||||
|
||||
// NewLogger 实例日志器对象
|
||||
func NewLogger(env, fileDir, fileName string, level, maxDay, maxSize int) (*Logger, error) {
|
||||
logFilePath := filepath.Join(fileDir, fileName)
|
||||
if err := os.MkdirAll(filepath.Dir(logFilePath), 0750); err != nil {
|
||||
return nil, fmt.Errorf("failed to mkdir logger dir: %v", err)
|
||||
}
|
||||
fileHandle, err := os.OpenFile(logFilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open log file: %v", err)
|
||||
}
|
||||
|
||||
writer := io.Writer(fileHandle)
|
||||
if env == "local" {
|
||||
writer = io.MultiWriter(fileHandle, os.Stderr)
|
||||
}
|
||||
|
||||
logger := log.New(writer, "", log.LstdFlags|log.Lshortfile)
|
||||
|
||||
logLevelMap := map[int]string{
|
||||
LOG_LEVEL_INFO: "INFO",
|
||||
LOG_LEVEL_WARN: "WARN",
|
||||
LOG_LEVEL_ERROR: "ERROR",
|
||||
}
|
||||
|
||||
stdLogger := &Logger{
|
||||
env: env,
|
||||
filePath: fileDir,
|
||||
fileName: fileName,
|
||||
level: level,
|
||||
maxDay: maxDay,
|
||||
maxSize: int64(maxSize * 1024 * 1024),
|
||||
fileHandle: fileHandle,
|
||||
logger: logger,
|
||||
logLevelMap: logLevelMap,
|
||||
logDay: time.Now().Day(),
|
||||
}
|
||||
|
||||
go stdLogger.checkFile()
|
||||
|
||||
return stdLogger, nil
|
||||
}
|
||||
|
||||
// checkFile 检查文件分割,自定时调用
|
||||
func (l *Logger) checkFile() {
|
||||
fileInfo, err := l.fileHandle.Stat()
|
||||
if err != nil {
|
||||
l.logger.Printf("Failed to get log file info: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
currTime := time.Now()
|
||||
if l.logDay != currTime.Day() {
|
||||
l.logDay = currTime.Day()
|
||||
l.rotateFile(currTime.AddDate(0, 0, -1).Format("2006_01_02"))
|
||||
// 移除超过保存最长天数的文件
|
||||
l.removeOldFile(currTime.AddDate(0, 0, -l.maxDay))
|
||||
} else if fileInfo.Size() >= l.maxSize {
|
||||
l.rotateFile(currTime.Format("2006_01_02_150405"))
|
||||
} else if time.Since(fileInfo.ModTime()).Hours() > 24 {
|
||||
l.rotateFile(fileInfo.ModTime().Format("2006_01_02"))
|
||||
}
|
||||
|
||||
time.AfterFunc(1*time.Minute, l.checkFile)
|
||||
}
|
||||
|
||||
// rotateFile 检查文件大小进行分割
|
||||
func (l *Logger) rotateFile(timeFormat string) {
|
||||
l.fileHandle.Close()
|
||||
|
||||
newFileName := fmt.Sprintf("%s.%s", l.fileName, timeFormat)
|
||||
newFilePath := filepath.Join(l.filePath, newFileName)
|
||||
oldfilePath := filepath.Join(l.filePath, l.fileName)
|
||||
|
||||
// 重命名
|
||||
os.Rename(oldfilePath, newFilePath)
|
||||
|
||||
// 新文件句柄
|
||||
fileHandle, err := os.OpenFile(oldfilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
||||
if err != nil {
|
||||
l.logger.Printf("Failed to open log file: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
l.fileHandle = fileHandle
|
||||
|
||||
// 重新设置 logger 的 writer
|
||||
writer := io.Writer(l.fileHandle)
|
||||
if l.env == "local" {
|
||||
writer = io.MultiWriter(l.fileHandle, os.Stderr)
|
||||
}
|
||||
l.logger.SetOutput(writer)
|
||||
}
|
||||
|
||||
// RemoveOldFile 删除旧文件
|
||||
func (l *Logger) removeOldFile(oldFileDate time.Time) {
|
||||
// 遍历目标文件夹中的文件
|
||||
files, err := os.ReadDir(l.filePath)
|
||||
if err != nil {
|
||||
l.Errorf("logger RemoveOldFile ReadDir err: %v", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
idx := strings.LastIndex(file.Name(), ".log.")
|
||||
if idx == -1 {
|
||||
continue
|
||||
}
|
||||
dateStr := file.Name()[idx+5 : idx+15]
|
||||
|
||||
// 解析日期字符串
|
||||
fileDate, err := time.Parse("2006_01_02", dateStr)
|
||||
if err != nil {
|
||||
l.Errorf("logger RemoveOldFile Parse err: %v", err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
// 判断文件日期是否在给定日期之前
|
||||
if fileDate.Before(oldFileDate) {
|
||||
// 删除旧文件
|
||||
err := os.Remove(filepath.Join(l.filePath, file.Name()))
|
||||
if err != nil {
|
||||
l.Errorf("logger RemoveOldFile Remove err: %v", err.Error())
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// writeLog 写入chan
|
||||
func (l *Logger) writeLog(level int, format string, args ...interface{}) {
|
||||
if level < l.level {
|
||||
return
|
||||
}
|
||||
|
||||
logMsg := fmt.Sprintf("[%s] %s\n", l.logLevelMap[level], fmt.Sprintf(format, args...))
|
||||
l.logger.Output(4, logMsg)
|
||||
}
|
||||
|
||||
func (l *Logger) Infof(format string, args ...interface{}) {
|
||||
l.writeLog(LOG_LEVEL_INFO, format, args...)
|
||||
}
|
||||
|
||||
func (l *Logger) Warnf(format string, args ...interface{}) {
|
||||
l.writeLog(LOG_LEVEL_WARN, format, args...)
|
||||
}
|
||||
|
||||
func (l *Logger) Errorf(format string, args ...interface{}) {
|
||||
l.writeLog(LOG_LEVEL_ERROR, format, args...)
|
||||
}
|
||||
|
||||
// Close 日志关闭
|
||||
func (l *Logger) Close() {
|
||||
err := l.fileHandle.Close()
|
||||
if err != nil {
|
||||
l.logger.Printf("Failed to close log file: %v\n", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user