OpenTelemetry Collectorにログを集計させるためにfilelog receiverとcount connectorを使う
こんにちは、Splunk Observabilityの導入支援をしている @katzchang です。今日はOpenTelemetry Collectorを使って、ログファイルを集計して、メトリクスプラットフォームに送るということをやってみたいと思います。
ログはとても柔軟なデータフォーマットで、あらゆることが自由な形式で記録できます。しかしその反面、データ転送や保管、可視化のためのクエリ処理など各所の処理コストが高く、データ転送料金が跳ね上がったり、収集サーバーの計算機リソースを食いつぶしたり、SaaSのライセンスコストも多くかかります。使用用途が限られたログ、つまりどのようなクエリをするか予めわかっているログは、事前に集計してメトリクスとして扱うことで、上記の処理コストを抑えつつより素早い可視化が実現できます。
ログをメトリクスに変換する箇所はいくつかあります。たとえば、ログをフィルタして件数を数えるような処理をするとしたら:
- 集計クエリが発行された時点で、ログをフィルタして、件数を数える
- ログ分析プラットフォームにログが取り込まれた時点で、フィルタして、件数を数える
- ログ分析プラットフォームにログを送るエージェントが、フィルタして、件数を数える
- ログを出力するアプリケーションが、生ログではなく、メトリクスとしてレポートとする機能を備える
すごく大雑把に言うと、下にいくほどコスト効率が良くなり、上にいくほど柔軟性が高まります。
今回はこの中の3番目、「ログ分析プラットフォームにログを送るエージェントが、フィルタして、件数を数える」を、OpenTelemetry Collectorの機能を使って実現してみましょう。このやり方は、アプリケーションを変更することなく、また、ログ分析プラットフォームに依存しない形でメトリクスの集計ができるというのがメリットです。
OpenTelemetry Collectorってなんだったっけ?
OpenTelemetry Collectorは、テレメトリーデータの受信、処理、送信を担うエージェントで、様々な形式データを受け取り、加工し、任意のバックエンドに送信することができます。利用者はコンポーネント化された部品つかって、自由にテレメトリーデータのパイプラインを組み立てることができます。OpenTelemetryの公式サイトのRegisitoryを見ると、どのようなコンポーネントが使えるかがわかります。
設定はyamlファイルで行われます。シンプルな設定はたとえばこんな感じです:
receivers:
otlp:
protocols:
grpc:
exporters:
otlp:
endpoint: otelcol.observability.svc.cluster.local:443
service:
extensions: []
pipelines:
logs:
receivers: [otlp]
processors: []
exporters: [otlp]
otlpのgprcプロトコル版でテレメトリデータ(トレース、ログ、メトリクスなど)を受け取り、とくに処理はせず、ログ形式のものを otelcol.observability.svc.cluster.local
の443ポートにotlpプロトコルで送信するという風にパイプラインが設定されています。
これでとりあえず問題なく動くのですが、ここでログの件数を数えたいときに、どういうコンポーネントを使えばいいでしょうか?このような問題をシンプルに解決するために、最近「コネクター(connector)」という新しいコンポーネントのタイプが登場しました。
コネクターとは
OpenTelemetry Collectorのコネクターは、レシーバーとエクスポーターの2つの役割を持ち、あるパイプラインで受け取ったものを別のパイプラインに送るというものです。スパンを受け取ってメトリクスにしたり、一つのパイプラインに流れてきたデータをアトリビュートによって分岐させたり、いままでよりも柔軟にパイプラインを構成できるようになるものです。
ということで、今回はログの件数を数えるためにCount Connectorを使ってみましょう。
OpenTelemetry Collectorを設定する
今回はSplunk distroであるsplunk-otel-collectorから始めてみます。セットアップは基本的にシェルスクリプトを叩くだけでいい感じにインストールされ、204行のデフォルトの設定が入ります。これをベースに、次の変更をしていきます。
- filelog receiverの追加
- count connectorの追加
- filelog receiver -> count connector -> metricsバックエンドのパイプラインの追加
気の早いかたは最終的なdiffを見てみてください。
filelog receiverの追加
ログファイルを取り込むために、filelog receiverを使います。
receivers
の下に記述していきます.
filelog/hoge:
include: [ /var/log/hoge/*.log ]
operators:
- type: json_parser
timestamp:
parse_from: attributes.time
layout: '%Y-%m-%d %H:%M:%S'
-
filelog/hoge
というコンポーネントとして命名する(この名前はパイプラインの中で使われます) -
/var/log/hoge/*.log
のログファイルを対象とする - 行分割のjson形式でパースする
-
time
という属性をログ生成の時刻として扱う
という程度の定義がされています。ほかにも正規表現でパースさせるなどいくつかのオプションがあるので、詳しくはREADME.mdを眺めてみてください。
count connectorの追加
次に、count connectorを追加していきます。
これはトップレベル(っていう表現でいいんだっけ?)に記述していきます。
connectors:
count/hoge:
logs:
hoge.count:
description: The number of hoge logs
attributes:
- key: type
default_value: unknown
-
count/hoge
というコンポーネントとして命名する -
logs
で、ログをカウントの対象とする -
hoge.count
というメトリクス名とする - 属性
type
の値毎に集計する
これで、集計に関する定義ができました。
filelog receiver -> count connector -> metricsバックエンドのパイプラインの追加
コンポーネントは定義できたので、パイプラインを定義していきます。それぞれ、コンポーネントを定義するときの名前 filelog/hoge
, count/hoge
を思い出しながら、作っていきましょう。
service
> pipelines
の下に、次のパイプラインを追加します。
logs/hoge:
receivers: [filelog/hoge]
exporters: [count/hoge]
次に、既存のメトリクスパイプラインの中に、 count/hoge
を receivers
の一つとして追加します。
receivers: [count/hoge, hostmetrics, otlp, signalfx, smartagent/signalfx-forwarder]
これで準備ができました!
結果を確認する
では、実際に動かしてみて、動作を見てみます。Collectorの再起動を忘れずにやりましょう。
sudo systemctl restart splunk-otel-collector
データを作る
ログファイルを作っていくために、たとえばechoを使ってこんな感じにできます。
echo "{\"time\": \"$(date +"%Y-%m-%d %H:%M:%S")\", \"type\":\"B\", \"message\":\"hoge\"}" >> /var/log/hoge/hoge.log
type
の値を変えながら何度かコマンドを叩くと、 /var/log/hoge/hoge.log
はこんな感じのファイルが出来上がります。
{"time": "2023-08-31 05:19:14", "type":"C", "message":"hoge"}
{"time": "2023-08-31 05:19:14", "type":"C", "message":"hoge"}
{"time": "2023-08-31 05:19:22", "message":"hoge"}
{"time": "2023-08-31 05:19:23", "message":"hoge"}
{"time": "2023-08-31 05:19:23", "message":"hoge"}
{"time": "2023-08-31 05:20:18", "message":"hoge"}
{"time": "2023-08-31 05:20:20", "type":"C", "message":"hoge"}
{"time": "2023-08-31 05:20:23", "message":"hoge"}
{"time": "2023-08-31 05:20:26", "type":"B", "message":"hoge"}
問題がなければ、すでにメトリクスがバックエンドに送られているはずです。
メトリクスをクエリする
count connectorで定義したメトリクス名で、クエリをしてみましょう。Splunk ObservabilityではMetrics Finderで検索することができるはずです。
チャートを見ると、ログの件数が type
をディメンションとしてカウントされていることがわかります。
まとめ
さまざまなテレメトリーデータを目的に応じて使い分けるのは、オブザーバビリティのコストコントロールの第一歩です。OpenTelemetry Collectorを使うことで、そのようなコントロールが設定だけで出来るようになります。また、今回はメトリクスをSplunk Observabilityへ送りましたが、エクスポーターを変更することで、Prometheusなど様々なメトリクスバックエンドに送信することができます。
もちろん、ログを処理することでOpenTelemetry Collectorサービスの負荷は高まります。十分なCPU/メモリを確保する必要があるかもしれません。また、Count Connectorは「in development」であり、今後仕様や動作の変更があるかもしれません。しかしまあ、シンプルな機能なので、おそらく大丈夫じゃないかな。たぶん。
Discussion