github.com/lingyao2333/mo-zero@v1.4.1/rest/internal/log.go (about) 1 package internal 2 3 import ( 4 "bytes" 5 "fmt" 6 "net/http" 7 "sync" 8 9 "github.com/lingyao2333/mo-zero/core/logx" 10 "github.com/lingyao2333/mo-zero/rest/httpx" 11 ) 12 13 // LogContext is a context key. 14 var LogContext = contextKey("request_logs") 15 16 // A LogCollector is used to collect logs. 17 type LogCollector struct { 18 Messages []string 19 lock sync.Mutex 20 } 21 22 // Append appends msg into log context. 23 func (lc *LogCollector) Append(msg string) { 24 lc.lock.Lock() 25 lc.Messages = append(lc.Messages, msg) 26 lc.lock.Unlock() 27 } 28 29 // Flush flushes collected logs. 30 func (lc *LogCollector) Flush() string { 31 var buffer bytes.Buffer 32 33 start := true 34 for _, message := range lc.takeAll() { 35 if start { 36 start = false 37 } else { 38 buffer.WriteByte('\n') 39 } 40 buffer.WriteString(message) 41 } 42 43 return buffer.String() 44 } 45 46 func (lc *LogCollector) takeAll() []string { 47 lc.lock.Lock() 48 messages := lc.Messages 49 lc.Messages = nil 50 lc.lock.Unlock() 51 52 return messages 53 } 54 55 // Error logs the given v along with r in error log. 56 func Error(r *http.Request, v ...interface{}) { 57 logx.WithContext(r.Context()).Error(format(r, v...)) 58 } 59 60 // Errorf logs the given v with format along with r in error log. 61 func Errorf(r *http.Request, format string, v ...interface{}) { 62 logx.WithContext(r.Context()).Error(formatf(r, format, v...)) 63 } 64 65 // Info logs the given v along with r in access log. 66 func Info(r *http.Request, v ...interface{}) { 67 appendLog(r, format(r, v...)) 68 } 69 70 // Infof logs the given v with format along with r in access log. 71 func Infof(r *http.Request, format string, v ...interface{}) { 72 appendLog(r, formatf(r, format, v...)) 73 } 74 75 func appendLog(r *http.Request, message string) { 76 logs := r.Context().Value(LogContext) 77 if logs != nil { 78 logs.(*LogCollector).Append(message) 79 } 80 } 81 82 func format(r *http.Request, v ...interface{}) string { 83 return formatWithReq(r, fmt.Sprint(v...)) 84 } 85 86 func formatf(r *http.Request, format string, v ...interface{}) string { 87 return formatWithReq(r, fmt.Sprintf(format, v...)) 88 } 89 90 func formatWithReq(r *http.Request, v string) string { 91 return fmt.Sprintf("(%s - %s) %s", r.RequestURI, httpx.GetRemoteAddr(r), v) 92 } 93 94 type contextKey string 95 96 func (c contextKey) String() string { 97 return "rest/internal context key " + string(c) 98 }