web-dev-qa-db-ja.com

Spring Bootのアプリケーションログ(slf4jによって生成された)でJaegerオープントレースデータを強化する方法

SLF4Jロガーを使用している既存のSpring Bootアプリがあります。 Jaegerをトレーサーとして使用して、標準のopentracing APIによる分散トレースのサポートを追加することにしました。初期設定がいかに簡単かは驚くべきことです。必要なのは、2つの依存関係を_pom.xml_に追加するだけです。

_    <dependency>
        <groupId>io.opentracing.contrib</groupId>
        <artifactId>opentracing-spring-web-autoconfigure</artifactId>
        <version>${io.opentracing.version}</version>
    </dependency>

    <dependency>
        <groupId>io.jaegertracing</groupId>
        <artifactId>jaeger-core</artifactId>
        <version>${jaegerVersion}</version>
    </dependency>
_

Tracer Beanに構成を提供します。

_@Bean
public io.opentracing.Tracer getTracer() throws ConfigurationException {
    return new new io.jaegertracing.Tracer.Builder("my-spring-boot-app").build();
}
_

すべては魅力のように機能します-アプリのリクエストはJaegerによって処理され、スパンが作成されます。

enter image description here

ただし、スパンLogsには、リクエストの実行中に呼び出されたクラス/メソッドに関する情報を含むpreHandleおよびafterCompletionイベントのみがあります(_slf4j_ロガーによって生成されたログは収集されません)。

enter image description here

問題は、すべてのアプリケーションログが_slf4j_/_LOG.info_を介して実行されるように、アプリロガーによって生成されたログ(私の場合は_LOG.warn_)をピックアップするようにトレーサーを構成できるかどうかです。/_LOG.error_などもJaegerに反映されます

[〜#〜]ノート[〜#〜]:スパンにログを記録する方法を理解しました手動でopentracing APIを使用して、例:

_Scope scope = tracer.scopeManager().active();
if (scope != null) {
    scope.span().log("...");
}
_

そして、フィルタでの例外処理のために、ERRORタグでmanual操作を実行します。

_} catch(Exception ex) {
    Tags.ERROR.set(span, true);
    span.log(Map.of(Fields.EVENT, "error", Fields.ERROR_OBJECT, ex, Fields.MESSAGE, ex.getMessage()));
    throw ex
}
_

しかし、アプリケーションログautomaticallyをピックアップするようにトレーサーを構成できるかどうか、私はまだ疑問に思っています。

  • _LOG.info_->トレーサは新しいログをアクティブなスパンに追加します
  • _LOG.error_->トレーサはアクティブスパンに新しいログを追加し、ERRORタグを追加します

