ログを Datadog に送信するには、ファイルにログを記録し、そのファイルを Datadog Agent で tail します。
一般的な Java ログのスタックトレースは複数の行に分割されているため、元のログイベントに関連付けることが困難です。例:
//1 つのはずのイベントに、4 つのイベントが生成される Exception in thread "main" java . lang . NullPointerException at com . example . myproject . Book . getTitle ( Book . java : 16 ) at com . example . myproject . Author . getBookTitles ( Author . java : 25 ) at com . example . myproject . Bootstrap . main ( Bootstrap . java : 14 ) この問題を解決するには、ログを JSON 形式で生成するようにログライブラリを構成します。JSON にログすると、次のことができます。
スタックトレースがログイベントに適切にラップされることを確実にします。 すべてのログイベント属性 (重大度、ロガー名、スレッド名など) が適切に抽出されることを確実にします。 マップされた診断コンテキスト (MDC) 属性にアクセスできます。この属性は、任意のログイベントにアタッチできます。カスタムパースルール が不要になります。次の手順は、Log4j、Log4j 2、および Logback ログライブラリのセットアップ例を示しています。
ロガーの構成 JSON 形式 Log4j の場合、SLF4J モジュール log4j-over-slf4j を Logback と組み合わせて使用して JSON 形式でログします。log4j-over-slf4j は、アプリケーションの Log4j を完全に置き換えるため、コードを変更する必要はありません。
pom.xml ファイルで、log4j.jar 依存関係を log4j-over-slf4j.jar 依存関係に置き換え、Logback 依存関係を追加します。例:
<dependency> <groupId> org.slf4j</groupId> <artifactId> log4j-over-slf4j</artifactId> <version> 1.7.32</version> </dependency> <dependency> <groupId> ch.qos.logback</groupId> <artifactId> logback-classic</artifactId> <version> 1.2.9</version> </dependency> <dependency> <groupId> net.logstash.logback</groupId> <artifactId> logstash-logback-encoder</artifactId> <version> 6.6</version> </dependency> logback.xml で JSON レイアウトを使用するアペンダーを構成してください。ファイルとコンソール向けのサンプル構成は以下を参照してください。
ファイル:
<configuration> <appender name= "FILE" class= "ch.qos.logback.core.FileAppender" > <file> logs/app.log</file> <encoder class= "net.logstash.logback.encoder.LogstashEncoder" /> </appender> <root level= "INFO" > <appender-ref ref= "FILE" /> </root> </configuration> コンソール:
<configuration> <appender name= "CONSOLE" class= "ch.qos.logback.core.ConsoleAppender" > <encoder class= "ch.qos.logback.classic.encoder.JsonEncoder" /> </appender> <root> <level value= "DEBUG" /> <appender-ref ref= "CONSOLE" /> </root> </configuration> Log4j 2 には JSON レイアウトが含まれています。
log4j2.xml で JSON レイアウトを使用するアペンダーを構成してください。ファイルおよびコンソールアペンダー向けのサンプル構成は以下を参照してください。Log4j プラグインのより詳細な説明については、Log4j Plugin リファレンス をご覧ください。Copy
<?xml version="1.0" encoding="UTF-8"?> <Configuration> <Appenders> <File name= "FILE" fileName= "logs/app.log" > <JsonTemplateLayout eventTemplateUri= "classpath:MyLayout.json" /> </File> </Appenders> <Loggers> <Root level= "INFO" > <AppenderRef ref= "FILE" /> </Root> </Loggers> </Configuration> Copy
<?xml version="1.0" encoding="UTF-8"?> <Configuration> <Appenders> <Console name= "console" target= "SYSTEM_OUT" > <JsonTemplateLayout eventTemplateUri= "classpath:MyLayout.json" /> </Console> </Appenders> <Loggers> <Root level= "INFO" > <AppenderRef ref= "console" /> </Root> </Loggers> </Configuration> JSON レイアウトの依存関係を pom.xml に追加します。例:<dependency> <groupId> org.apache.logging.log4j</groupId> <artifactId> log4j-core</artifactId> <version> 2.17.1</version> </dependency> <dependency> <groupId> com.fasterxml.jackson.core</groupId> <artifactId> jackson-core</artifactId> <version> 2.13.0</version> </dependency> <dependency> <groupId> com.fasterxml.jackson.core</groupId> <artifactId> jackson-databind</artifactId> <version> 2.13.0</version> </dependency> <dependency> <groupId> com.fasterxml.jackson.core</groupId> <artifactId> jackson-annotations</artifactId> <version> 2.13.0</version> </dependency> Logback の JSON 形式のログには、logstash-logback-encoder を使用します。
logback.xml の JSON レイアウトを使用してファイルアペンダーを構成します。例:
<configuration> <appender name= "FILE" class= "ch.qos.logback.core.FileAppender" > <file> logs/app.log</file> <encoder class= "net.logstash.logback.encoder.LogstashEncoder" /> </appender> <root level= "INFO" > <appender-ref ref= "FILE" /> </root> </configuration> Logstash エンコーダの依存関係を pom.xml ファイルに追加します。例:
<dependency> <groupId> ch.qos.logback</groupId> <artifactId> logback-classic</artifactId> <version> 1.2.9</version> </dependency> <dependency> <groupId> net.logstash.logback</groupId> <artifactId> logstash-logback-encoder</artifactId> <version> 6.6</version> </dependency> Tinylog 公式ドキュメント に基づいて、JSON ライターの構成を作成します。
tinylog.properties ファイルでは次の形式を使用してください。
writer = json writer.file = log.json writer.format = LDJSON writer.level = info writer.field.level = level writer.field.source = {class}.{method}() writer.field.message = {message} writer.field.dd.trace_id = {context: dd.trace_id} writer.field.dd.span_id = {context: dd.span_id} writer.field.dd.service = {context: dd.service} writer.field.dd.version = {context: dd.version} writer.field.dd.env = {context: dd.env} ログへのトレース ID の挿入 このアプリケーションで APM が有効になっている場合は、トレース ID インジェクションを有効にすることで、ログとトレースを相互に関連付けることができます。詳細については、Java ログとトレースの接続 を参照してください。
未加工の形式 log4j.xml でファイルアペンダーを構成します。例:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration> <appender name= "FILE" class= "org.apache.log4j.FileAppender" > <param name= "File" value= "logs/app.log" /> <param name= "Append" value= "true" /> <layout class= "org.apache.log4j.PatternLayout" > <param name= "ConversionPattern" value= "%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %X{dd.trace_id} %X{dd.span_id} - %m%n" /> </layout> </appender> <root> <priority value= "INFO" /> <appender-ref ref= "FILE" /> </root> </log4j:configuration> log4j2.xml でファイルアペンダーを構成します。例:
<?xml version="1.0" encoding="UTF-8"?> <Configuration> <Appenders> <File name= "FILE" fileName= "logs/app.log" > <PatternLayout pattern= "%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %X{dd.trace_id} %X{dd.span_id} - %m%n" /> </File> </Appenders> <Loggers> <Root level= "INFO" > <AppenderRef ref= "FILE" /> </Root> </Loggers> </Configuration> logback.xml でファイルアペンダーを構成します。例:
<configuration> <appender name= "FILE" class= "ch.qos.logback.core.FileAppender" > <file> ${dd.test.logfile}</file> <append> false</append> <immediateFlush> true</immediateFlush> <encoder> <pattern> %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %X{dd.trace_id} %X{dd.span_id} - %m%n</pattern> </encoder> </appender> <root level= "INFO" > <appender-ref ref= "FILE" /> </root> </configuration> 公式 Tinylog ドキュメント に基づき、ファイルへ出力するためのライター構成を作成してください。
tinylog.properties ファイルでは以下の形式を使用してください。
writer = file writer.level = debug writer.format = {level} - {message} - "dd.trace_id":{context: dd.trace_id} - "dd.span_id":{context: dd.span_id} writer.file = log.txt ログへのトレース ID の挿入 このアプリケーションで APM が有効になっている場合は、トレース ID インジェクションを有効にすることで、ログとトレースを相互に関連付けることができます。Java ログとトレースの接続 を参照してください。
ログとトレースを相関させていない場合は、上記の構成例に含まれているログパターンから MDC プレースホルダー (%X{dd.trace_id} %X{dd.span_id}) を削除できます。
Datadog Agent の構成 ログ収集が有効 になったら、ログファイルを追跡して Datadog に送信するカスタムログ収集 を設定します。
java.d/ フォルダーを conf.d/ Agent 構成ディレクトリ に作成します。
java.d/ に以下の内容で conf.yaml ファイルを作成します。
#Log section logs : - type : file path : "<path_to_your_java_log>.log" service : <service_name> source : java sourcecategory : sourcecode # For multiline logs, if they start by the date with the format yyyy-mm-dd uncomment the following processing rule #log_processing_rules: # - type: multi_line # name: new_log_start_with_date # pattern: \d{4}\-(0?[1-9]|1[012])\-(0?[1-9]|[12][0-9]|3[01]) Agent を再起動します 。
Agent の status サブコマンド を実行し、Checks セクションで java を探し、ログが Datadog に正常に送信されることを確認します。
ログが JSON 形式の場合、Datadog は自動的にログメッセージをパース し、ログ属性を抽出します。ログエクスプローラー を使用して、ログを表示し、トラブルシューティングを行うことができます。
エージェントレスのログ収集 アクセスできない、またはファイルにログを記録できないマシンでアプリケーションが実行されている例外的なケースでは、ログを Datadog または Datadog Agent に直接ストリーミングすることができます。アプリケーションが接続の問題を処理する必要があるため、これは推奨される設定ではありません。
ログを Datadog に直接ストリーミングするには
Logback ログライブラリをコードに追加するか、現在のロガーを Logback にブリッジ します。 Logback を構成 して Datadog にログを送信します。Java ロギングライブラリから Logback へのブリッジ まだ Logback を使用していない場合、ほとんどの一般的なログライブラリは Logback にブリッジすることができます。
SLF4J モジュール log4j-over-slf4j を Logback とともに使用して、ログを別のサーバーに送信します。log4j-over-slf4j は、アプリケーションの Log4j を完全に置き換えるため、コードを変更する必要はありません。
pom.xml ファイルで、log4j.jar 依存関係を log4j-over-slf4j.jar 依存関係に置き換え、Logback 依存関係を追加します。例:<dependency> <groupId> org.slf4j</groupId> <artifactId> log4j-over-slf4j</artifactId> <version> 1.7.32</version> </dependency> <dependency> <groupId> ch.qos.logback</groupId> <artifactId> logback-classic</artifactId> <version> 1.2.9</version> </dependency> <dependency> <groupId> net.logstash.logback</groupId> <artifactId> logstash-logback-encoder</artifactId> <version> 6.6</version> </dependency> Logback を構成します。 注: この変更の結果、Log4j コンフィギュレーションファイルは使用されなくなります。Log4j トランスレーター を使用して log4j.properties ファイルを logback.xml に移行してください。
Log4j 2 では、リモートホストへのログ記録が可能ですが、ログの前に API キーを付ける機能はありません。このため、SLF4J モジュール log4j-over-slf4j と Logback を使用してください。log4j-to-slf4j.jar は、アプリケーションの Log4j 2 を完全に置き換えるため、コードを変更する必要はありません。これを使用するには
pom.xml ファイルで、log4j.jar 依存関係を log4j-over-slf4j.jar 依存関係に置き換え、Logback 依存関係を追加します。例:<dependency> <groupId> org.apache.logging.log4j</groupId> <artifactId> log4j-to-slf4j</artifactId> <version> 2.17.1</version> </dependency> <dependency> <groupId> ch.qos.logback</groupId> <artifactId> logback-classic</artifactId> <version> 1.2.9</version> </dependency> <dependency> <groupId> net.logstash.logback</groupId> <artifactId> logstash-logback-encoder</artifactId> <version> 6.6</version> </dependency> Logback を構成します。 注:
Logback を構成する
logstash-logback-encoder ログライブラリを Logback と一緒に使用して、ログを Datadog に直接ストリーミングします。
logback.xml ファイルに TCP アペンダーを構成します。この構成では、API キーは環境変数 DD_API_KEY から取得されます。あるいは、コンフィギュレーションファイルに直接 API キーを挿入することもできます。
以下の構成を使用する際は、<YOUR REGION INTAKE> をご利用の地域に応じたインテーク () に置き換えてください。
US1 : intake.logs.datadoghq.com:10516EU : tcp-intake.logs.datadoghq.eu:443<configuration> <appender name= "FILE" class= "ch.qos.logback.core.FileAppender" > <file> logs/app.log</file> <encoder class= "net.logstash.logback.encoder.LogstashEncoder" /> </appender> <appender name= "JSON_TCP" class= "net.logstash.logback.appender.LogstashTcpSocketAppender" > <destination><YOUR REGION INTAKE ></destination> <keepAliveDuration> 20 seconds</keepAliveDuration> <encoder class= "net.logstash.logback.encoder.LogstashEncoder" > <prefix class= "ch.qos.logback.core.encoder.LayoutWrappingEncoder" > <layout class= "ch.qos.logback.classic.PatternLayout" > <pattern> ${DD_API_KEY} %mdc{keyThatDoesNotExist}</pattern> </layout> </prefix> </encoder> <ssl /> </appender> <root level= "DEBUG" > <appender-ref ref= "FILE" /> <appender-ref ref= "JSON_TCP" /> </root> </configuration> 注: XML コンフィギュレーションで空白が削除されるため、%mdc{keyThatDoesNotExist} が追加されます。プレフィックスパラメータの詳細については、Logback ドキュメント を参照してください。
Logstash エンコーダの依存関係を pom.xml ファイルに追加します。例:
<dependency> <groupId> ch.qos.logback</groupId> <artifactId> logback-classic</artifactId> <version> 1.2.9</version> </dependency> <dependency> <groupId> net.logstash.logback</groupId> <artifactId> logstash-logback-encoder</artifactId> <version> 6.6</version> </dependency> 補足説明 ログイベントをコンテキスト属性で補完することができます。
キー値パーサーの使用 キー値パーサー は、ログイベント内で認識された <KEY>=<VALUE> パターンを抽出します。
Java のログイベントを補完するには、コードでメッセージを書き直し、<キー>=<値> のシーケンスを挿入します。
たとえば、次のメッセージがあるとします。
logger . info ( "Emitted 1001 messages during the last 93 seconds for customer scope prod30" ); これを次のように変更します。
logger . info ( "Emitted quantity=1001 messages during the last durationInMs=93180 ms for customer scope=prod30" ); キー値パーサーを有効にすると、各ペアが JSON から抽出されます。
{ "message" : "Emitted quantity=1001 messages during the last durationInMs=93180 ms for customer scope=prod30" , "scope" : "prod30" , "durationInMs" : 93180 , "quantity" : 1001 } これで、scope をフィールド、durationInMs と quantity をログメジャーとして利用できます。
MDC ログを補完するもう 1 つの方法として、Java の マップされた診断コンテキスト (MDC) の利用があります。
SLF4J を使用する場合は、次の Java コードを使用してください。
... MDC . put ( "scope" , "prod30" ); logger . info ( "Emitted 1001 messages during the last 93 seconds" ); ... この JSON を生成するには
{ "message" : "過去 93 秒間に 1001 メッセージを送信" , "scope" : "prod30" } 注 : MDC は文字列タイプのみを許可するため、数値メトリクスには使用しないでください。
その他の参考資料