日记
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

241 lines
5.7 KiB

package log
import (
"context"
"encoding/json"
"fmt"
"git.gz.internal.jumaiyx.cn/pkg/config/v2/cproto"
klog "git.gz.internal.jumaiyx.cn/pkg/log/klog"
"git.gz.internal.jumaiyx.cn/pkg/log/request"
"git.gz.internal.jumaiyx.cn/pkg/log/tracing"
"github.com/go-kratos/kratos/v2/errors"
"github.com/go-kratos/kratos/v2/log"
"github.com/go-kratos/kratos/v2/middleware"
"github.com/go-kratos/kratos/v2/transport"
"time"
)
const (
LogKafkaKey = "log"
LogKafkaTopic = "log-information-record-topic"
LogKafkaGroup = "log-information-record-group"
ReqId = "reqId"
)
// Redacter defines how to log an object
type Redacter interface {
Redact() string
}
type logger struct {
log *klog.Helper
logger klog.Logger
ctx context.Context
}
type Logger interface {
Server() middleware.Middleware
SetCtx(ctx context.Context)
GetCtx() context.Context
WithContext(ctx context.Context)
Log(level klog.Level, keyvals ...interface{})
Debug(a ...interface{})
Debugf(format string, a ...interface{})
Debugw(keyvals ...interface{})
Info(a ...interface{})
Infof(format string, a ...interface{})
Infow(keyvals ...interface{})
Warn(a ...interface{})
Warnf(format string, a ...interface{})
Warnw(keyvals ...interface{})
Error(a ...interface{})
Errorf(format string, a ...interface{})
Errorw(keyvals ...interface{})
Fatal(a ...interface{})
Fatalf(format string, a ...interface{})
Fatalw(keyvals ...interface{})
}
// NewLogger new a logger with writer.
func NewLogger(c *cproto.Log, opts ...klog.Option) Logger {
if c == nil {
return DefaultLogger()
}
l := NewKLogger(c)
return &logger{
logger: l,
log: klog.NewHelper(l, opts...),
}
}
func DefaultLogger() Logger {
l := NewKLogger(&cproto.Log{
Level: LevelDebug,
Debug: true,
})
return &logger{
logger: l,
log: klog.NewHelper(l),
}
}
// Server 日志中间件
func (l *logger) Server() middleware.Middleware {
return func(handler middleware.Handler) middleware.Handler {
return func(ctx context.Context, req interface{}) (reply interface{}, err error) {
//fmt.Println("开始")
//var (
// reqId string
// spanId int
//)
// 获取传递的id
ctx, _ = request.GetReqId(ctx)
//fmt.Printf("===== server reqId:%s=====:\n", reqId)
ctx, _ = tracing.GetSpanId(ctx)
//fmt.Printf("===== server spanId:%d=====:\n", spanId)
var (
code int32
reason string
kind string
operation string
)
startTime := time.Now()
if info, ok := transport.FromServerContext(ctx); ok {
kind = info.Kind().String()
operation = info.Operation()
}
reply, err = handler(ctx, req)
if se := errors.FromError(err); se != nil {
code = se.Code
reason = se.Reason
}
_, stack := extractError(err)
l.Infof("component:%s operation:%s args:%s code:%d reason:%s stack:%s latency:%f", kind, operation, extractArgs(req), code, reason, stack, time.Since(startTime).Seconds())
// 打印参数
l.WithContext(ctx)
l.Request(req)
//fmt.Println("结束")
return
}
}
}
func (l *logger) Request(req interface{}) {
str, _ := json.Marshal(req)
l.log.Infof("request:%s", string(str))
}
func (l *logger) SetCtx(ctx context.Context) {
l.ctx = ctx
}
func (l *logger) GetCtx() context.Context {
return l.log.ReadContext()
}
// WithContext returns a shallow copy of h with its context changed
// to ctx. The provided ctx must be non-nil.
func (l *logger) WithContext(ctx context.Context) {
l.log = l.log.WithContext(ctx)
}
// Log Print log by level and keyvals.
func (l *logger) Log(level klog.Level, keyvals ...interface{}) {
l.log.Log(level, keyvals...)
}
// Debug logs a message at debug level.
func (l *logger) Debug(a ...interface{}) {
l.log.Debug(a...)
}
// Debugf logs a message at debug level.
func (l *logger) Debugf(format string, a ...interface{}) {
l.log.Debugf(format, a...)
}
// Debugw logs a message at debug level.
func (l *logger) Debugw(keyvals ...interface{}) {
l.log.Debugw(keyvals...)
}
// Info logs a message at info level.
func (l *logger) Info(a ...interface{}) {
l.log.Info(a...)
}
// Infof logs a message at info level.
func (l *logger) Infof(format string, a ...interface{}) {
l.log.Infof(format, a...)
}
// Infow logs a message at info level.
func (l *logger) Infow(keyvals ...interface{}) {
l.log.Infow(keyvals...)
}
// Warn logs a message at warn level.
func (l *logger) Warn(a ...interface{}) {
l.log.Warn(a...)
}
// Warnf logs a message at warnf level.
func (l *logger) Warnf(format string, a ...interface{}) {
l.log.Warnf(format, a...)
}
// Warnw logs a message at warnf level.
func (l *logger) Warnw(keyvals ...interface{}) {
l.log.Warnw(keyvals...)
}
// Error logs a message at error level.
func (l *logger) Error(a ...interface{}) {
l.log.Error(a...)
}
// Errorf logs a message at error level.
func (l *logger) Errorf(format string, a ...interface{}) {
l.log.Errorf(format, a...)
}
// Errorw logs a message at error level.
func (l *logger) Errorw(keyvals ...interface{}) {
l.log.Errorw(keyvals...)
}
// Fatal logs a message at fatal level.
func (l *logger) Fatal(a ...interface{}) {
l.log.Fatal(a...)
}
// Fatalf logs a message at fatal level.
func (l *logger) Fatalf(format string, a ...interface{}) {
l.log.Fatalf(format, a...)
}
// Fatalw logs a message at fatal level.
func (l *logger) Fatalw(keyvals ...interface{}) {
l.log.Fatalw(keyvals...)
}
// extractArgs returns the string of the req
func extractArgs(req interface{}) string {
if redacter, ok := req.(Redacter); ok {
return redacter.Redact()
}
if stringer, ok := req.(fmt.Stringer); ok {
return stringer.String()
}
return fmt.Sprintf("%+v", req)
}
// extractError returns the string of the error
func extractError(err error) (log.Level, string) {
if err != nil {
return log.LevelError, fmt.Sprintf("%+v", err)
}
return log.LevelInfo, ""
}