Files
loggerx/loggerx.go
T

161 lines
3.1 KiB
Go
Raw Normal View History

2024-01-22 18:05:51 +08:00
package loggerx
// author:黄新云
2024-04-03 21:18:44 +08:00
// lastTime:2024年4月3日21:18:05
2024-01-22 18:05:51 +08:00
// desc: 日志封装类
import (
"bytes"
"context"
"fmt"
"io"
"log"
"os"
"runtime"
"sync"
// "sync_log/global"
"github.com/gin-gonic/gin"
)
// 需要实现io.Writer接口
type Logger struct {
2024-11-22 20:08:25 +08:00
ctx context.Context
filePath *sync.Map // filePath
mu *sync.Mutex
option loggerOption
channel string
writeType writeType // 是否异步落盘,这里作用范围是本条,优先判断这里
2024-01-23 00:12:08 +08:00
}
type filePath struct {
2024-01-22 18:05:51 +08:00
file *os.File
fileName string
}
2024-04-15 23:40:55 +08:00
func NewLogger(ctx context.Context, opts ...Option) *Logger {
2024-01-22 18:05:51 +08:00
opt := defaultOptions()
for _, apply := range opts {
apply(&opt)
}
2024-04-03 21:18:44 +08:00
// 验证文件夹权限
if !checkDir(opt.dir) {
panic("文件夹权限不足")
}
2024-01-23 00:12:08 +08:00
l := &Logger{
2024-11-22 20:08:25 +08:00
ctx: ctx,
filePath: &sync.Map{},
mu: &sync.Mutex{},
option: opt,
writeType: writeTypeDefault,
2024-01-22 18:05:51 +08:00
}
2024-01-23 00:12:08 +08:00
2024-01-22 18:05:51 +08:00
log.SetOutput(l)
log.SetFlags(log.LstdFlags | log.Llongfile | log.Lmicroseconds) // log.Lshortfile | log.LUTC
// 保存Gin日志写入到文件+控制台
2024-01-23 00:12:08 +08:00
if opt.isGinLog {
gin.DefaultWriter = io.MultiWriter(l, os.Stdout)
gin.DefaultErrorWriter = io.MultiWriter(l, os.Stdout)
2024-01-22 18:05:51 +08:00
}
2024-01-23 13:37:51 +08:00
// 日志删除
go l.delete()
2024-04-15 23:40:55 +08:00
// 强制刷盘
go func() {
<-ctx.Done()
l.MustSync()
}()
2024-01-22 18:05:51 +08:00
return l
}
2024-01-23 00:12:08 +08:00
// 强制刷盘
func (l *Logger) MustSync() {
l.filePath.Range(func(key, value any) bool {
f := value.(*filePath)
f.file.Sync()
return true
})
}
2024-01-22 18:05:51 +08:00
2024-01-23 00:12:08 +08:00
func (l *Logger) Channel(ch string) (r *Logger) {
rr := *l
rr.channel = ch
return &rr
}
2024-01-22 18:05:51 +08:00
2024-11-22 20:08:25 +08:00
func (l *Logger) WriteAsync() (r *Logger) {
rr := *l
rr.writeType = writeTypeAsync
return &rr
}
func (l *Logger) WriteSync() (r *Logger) {
rr := *l
rr.writeType = writeTypeSync
return &rr
}
2024-07-03 16:58:14 +08:00
// 获取TraceField的字段
func (l *Logger) GetTraceField() string {
return l.option.traceField
}
2024-01-23 00:12:08 +08:00
// 实现io.Writer接口
2024-01-22 18:05:51 +08:00
func (l *Logger) Write(b []byte) (n int, err error) {
2024-01-23 00:12:08 +08:00
return l.write("info", b)
2024-01-22 18:05:51 +08:00
}
func (l *Logger) Info(ctx context.Context, v ...any) {
l.logger(ctx, "info", v...)
}
func (l *Logger) Infof(ctx context.Context, format string, v ...any) {
s := fmt.Sprintf(format, v...)
l.logger(ctx, "info", s)
}
func (l *Logger) Error(ctx context.Context, v ...any) {
l.logger(ctx, "error", v...)
}
func (l *Logger) Errorf(ctx context.Context, format string, v ...any) {
s := fmt.Sprintf(format, v...)
l.logger(ctx, "error", s)
}
// 添加固定的内容
// func (l *Logger) ContextWithFields(ctx context.Context, v ...any) {
// l.logger(ctx, "add", v...)
// }
// func (l *Logger) Field(key,val string) {
// l.logger(nil, "add", key,val)
// }
func getGID() string {
b := make([]byte, 64)
b = b[:runtime.Stack(b, false)]
b = bytes.TrimPrefix(b, []byte("goroutine "))
b = b[:bytes.IndexByte(b, ' ')]
return string(b)
}
2024-04-03 21:18:44 +08:00
// 验证文件夹权限
// 根文件夹如果不存在则创建
func checkDir(dir string) bool {
if _, err := os.Stat(dir); err != nil {
if os.IsNotExist(err) {
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
log.Println("创建文件夹失败", err)
return false
}
}
}
return true
}