Last active
September 12, 2021 08:36
-
-
Save lwydyby/58700d6ea1082d25ecc46049633243c7 to your computer and use it in GitHub Desktop.
logrus hook concurrent map iteration and map write error
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bytes" | |
"context" | |
"fmt" | |
log "github.com/sirupsen/logrus" | |
"path/filepath" | |
"runtime" | |
"strconv" | |
"sync" | |
"time" | |
) | |
func main() { | |
log.SetFormatter(&LogFormatter{}) | |
go func() { | |
for { | |
func(){ | |
defer func() { | |
// 处理所有异常,防止panic导致程序关闭 | |
if p := recover(); p != nil { | |
} | |
}() | |
hook:=AddTraceIdHook("123") | |
defer RemoveTraceHook(hook) | |
log.Infof("test why ") | |
}() | |
} | |
}() | |
go func() { | |
for { | |
func(){ | |
defer func() { | |
// 处理所有异常,防止panic导致程序关闭 | |
if p := recover(); p != nil { | |
} | |
}() | |
hook:=AddTraceIdHook("1233") | |
defer RemoveTraceHook(hook) | |
log.Infof("test why 2") | |
}() | |
} | |
}() | |
c:=make(chan int) | |
<-c | |
} | |
var traceLock = &sync.Mutex{} | |
func AddTraceIdHook(traceId string) log.Hook { | |
defer traceLock.Unlock() | |
traceLock.Lock() | |
traceHook := newTraceIdHook(traceId) | |
if log.StandardLogger().Hooks == nil { | |
hooks := new(log.LevelHooks) | |
log.StandardLogger().ReplaceHooks(*hooks) | |
} | |
log.AddHook(traceHook) | |
return traceHook | |
} | |
func RemoveTraceHook(hook log.Hook) { | |
defer traceLock.Unlock() | |
traceLock.Lock() | |
allHooks := log.StandardLogger().Hooks | |
for key, hooks := range allHooks { | |
replaceHooks := hooks | |
for index, h := range hooks { | |
if h == hook { | |
replaceHooks = append(hooks[:index], hooks[index+1:]...) | |
break | |
} | |
} | |
allHooks[key] = replaceHooks | |
} | |
log.StandardLogger().ReplaceHooks(allHooks) | |
} | |
type TraceIdHook struct { | |
TraceId string | |
GID uint64 | |
} | |
func newTraceIdHook(traceId string) log.Hook { | |
return &TraceIdHook{ | |
TraceId: traceId, | |
GID: getGID(), | |
} | |
} | |
func (t TraceIdHook) Levels() []log.Level { | |
return log.AllLevels | |
} | |
func (t TraceIdHook) Fire(entry *log.Entry) error { | |
if getGID() == t.GID { | |
entry.Context = context.WithValue(context.Background(), "trace_id", t.TraceId) | |
} | |
return nil | |
} | |
type LogFormatter struct{} | |
//格式详情 | |
func (s *LogFormatter) Format(entry *log.Entry) ([]byte, error) { | |
timestamp := time.Now().Format("2006-01-02 15:04:05") | |
var file string | |
var line int | |
if entry.Caller != nil { | |
file = filepath.Base(entry.Caller.File) | |
line = entry.Caller.Line | |
} | |
level := entry.Level.String() | |
if entry.Context == nil || entry.Context.Value("trace_id") == "" { | |
uuid:= "NO UUID" | |
entry.Context = context.WithValue(context.Background(), "trace_id", uuid) | |
} | |
msg := fmt.Sprintf("%-15s [%-3d] [%-5s] [%s] %s:%d %s\n", timestamp, getGID(), level, entry.Context.Value("trace_id"), file, line, entry.Message) | |
return []byte(msg), nil | |
} | |
// 获取当前协程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, _ := strconv.ParseUint(string(b), 10, 64) | |
return n | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment