| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- /**
- @author: xuhanlin
- @date: 2022/6/28
- @note: 基础线性格式日志
- **/
- package log
- import (
- "bytes"
- "fmt"
- "github.com/sirupsen/logrus"
- "runtime"
- "strconv"
- "strings"
- )
- // GetGid 获取协程ID
- func GetGid() uint64 {
- b := make([]byte, 64)
- b = b[:runtime.Stack(b, false)]
- b = bytes.TrimPrefix(b, []byte("goroutine "))
- b = b[:bytes.IndexByte(b, ' ')]
- n, err := strconv.ParseUint(string(b), 10, 64)
- if err != nil {
- return 0
- }
- return n
- }
- type LineFormatter struct {
- Skip int
- }
- func (f *LineFormatter) Format(entry *logrus.Entry) ([]byte, error) {
- data := ""
- // 毫秒时间
- data += entry.Time.Format("2006-01-02 15:04:05.000")
- // 日志等级
- data += "|" + strings.ToUpper(entry.Level.String())
- // 调用信息
- data += "|" + findCaller(f.Skip)
- // 线程信息
- data += "|" + strconv.FormatUint(GetGid(), 10)
- // 日志内容
- data += "|" + entry.Message
- return append([]byte(data), '\n'), nil
- }
- func findCaller(skip int) string {
- file, line, pc := getCaller(skip)
- fullFnName := runtime.FuncForPC(pc)
- fnName := ""
- if fullFnName != nil {
- fnNameStr := fullFnName.Name()
- parts := strings.Split(fnNameStr, ".")
- fnName = parts[len(parts)-1]
- }
- tmp := strings.Split(file, "/")
- return fmt.Sprintf("%s:%s:%d", tmp[len(tmp)-1], fnName, line)
- }
- func getCaller(skip int) (string, int, uintptr) {
- pc, file, line, ok := runtime.Caller(skip)
- if !ok {
- return "", 0, pc
- }
- n := 0
- for i := len(file) - 1; i > 0; i-- {
- if file[i] == '/' {
- n++
- if n >= 2 {
- file = file[i+1:]
- break
- }
- }
- }
- return file, line, pc
- }
|