使用带有 Jaegar 后端的 OTEL 工具将日志添加到 span

Add logs to spans using OTEL instrumentation with Jaegar backend

目前,开放遥测 (OTEL) 跨度没有添加日志的机制,如 Jaegar 等实现中所见。

那么是否有将应用程序日志添加到跨度的解决方法?

正如我们所见here,jaegar 后端解释 OTEL 异常的方式是将异常内容作为日志放入相关跨度中。

现在,异常是事件的一种形式,jaegar 后端似乎将 OTEL 事件解释为日志。所以我们可以通过以下方式复制此行为:

  1. 创建自定义日志附加器
  2. 在里面,创建一个 OTEL 事件并在其中填充日志记录详细信息。
  3. 将事件添加到当前范围。

这个跨度将由 jaegar 后端解释,所有事件都作为单独的日志项放入该跨度中。

自定义日志附加程序

下面是我基于 spring-cloud 项目的 SpanLogsAppender.java 编写的基本 LogAppender。

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.IThrowableProxy;
import ch.qos.logback.classic.spi.ThrowableProxy;
import ch.qos.logback.core.AppenderBase;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.StatusCode;


public class SpanLogsAppender extends AppenderBase<ILoggingEvent> {

    /**
     * This is called only for configured levels.
     * It will not be executed for DEBUG level if root logger is INFO.
     */
    @Override
    protected void append(ILoggingEvent event) {
        final Span currentSpan = Span.current();
        AttributesBuilder builder = Attributes.builder();

        if (currentSpan != null) {
            builder.put("logger", event.getLoggerName())
                    .put("level", event.getLevel().toString())
                    .put("message", event.getFormattedMessage());

            currentSpan.addEvent("LogEvent", builder.build());

            if (Level.ERROR.equals(event.getLevel())) {
                currentSpan.setStatus(StatusCode.ERROR);
            }

            IThrowableProxy throwableProxy = event.getThrowableProxy();
            if (throwableProxy instanceof ThrowableProxy) {
                Throwable throwable = ((ThrowableProxy)throwableProxy).getThrowable();
                if (throwable != null) {
                    currentSpan.recordException(throwable);
                }
            }
        }
    }
}

我的本地版本:

  • spring 开机:2.5.1
  • io.opentelemetry.opentelemetry-api : 1.2.0
  • jaegar 后端:1.18 (windows)