[〜#〜] update [〜#〜]:ロガーのラッパーを追加することで、アプリケーションログをトレーサーに追加できました。

_public void error(String message, Exception e) {
    Scope scope = tracer.scopeManager().active();
    if (scope != null) {
        Span span = scope.span();
        Tags.ERROR.set(span, true);
        span.log(Map.of(Fields.EVENT, "error", Fields.ERROR_OBJECT, e, Fields.MESSAGE, e.getMessage()));

    }
    LOG.error(message, e);
}
_

ただし、これまでのところ、デフォルトでアプリケーションログを自動的にトレーサーに追加できるオープントレーシング構成オプションを見つけることができませんでした。基本的に、必要に応じてdevがプログラムによってトレーサに追加のログを追加することが予想されるようです。また、トレースをさらに調査した後、通常loggingtracingは別々に処理され、すべてのアプリケーションログをトレーサーに追加することはお勧めできません(トレーサーは主にリクエストの識別のためにサンプルデータとタグを含める必要があります)

7
Ilya Buziuk

https://github.com/opentracing-contrib/Java-spring-cloud プロジェクトは、標準のログをアクティブなスパンに自動的に送信します。次の依存関係をpom.xmlに追加するだけです

<dependency>
   <groupId>io.opentracing.contrib</groupId>
   <artifactId>opentracing-spring-cloud-starter</artifactId>
</dependency>

または、ロギングの統合のみが必要な場合は、これを使用します https://github.com/opentracing-contrib/Java-spring-cloud/tree/master/instrument-starters/opentracing-spring-cloud-core starter 。

5
Pavol Loffay

以下は、Logback(Slf4j)からjdbc関連のログをJaegerサーバーに書き込むために行ったものです。

Logback config(logback-spring.xml)から:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<springProperty scope="context" name="consoleAppender" source="logging.console.enabled" defaultValue="false"/>
<property name="ENV" value="${SPRING_PROFILES_ACTIVE:-dev}"/>

<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>

<jmxConfigurator/>

<appender name="JSON_CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="net.logstash.logback.encoder.LogstashEncoder">
        <includeMdc>true</includeMdc>
        <customFields>{"log_type":"application","appname":"products-rs-load", "environment": "${ENV}"}
        </customFields>
    </encoder>
</appender>
<appender name="myAppender" class="com.test.MyAppender">
</appender>
<root level="DEBUG">
    <appender-ref ref="myAppender"/>
</root>
<logger name="org.springframework.boot" level="INFO"/>
<logger name="p6spy" additivity="false" level="ALL">
    <appender-ref ref="myAppender" />
</logger>
</configuration>

これが私のアペンダーです:

import ch.qos.logback.core.AppenderBase;
public class MyAppender extends AppenderBase {

@Override
protected void append(Object eventObject) {
    LoggingEvent event = (LoggingEvent) eventObject;

    final String loggerName = event.getLoggerName();

    // only DB related operations have to be traced:
    if (!("p6spy".equals(loggerName))) {
        return;
    }
    /// Tracer config is straight forward
    Span sp = TracingUtils.buildActiveChildSpan(loggerName, null);

    if (Level.ERROR.equals(event.getLevel())) {
        TracingUtils.setErrorTag(sp);
    }
    Map<String, String> fields = new HashMap<String, String>();
    fields.put("level", event.getLevel().toString());
    fields.put("logger", loggerName);
    fields.put("content", event.getFormattedMessage());
    sp.log(fields);

    sp.finish();
  }
}
0
sharden

それからopentracing-spring-jaeger-cloud-starterを使用します

<dependency>
    <groupId>io.opentracing.contrib</groupId>
    <artifactId>opentracing-spring-jaeger-cloud-starter</artifactId>
    <version>2.0.0</version>
</dependency>

現在のトレースとスパンでコンソールに1行だけが表示されました。

2019-05-20 16:07:59.549 DEBUG 24428 --- [ctor-http-nio-2] o.s.w.s.adapter.HttpWebHandlerAdapter    : [632103eb] HTTP POST "/api"
2019-05-20 16:07:59.552 DEBUG 24428 --- [ctor-http-nio-2] s.w.r.r.m.a.RequestMappingHandlerMapping : [632103eb] Mapped to public reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<model.Response>> service.controller.method(model.Request)
2019-05-20 16:07:59.559 DEBUG 24428 --- [ctor-http-nio-2] .s.w.r.r.m.a.RequestBodyArgumentResolver : [632103eb] Content-Type:application/json
2019-05-20 16:08:01.450  INFO 24428 --- [ctor-http-nio-2] i.j.internal.reporters.LoggingReporter   : Span reported: f1a264bbe2c7eae9:f1a264bbe2c7eae9:0:1 - method
2019-05-20 16:08:01.450 DEBUG 24428 --- [ctor-http-nio-2] o.s.w.s.adapter.HttpWebHandlerAdapter    : [632103eb] Completed 200 OK

次にspring-cloud-starter-sleuthを使用します

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>

各行に[my-service、90e1114e35c897d6,90e1114e35c897d6、false]のようなトレースとスパンがあり、ELKのファイルビートに役立ちます

2019-05-20 16:15:38.646 DEBUG [my-service,,,] 12548 --- [ctor-http-nio-2] o.s.w.s.adapter.HttpWebHandlerAdapter    : [3e578505] HTTP POST "/api"
2019-05-20 16:15:38.662 DEBUG [my-service,,,] 12548 --- [ctor-http-nio-2] o.s.c.s.instrument.web.TraceWebFilter    : Received a request to uri [/api]
2019-05-20 16:15:38.667 DEBUG [my-service,,,] 12548 --- [ctor-http-nio-2] o.s.c.s.instrument.web.TraceWebFilter    : Handled receive of span NoopSpan(90e1114e35c897d6/90e1114e35c897d6)
2019-05-20 16:15:38.713 DEBUG [my-service,90e1114e35c897d6,90e1114e35c897d6,false] 12548 --- [ctor-http-nio-2] s.w.r.r.m.a.RequestMappingHandlerMapping : [3e578505] Mapped to public reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<model.Response>> service.controller.method(model.Request)
2019-05-20 16:15:38.727 DEBUG [my-service,90e1114e35c897d6,90e1114e35c897d6,false] 12548 --- [ctor-http-nio-2] .s.w.r.r.m.a.RequestBodyArgumentResolver : [3e578505] Content-Type:application/json
2019-05-20 16:15:39.956 DEBUG [my-service,90e1114e35c897d6,90e1114e35c897d6,false] 12548 --- [gine-1-thread-1] .s.w.r.r.m.a.ResponseEntityResultHandler : Using 'application/json;charset=UTF-8' given [*/*] and supported [application/json;charset=UTF-8, application/*+json;charset=UTF-8, text/event-stream]
2019-05-20 16:15:40.009 DEBUG [my-service,90e1114e35c897d6,90e1114e35c897d6,false] 12548 --- [ctor-http-nio-2] o.s.c.s.instrument.web.TraceWebFilter    : Adding a method tag with value [method] to a span NoopSpan(90e1114e35c897d6/90e1114e35c897d6)
2019-05-20 16:15:40.009 DEBUG [my-service,90e1114e35c897d6,90e1114e35c897d6,false] 12548 --- [ctor-http-nio-2] o.s.c.s.instrument.web.TraceWebFilter    : Adding a class tag with value [Controller] to a span NoopSpan(90e1114e35c897d6/90e1114e35c897d6)
2019-05-20 16:15:40.010 DEBUG [my-service,90e1114e35c897d6,90e1114e35c897d6,false] 12548 --- [ctor-http-nio-2] o.s.c.s.instrument.web.TraceWebFilter    : Handled send of NoopSpan(90e1114e35c897d6/90e1114e35c897d6)
2019-05-20 16:15:40.021 DEBUG [my-service,90e1114e35c897d6,90e1114e35c897d6,false] 12548 --- [ctor-http-nio-2] o.s.w.s.adapter.HttpWebHandlerAdapter    : [3e578505] Completed 200 OK

Opentracing-spring-jaeger-cloud-starterを使用してコンソールで同じログを取得するにはどうすればよいですか?

私のオープントレーシング設定

opentracing:
  jaeger:
    enabled: true
    enable-b3-propagation: true
    log-spans: true
    const-sampler:
      decision: true
    http-sender:
      url: http://jaeger-collector:14268/api/traces

0
Petr Sheshenya