github.com/nyan233/littlerpc@v0.4.6-0.20230316182519-0c8d5c48abaf/plugins/logger/logger.go (about) 1 package logger 2 3 import ( 4 "context" 5 "fmt" 6 lContext "github.com/nyan233/littlerpc/core/common/context" 7 "github.com/nyan233/littlerpc/core/middle/plugin" 8 errorCode "github.com/nyan233/littlerpc/core/protocol/error" 9 perror "github.com/nyan233/littlerpc/core/protocol/error" 10 "github.com/nyan233/littlerpc/core/protocol/message" 11 "io" 12 "reflect" 13 "strings" 14 "time" 15 ) 16 17 type statusCode struct{} 18 19 type Logger struct { 20 plugin.AbstractServer 21 w io.Writer 22 } 23 24 func New(w io.Writer) plugin.ServerPlugin { 25 return &Logger{ 26 w: w, 27 } 28 } 29 30 func (l Logger) Call4S(pub *plugin.Context, args []reflect.Value, err perror.LErrorDesc) perror.LErrorDesc { 31 if err != nil { 32 return l.printLog(pub, nil, err, "Call") 33 } 34 return nil 35 } 36 37 func (l Logger) AfterCall4S(pub *plugin.Context, args, results []reflect.Value, err perror.LErrorDesc) perror.LErrorDesc { 38 if err != nil { 39 return l.printLog(pub, nil, err, "AfterCall") 40 } 41 if results == nil || len(results) == 0 { 42 return nil 43 } 44 var status int 45 r0 := results[len(results)-1].Interface() 46 if r0 == nil { 47 status = errorCode.Success 48 } else if rErr, ok := r0.(perror.LErrorDesc); ok { 49 status = rErr.Code() 50 } else { 51 status = errorCode.Unknown 52 } 53 pub.PluginContext = context.WithValue(pub.PluginContext, statusCode{}, status) 54 return nil 55 } 56 57 func (l Logger) Send4S(pub *plugin.Context, msg *message.Message, err perror.LErrorDesc) perror.LErrorDesc { 58 if err != nil { 59 return l.printLog(pub, msg, err, "Send") 60 } 61 return nil 62 } 63 64 func (l Logger) AfterSend4S(pub *plugin.Context, msg *message.Message, err perror.LErrorDesc) perror.LErrorDesc { 65 return l.printLog(pub, msg, err, "AfterSend") 66 } 67 68 func (l Logger) printLog(pub *plugin.Context, msg *message.Message, err perror.LErrorDesc, phase string) perror.LErrorDesc { 69 const ( 70 KB = 1024 71 MB = KB * 1024 72 GB = MB * 1024 73 ) 74 if phase == "" { 75 phase = "Unknown" 76 } 77 data := lContext.CheckInitData(pub.PluginContext) 78 if data == nil { 79 pub.Logger.Warn("logger error : init data not found") 80 return nil 81 } 82 var status int 83 if err == nil { 84 if ctxStatus, ok := pub.PluginContext.Value(statusCode{}).(int); !ok { 85 status = errorCode.Success 86 } else { 87 status = ctxStatus 88 } 89 } else { 90 status = err.Code() 91 } 92 live := time.Now() 93 interval := live.Sub(data.Start) 94 var msgSize uint32 95 if msg != nil { 96 msgSize = msg.GetAndSetLength() 97 } 98 var size string 99 switch { 100 case msgSize < 1024: 101 size = fmt.Sprintf("%.3fB", float64(msgSize)) 102 case msgSize/uint32(KB) < 1024: 103 size = fmt.Sprintf("%.3fKB", float64(msgSize)/KB) 104 case msgSize/uint32(MB) < 1024: 105 size = fmt.Sprintf("%.3fMB", float64(msgSize)/MB) 106 case msgSize/uint32(GB) < 1024: 107 size = fmt.Sprintf("%.3fGB", float64(msgSize)/GB) 108 } 109 var msgType string 110 switch data.MsgType { 111 case message.Call: 112 msgType = "Call" 113 case message.Ping: 114 msgType = "Keep-Alive" 115 case message.ContextCancel: 116 msgType = "Context-Cancel" 117 default: 118 msgType = "Unknown" 119 } 120 _, wErr := fmt.Fprintf(l.w, "[LRPC] | %-10s | %s | %7d | %10s | %10s | %12s | %15s | \"%s\"\n", 121 phase, 122 live.Format("2006/01/02 - 15:04:05"), 123 status, 124 interval, 125 size, 126 strings.Split(lContext.CheckRemoteAddr(pub.PluginContext).String(), ":")[0], 127 msgType, 128 data.ServiceName) 129 if wErr != nil { 130 pub.Logger.Warn("logger write data error : %v", wErr) 131 } 132 return nil 133 }