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  }