🗃️
OpenTelemetry CollectorでSQL Queryしてログ取得かメトリクス化する
はじめに
たまに取り込みたいデータがDB内にある時がありますよね。
なんとOpenTelemetry CollectorはDBにクエリかけて取り込めもできちゃいます。
SQL Query receiver
これを使います。
特徴としてはこの辺りかと思います。
- 任意のカラムの最終取り込み値を管理して差分取得(tracking)ができる
- ログ直接取り込み、もしくはメトリクス化して取り込みができる
対応DB driverは現時点(2023年10月)だと以下のようです。
postgres, mysql, snowflake, sqlserver, hdb (SAP HANA), or oracle (Oracle DB).
まだMetricはAlpha、LogはDevelopmentなので将来の拡張に期待です。
やってみた
テストデータ
PostgreSQLでこんなデータを用意しました。裏側でスクリプト走らせて毎秒追加しています。
id | timestamp | alert_level | message |
---|---|---|---|
10001 | 2023-10-13 04:42:17.4883+00 | INFO | Sample message at level INFO |
10002 | 2023-10-13 04:42:18.490512+00 | ERROR | Sample message at level ERROR |
10003 | 2023-10-13 04:42:19.49282+00 | ERROR | Sample message at level ERROR |
・・・ | ・・・ | ・・・ | ・・・ |
Otel設定
Otel Collectorには以下のような設定をします。
receivers:
sqlquery/postgrestest:
driver: postgres
storage: file_storage # Checkpoint保存先をファイルとする
datasource: "host=localhost port=5432 user=<User Name> password=<Password> dbname=<DB name> sslmode=disable" # 定義方法は各DBによる。これはPostgreSQL用
collection_interval: 60s # デフォルト10s
queries:
- sql: "SELECT id, row_to_json(t) FROM (SELECT * FROM alert_logs WHERE id > $$1 ORDER BY id) t;"
tracking_start_value: 1 # tracking初期値。デフォルトは""。
tracking_column: id # tracking用カラム名。デフォルトは""。
logs:
- body_column: row_to_json # 出力したいカラム名
- sql: "select count(*) as count, alert_level from alert_logs group by alert_level"
metrics: # これでメトリクス化できる
- metric_name: alert.level
value_column: "count"
attribute_columns: ["alert_level"]
static_attributes:
dbinstance: dbdemo
extensions:
file_storage:
# ログをSplunkに送る場合で、sourcetypeを変えたい場合。
processors:
resource/sqlquery:
attributes:
- key: com.splunk.sourcetype
value: "_json"
action: upsert
service:
extensions: [..., file_storage]
pipelines:
metrics:
receivers: [..., sqlquery/postgrestest]
logs/sqlquery:
receivers: [sqlquery/postgrestest]
processors: [resource/sqlquery] # ログをSplunkに送る場合で、sourcetypeを変えたい場合。
注意点としては以下の辺りかなと思います。
- storageを定義すること。さもないとチェックポイントがメモリ内に保存されてOtel Collector再起動時に失われてしまう。
ちなみにextensions.file_storageを指定するとデフォルト値で/var/lib/otelcol/file_storage/receiver_sqlquery_postgrestest
に出力される。
/var/lib/otelcol/file_storage
をRead/Write権限与えて作成しておくこと。 - trackingを行う場合、必ずSELECTで対象のカラムを出力すること。Trackingの詳細はこちら。
- ログとして出力するカラムは一つしか選べない。複数のカラムの値を送りたい場合は結合するかJSONにするとよい。
log
クエリと結果はこんなのです。
$$1はPostgreSQL用のプレースホルダ表記方法なのでDBに応じて変えてください。
上で書いた通り、カラムは今のところ一つしか選べないので複数のカラムをJSONでまとめました。
log用クエリ
SELECT id, row_to_json(t) FROM (SELECT * FROM alert_logs WHERE id > $$1 ORDER BY id) t;
id | row_to_json |
---|---|
10001 | {"id":10001,"timestamp":"2023-10-13T04:42:17.4883+00:00","alert_level":"INFO","message":"Sample message at level INFO"} |
Splunkに投げてみました。
ちゃんとJSONを解析してくれていますね。
この画像からは見えないですが、ちゃんとクエリの度にTrackingにより差分だけ取れています。
metric
クエリと結果はこんなのです。
もちろん、こっちでもTracking使ってもいいです。
metric用クエリ
select count(*) as count, alert_level from alert_logs group by alert_level;
count | alert_level |
---|---|
4453 | ERROR |
4271 | WARNING |
4297 | INFO |
これもSplunkに。
いいですね。
デフォルトはgaugeですが設定でdeltaにもできます。
まとめ
Otel Collector、なんでもできちゃうねというお話の一つでした。
Discussion