Kubernetesのログを見るといえば、Datadog Log Mangementが楽なのですがログメッセージがレベルで扱われないことが度々あります。
そんなときによくやる「ログメッセージからレベルになるフィールドを取り出してLog Statusとして認識させる」ことを見てみましょう。


概要
- Custom Pipelineを使って、ログメッセージを構造化とLog Statusの変更すればok
- ログメッセージが
key=valueで構造化されているとさくさく構築できるので神
問題
Kubernetesに限らず、Log Managementでログを取り込んだ時に意図と違ったログレベルとして認識されることがあります。
たとえばKubernetesでexternal-dnsを使っているとき、実行するものがないときはAll records are already up to dateというメッセージ出力されるのですが、Datadog Log ManagementではStatusがErrorとなっています。
level=info msg="All records are already up to date"
しかしこのログは、Messageにlevel=infoとある通りエラーログではありません。
これをInfoとして扱いたいのでさくっと対処しましょう。
ログを見てみる
まずはログがどう認識されているのか見てみましょう。

対象のログを見てみると、Log StatusがErrorとなっていることがわかります。

また、ログも構造化されていません。

対処法針
external-dnsのログは、level keyでログレベルを表現しています。
こういったログへの追加対応は、Log ManagementのPipelineに追加のカスタムパイプラインを追加できます。
パイプラインには様々な処理(Processor)を設定できます。
今回はデフォルトのパイプラインで設定されたログレベルを書き換えたいので、Log Status Remapperを用いることでログに含まれるlevelキーの値をLog Statusとして認識させることができます。
Use this Processor if you want to assign some attributes as the official status. For example, it can transform this log:


対応方針は次の通りです。
- 新規パイプランを作る
- ログメッセージがただの文字列として扱われているのでJSONとして認識されるように構造化
- 構造化したデータから対象の
levelkeyを拾ってLog Statusを書き換える
パイプライン対応
Custom Pipelineを追加して、2つProcessorを追加していきます。
Custom Pipeline の追加
Datadog AgentのPipelineの後ろに新規Pipelineを追加します。
パイプラインを作成するときに、対象となるログを絞り込みます。
今回はAll records are already up to dateとなっているログを絞りたいので、Sourceとメッセージで指定してみましょう。
source:external-dns message:"*All records are already up to date"
Processor の追加: Grok Parserで構造化する
パイプラインができたら、具体的な処理単位であるProcessorを追加します。 まずは、ただの文字列になっているログを構造化 (JSON) 変換するため、Grok Parserを用います。
変換方法を考えるため、対象にしたいログメッセージを見てみましょう。
time="2020-01-07T09:49:07Z" level=info msg="All records are already up to date"
今回のログは「key=valueがスペースで羅列されている構造」とわかります。
こういった、文字列がkey{何かの文字}valueで構成されている場合、%{data::keyvalue}を使うだけでサクッと構造化できます。
external_dns_rule %{data::keyvalue}
これでいい感じのJSONに変換されてました。
{ "time": "2020-01-07T09:49:07Z", "level": "info", "msg": "All records are already up to date" }

Processor の追加: Log Status Remapperでログステータスとする
構造化したデータからステータスをとります。
もう一度Processorを追加して、今度はLog Status Remapperを使ってログステータスの差し替えを行います。
levelキーの値を使うので、対象キーにlevelを指定します。

これでおしまいます。
Pipelineの結果を確認
Log Explorerでログの結果を見てみると、いい感じにStatusが変わったことと確認できます。

先ほどなにもデータがなかったATTRIBUTESにも、変換した構造化データがのっていることがわかります。
このパターンはちょくちょく使うので、さくっとできると捗るでしょう。