目的
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 として無料プランを提供しており、良さそうでしたので連携してみます。
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.
実際に Hobby ライセンスで無料アカウントを作成してみたところ、以下の機能範囲が有効化されていましたので、無料の範囲でも十分使えそうです。
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
を作成します。
Axiom データセット作成
以下の画面で AXIOM_DATASET_NAME
を作成します。
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.
下記の内容を参考にしました。
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_NAME
、 AXIOM_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 にバッチリ連携できました。結構検索もしやすく、動作も速い。
感想
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 何でもできるなぁー