kitex-contrib / obs-opentelemetry

An extension library of OpenTelemetry for Kitex
Apache License 2.0
24 stars 21 forks source link

日志关联trace 后,在控制台有输出,但是在 jaeger 上没有 log #50

Closed li1553770945 closed 1 week ago

li1553770945 commented 2 weeks ago

按照 Hertz 的用法,只要把 log 和 trace 关联,不仅会在控制台显示 log 对应的 traceid 和 spanid,在 jaeger 上也能看到。 QQ_1730723801877 QQ_1730723828309

但是在 kitex 中,在 jaeger上不显示,不知道是不是我的用法不对。 QQ_1730723897861 QQ_1730723859155

CoderPoet commented 2 weeks ago

这俩关联不是一个概念哈

jaeger这边的 log 其实就是 span 的 event 属性

log 关联 trace 是在 log 的 kv 里注入 trace id、span id 这些

li1553770945 commented 2 weeks ago

好的明白了。能否多问一句,如果我希望在 jaeger 上看到 log,是不是应该在原来 logger 的基础上封装,实现向对应的 span 里面注入 log event?

CoderPoet commented 1 week ago

好的明白了。能否多问一句,如果我希望在 jaeger 上看到 log,是不是应该在原来 logger 的基础上封装,实现向对应的 span 里面注入 log event?

你可以自定义 span 的时候在 event 里写你希望在 jaeger 上看到的日志哈~

li1553770945 commented 1 week ago

好的,感谢回答,我再去看一下

li1553770945 commented 1 week ago

简单写了一个版本

import (
    "context"
    "fmt"
    "github.com/cloudwego/kitex/pkg/klog"
    kitexlogrus "github.com/kitex-contrib/obs-opentelemetry/logging/logrus"
    "go.opentelemetry.io/otel/attribute"
    "go.opentelemetry.io/otel/trace"
    "io"
    "os"
    "path/filepath"
    "runtime"
    "time"
)

type TraceLogger struct {
    *kitexlogrus.Logger
}

func NewTraceLogger() *TraceLogger {
    return &TraceLogger{
        Logger: kitexlogrus.NewLogger(),
    }
}

func getCallerInfo(skip int) string {
    _, file, line, ok := runtime.Caller(skip)
    if !ok {
        return ""
    }
    return fmt.Sprintf("%s:%d", file, line)
}

func (l *TraceLogger) logWithTrace(ctx context.Context, level, msg string) {
    caller := getCallerInfo(4)
    span := trace.SpanFromContext(ctx)
    if span.IsRecording() {
        span.AddEvent("log", trace.WithAttributes(
            attribute.String("level", level),
            attribute.String("message", msg),
            attribute.String("caller", caller),
        ))
    }
}

func (l *TraceLogger) CtxDebugf(ctx context.Context, format string, v ...interface{}) {
    l.logWithTrace(ctx, "DEBUG", fmt.Sprintf(format, v...))
    l.Logger.CtxDebugf(ctx, format, v...)
}

func (l *TraceLogger) CtxInfof(ctx context.Context, format string, v ...interface{}) {
    l.logWithTrace(ctx, "INFO", fmt.Sprintf(format, v...))
    l.Logger.CtxInfof(ctx, format, v...)
}

func (l *TraceLogger) CtxNoticef(ctx context.Context, format string, v ...interface{}) {
    l.logWithTrace(ctx, "NOTICE", fmt.Sprintf(format, v...))
    l.Logger.CtxNoticef(ctx, format, v...)
}

func (l *TraceLogger) CtxWarnf(ctx context.Context, format string, v ...interface{}) {
    l.logWithTrace(ctx, "WARN", fmt.Sprintf(format, v...))
    l.Logger.CtxWarnf(ctx, format, v...)
}

func (l *TraceLogger) CtxErrorf(ctx context.Context, format string, v ...interface{}) {
    l.logWithTrace(ctx, "ERROR", fmt.Sprintf(format, v...))
    l.Logger.CtxErrorf(ctx, format, v...)
}

func (l *TraceLogger) CtxFatalf(ctx context.Context, format string, v ...interface{}) {
    l.logWithTrace(ctx, "FATAL", fmt.Sprintf(format, v...))
    l.Logger.CtxFatalf(ctx, format, v...)
}