1 Star 0 Fork 0

aurora-engine / utils

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
logrus_multiformatter.go 5.93 KB
一键复制 编辑 原始数据 按行查看 历史
package logutils
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"gitee.com/aurora-engine/utils/osutils"
"github.com/sirupsen/logrus"
"golang.org/x/term"
"io"
"log"
"os"
"path/filepath"
"strings"
"sync"
"time"
)
const (
nameColor = "\033[36m"
infoColor = "\033[94m"
debugColor = "\033[95m"
warnColor = "\033[93m"
errColor = "\033[91m"
fatalColor = "\033[31m"
reset = "\033[0m"
Pkg = "logrusPkgPrint"
colorFmt = "[%s%s%s] [%s] [%s%-5s%s] : %s %s\n"
defaultFmt = "[%s] [%s] [%-5s] : %s %s\n"
)
type FD interface {
Fd() uintptr
}
// MultiFormatter logrus多格式输出工具
type MultiFormatter struct {
Name, LogName string
ColorFormatter, DefaultFormatter string
writers []io.Writer
buf *sync.Pool
}
// Format 自定义 log 格式
func (format *MultiFormatter) Format(entry *logrus.Entry) ([]byte, error) {
buf := format.buf.Get().(*bytes.Buffer)
defer format.buf.Put(buf)
defer buf.Reset()
t := entry.Time.Format("2006-01-02 15:04:05")
funcInfo := ""
if entry.Caller != nil {
funcInfo = fmt.Sprintf("%s:%d", entry.Caller.Function, entry.Caller.Line)
}
args := []any{format.Name, t, entry.Level, entry.Message, funcInfo}
colorArgs := []any{}
switch entry.Level {
case logrus.InfoLevel:
colorArgs = []any{nameColor, format.Name, reset, t, infoColor, entry.Level, reset, entry.Message, funcInfo}
case logrus.DebugLevel:
colorArgs = []any{nameColor, format.Name, reset, t, debugColor, entry.Level, reset, entry.Message, funcInfo}
case logrus.WarnLevel:
colorArgs = []any{nameColor, format.Name, reset, t, warnColor, entry.Level, reset, entry.Message, funcInfo}
case logrus.ErrorLevel:
colorArgs = []any{nameColor, format.Name, reset, t, errColor, entry.Level, reset, entry.Message, funcInfo}
case logrus.FatalLevel:
colorArgs = []any{nameColor, format.Name, reset, t, fatalColor, entry.Level, reset, entry.Message, funcInfo}
case logrus.PanicLevel:
colorArgs = []any{nameColor, format.Name, reset, t, fatalColor, entry.Level, reset, entry.Message, funcInfo}
}
formats := map[string]any{
format.DefaultFormatter: args,
format.ColorFormatter: colorArgs,
}
marshal, err := json.Marshal(formats)
if err != nil {
return nil, err
}
buf.Write(marshal)
return buf.Bytes(), nil
}
func (format *MultiFormatter) Write(p []byte) (n int, err error) {
var message []byte
for _, w := range format.writers {
if message, err = format.log(w, p); err != nil {
return
}
if n, err = w.Write(message); err != nil {
return
}
if n != len(message) {
err = io.ErrShortWrite
return
}
}
return len(message), nil
}
func (format *MultiFormatter) log(writer io.Writer, p []byte) ([]byte, error) {
var data map[string][]any
err := json.Unmarshal(p, &data)
if err != nil {
return nil, err
}
var message []any
var Fmt string
switch f := writer.(type) {
case *os.File:
if term.IsTerminal(int(f.Fd())) {
Fmt = colorFmt
} else {
Fmt = defaultFmt
}
case FD:
if term.IsTerminal(int(f.Fd())) {
Fmt = colorFmt
} else {
Fmt = defaultFmt
}
default:
return nil, errors.New("log fmt error")
}
if message = data[Fmt]; message == nil {
return nil, errors.New("not found fmt")
}
msg := fmt.Sprintf(Fmt, message...)
return []byte(msg), nil
}
func NewMultiFormatter(name string, writers ...io.Writer) *MultiFormatter {
return &MultiFormatter{
Name: name,
ColorFormatter: colorFmt,
DefaultFormatter: defaultFmt,
writers: writers,
buf: &sync.Pool{New: func() any {
return new(bytes.Buffer)
}}}
}
func NewOut(path, name string) *OutLog {
// 创建文件
var file *os.File
var StarTime string
var err error
StarTime, file, err = NowTimeFileLog(path, name, "")
if err != nil {
log.Fatalln("create log failed err:" + err.Error())
}
return &OutLog{
LogName: name,
Path: path,
StartTime: StarTime,
Size: 20,
File: file,
}
}
type OutLog struct {
Path string // 存储目录
LogName string // 日志名称
Size int64 // 分割大小
StartTime string // 开始写入日志的时间
*os.File // 当前日志输出文件
}
func (receiver *OutLog) Write(p []byte) (n int, err error) {
newTime, file, err := receiver.check()
if err != nil {
return 0, err
}
if newTime != "" && file != nil {
receiver.StartTime = newTime
receiver.File = file
}
return receiver.File.Write(p)
}
// 检查当前写入的文件大小是否需要生成新文件进行日志存储
func (receiver *OutLog) check() (newTime string, newFile *os.File, err error) {
fileInfo, err := receiver.Stat()
if err != nil {
return "", nil, err
}
if fileInfo.Size() > receiver.Size {
newTime, newFile, err = NowTimeFileLog(receiver.Path, receiver.LogName, receiver.StartTime)
}
return
}
// NowTimeFileLog 创建日志文件
// @param path 日志创建路径
// @param name 日志文件名
// @return star 生成日志文件的时间
// @return file 日志文件
// @return err 错误信息
func NowTimeFileLog(path, name, begin string) (star string, file *os.File, err error) {
// 创建文件
var exists bool
if path == "" {
return "", nil, errors.New("path is ''")
}
if exists, err = osutils.PathExists(path); err != nil {
return
}
if !exists {
err = os.MkdirAll(path, os.ModePerm)
if err != nil {
return
}
}
// 生成当前时间
format := time.Now().Format("2006-01-02T15-04-05")
if index := strings.LastIndex(name, ".log"); index != -1 {
name = name[:index] + begin + "-" + format + ".log"
} else {
name = name + begin + "-" + format + ".log"
}
name = name + ".log"
logPath := filepath.Join(path, name)
file, err = os.OpenFile(logPath, os.O_APPEND|os.O_CREATE, 0755)
if err != nil {
return "", nil, errors.New("create log failed:" + err.Error())
}
return
}
func (format *MultiFormatter) Levels() []logrus.Level {
return []logrus.Level{logrus.InfoLevel}
}
func (format *MultiFormatter) Fire(entry *logrus.Entry) error {
fmt.Println()
return nil
}
1
https://gitee.com/aurora-engine/utils.git
git@gitee.com:aurora-engine/utils.git
aurora-engine
utils
utils
v0.0.2

搜索帮助