LoginSignup
1
0

More than 1 year has passed since last update.

Cloudflare Logpush を Axiom に Ingest する

Last updated at Posted at 2022-11-30

目的

Cloudflare の Logpush が無料プランで使えるようになるとの発表を受け、無料のログ SaaS と連携する方法を探しました。

https://blog.cloudflare.com/announcing-logs-engine/
Finally, Logpush was previously limited to Enterprise plans. Soon, we will start offering these services to customers at any scale, regardless of plan type or how they choose to pay.

Workers Launchpad プログラムに参加している「Axiom」という会社がログ SaaS として無料プランを提供しており、良さそうでしたので連携してみます。

https://blog.cloudflare.com/ja-jp/launchpad-fall-22-ja-jp/
img

Axiom とは

https://www.axiom.co/ - Observability を提供する会社でログの取得先も幅広く対応しているようです。

クエリ対応を充実しており、ログを取得して分析するまでを1つのプラットフォームで完結できる。

https://www.axiom.co/play のプレイグラウンドから試すことでわかりますが、動作が速い。

https://www.axiom.co/pricing にプランがありますが、ログに関する柔軟なプライシングの考え方も魅力です。

All plans include bandwidth, api access, and unlimited data sources - subject to our Fair Use Policy.

image-20221128161418313

実際に Hobby ライセンスで無料アカウントを作成してみたところ、以下の機能範囲が有効化されていましたので、無料の範囲でも十分使えそうです。

image-20221128161620418

Axiom Ingest API

上記の Ingest API により、json, ndjson, csv でログを投げて取り込むことができます。

ndjson に対応しているあたり、Logpush に関してはコード量が削減できて都合が良い)

Cloudflare Logpush --> Workers --> Axiom

Cloudflare の Logpush には、任意の HTTP エンドポイントにログ出力を行うことができます。

上記の記事を参考に、Cloudflare Logpush --> Cloudflare Workers --> Axiom という構成を実装します。

Axiom API トークン作成

以下の画面で AXIOM_API_TOKEN を作成します。

image-20221128235141559

Axiom データセット作成

以下の画面で AXIOM_DATASET_NAME を作成します。

image-20221128232411553

Workers コード

GitHub にコードをアップロードしておきました。

コード作成の際には、gzip 解凍時に DecompressionStream が使えるようになったので

https://blog.cloudflare.com/standards-compliant-workers-api/
CompressionStream and DecompressionStream
Streaming compression and decompression is also now supported in the runtime using the standard CompressionStream and DecompressionStream APIs.

下記の内容を参考にしました。

src/index.js
export default {
	async fetch(request, env, ctx) {
		// Check pre-shared key header
		const PRESHARED_AUTH_HEADER_KEY = 'X-Logpush-Auth';
		const PRESHARED_AUTH_HEADER_VALUE = 'mypresharedkey';
		const psk = request.headers.get(PRESHARED_AUTH_HEADER_KEY);
		if (psk !== PRESHARED_AUTH_HEADER_VALUE) {
			return new Response('Sorry, you have supplied an invalid key.', {
				status: 403,
			});
		}

		// Initial pre-flight Logpush Request to confirm the integration check
		const buf = await request.arrayBuffer();
		const compressed = new Uint8Array(buf);
		const enc = new TextDecoder("utf-8");
		if (enc.decode(compressed).trim() === '{"content":"test","filename":"test.txt"}') {
			const json = '{"content":"test","filename":"test.txt"}';
			return await fetch(`https://cloud.axiom.co/api/v1/datasets/${env.AXIOM_DATASET_NAME}/ingest`, {
				method: "POST",
				body: json,
				headers: {
					"Content-Type": "application/x-ndjson",
					Authorization: `Bearer ${env.AXIOM_API_TOKEN}`
				}
			});
		}

		// Decompress gzipped logpush body to ndjson
		const blob = new Blob([buf])
		const ds = new DecompressionStream('gzip');
		const decompressedStream = blob.stream().pipeThrough(ds);
		const buffer = await new Response(decompressedStream).arrayBuffer();
		const decompressed = new Uint8Array(buffer)
		const ndjson = enc.decode(decompressed)

		// Ingest to Axiom
		return await fetch(`https://cloud.axiom.co/api/v1/datasets/${env.AXIOM_DATASET_NAME}/ingest`, {
			method: "POST",
			body: ndjson,
			headers: {
				"Content-Type": "application/x-ndjson",
				Authorization: `Bearer ${env.AXIOM_API_TOKEN}`
			}
		});
	},
};

Workers Secrets 設定 & デプロイ

Axiom の設定情報( AXIOM_DATASET_NAMEAXIOM_API_TOKEN )を Secret に設定します。

wrangler secret put AXIOM_DATASET_NAME
wrangler secret put AXIOM_API_TOKEN

その後、Workers をデプロイします。

wrangler publish

これで Logpush を待ち受けて、Axiom に Ingest する準備ができました。

Logpush 構成

以下のコマンドで、Workers をターゲットとした Logpush ジョブを構成します。

export EMAIL='YOUR_EMAIL'
export APIKEY='YOUR_APIKEY'
export ZONE_ID='YOUR_ZONE_ID'

# 全フィールドを指定
export FIELDS=$(curl -s \
-H "X-Auth-Email: $EMAIL" \
-H "X-Auth-Key: $APIKEY" \
"https://api.cloudflare.com/client/v4/zones/$ZONE_ID/logpush/datasets/http_requests/fields" | jq -r '.result | keys | join(",")')
# echo $FIELDS

# example.workers.dev と example.com 等は適宜変更
curl -s "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/logpush/jobs" -X POST -d '
{
  "name": "axiom",                                   
  "logpull_options": "fields='$FIELDS'",
  "destination_conf": "https://logpush-axiom.example.workers.dev?header_X-Logpush-Auth=mypresharedkey&tags=host:example.com,dataset:http_requests",
  "max_upload_bytes": 5000000,
  "max_upload_records": 1000,
  "dataset": "http_requests",
  "enabled": true
}' \
-H "X-Auth-Email: $EMAIL" \
-H "X-Auth-Key: $APIKEY"

確認

Axiom にバッチリ連携できました。結構検索もしやすく、動作も速い。

image-20221129011700535

感想

Cloudflare の Logpush が無料プランでも使えるようになる期待を込めて、今後活用の場面が来ることを楽しみに待ちます。

この方法を使えば、ログの連携先はどこでも大丈夫そうなので、改めて Workers の柔軟性について理解を深めた次第でした。

また、Workers ログも有償プランで Logpush できるようになったので、個人開発にも活用できるかと思います。

Workers visibility: announcing Logpush for Worker’s Trace Events
Logpush · Cloudflare Workers docs
This product is available on the Workers Paid plan.

Workers 何でもできるなぁー

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0