Grafana Loki とは
Grafana Loki に HTTP POST するには
/loki/api/v1/push
に Content-Type: application/json
で JSON ボディをポストできます。
{
"streams": [
{
"stream": {
"label": "value"
},
"values": [
[ "<unix epoch in nanoseconds>", "<log line>" ],
[ "1677514484485207000", "{"BotScore":99,"BotScoreSrc":"Machine Learning","CacheCacheStatus":"miss","CacheResponseBytes":2478}" ]
]
}
]
}
タイムスタンプは、Cloudflare Logpush でも利用できる以下の形式にしましょう。
1628819445609000000 (unixnano)
Grafana Cloud で Loki を使う
「https://grafana.com/products/cloud/ 」から無料アカウントを作成します。
「Forever Free」の枠があるので無料アカウントでも、それなりに使えます。
Loki には 14日間保持で 50GB logs を保存できます。
すると Loki データソースが自動で構成されるので、URL と User の情報を使います。
最後に「https://grafana.com/profile/org/api-keys?src=hg_home 」から API KEY を発行します。
得られた情報を使ってテストデータを POST します。
export LOKI_HOST='YOUR_LOKI_HOST'
export LOKI_USER='YOUR_LOKI_USER'
export LOKI_API_KEY='YOUR_LOKI_API_KEY'
% curl -v -H "Content-Type: application/json" -XPOST -s \
"https://$LOKI_USER:$LOKI_API_KEY@$LOKI_HOST/loki/api/v1/push" --data-raw \
'{"streams": [{ "stream": { "foo": "bar2" }, "values": [ [ "1677514484485207000", "fizzbuzz" ] ] }]}'
* Trying 34.110.200.173:443...
* Connected to logs-prod-011.grafana.net (34.110.200.173) port 443 (#0)
...
> POST /loki/api/v1/push HTTP/2
...
> user-agent: curl/7.88.1-DEV
> accept: */*
> content-type: application/json
> content-length: 99
>
* We are completely uploaded and fine
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
< HTTP/2 204
< date: Mon, 27 Feb 2023 16:18:21 GMT
< via: 1.1 google
< alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
<
* Connection #0 to host xxx.grafana.net left intact
データソースを Explore すると、ラベルフィルタ指定でテスト POST データが以下のように確認できます。
Workers デプロイ
まず、こちらのコードをクローンします。
git clone https://github.com/kyouheicf/logpush-grafana-loki.git && cd $(basename $_ .git)
先ほど取得した各パラメータを Secret にセットします。
(また、src/index.js
スクリプト内の PRESHARED_AUTH_HEADER_VALUE
も必要に応じて変更してください。)
wrangler secret put LOKI_USER
wrangler secret put LOKI_API_KEY
wrangler secret put LOKI_HOST
先にローカルでテストしたい場合は、以下のようにすると確認できます。
LOKI_HOST='logs-prod-xxxxxx.grafana.net'
LOKI_USER='XXXXXX'
LOKI_API_KEY='eyJxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=='
wrangler dev
curl "http://localhost:8787/" -X POST \
--data-raw '{"content":"test","filename":"test.txt"}' \
-H "Content-Type: application/json" \
-H "X-Logpush-Auth: mypresharedkey"
echo '[{"BotScore":99,"BotScoreSrc":"Machine Learning","CacheCacheStatus":"miss","CacheResponseBytes":2478}, {"BotScore":1,"BotScoreSrc":"Heuristics","CacheCacheStatus":"dynamic","CacheResponseBytes":8346}]' | jq -c '.[]'| perl -p -e 'chomp if eof'| gzip > body.gz
curl "http://localhost:8787/" -X POST \
--data-binary @body.gz \
-H "Content-Type: application/json" \
-H "Content-Encoding: gzip" \
-H "X-Logpush-Auth: mypresharedkey"
最後に wrangler publish src/index.js
で Workers をデプロイします。
% wrangler publish src/index.js
⛅️ wrangler 2.11.0 (update available 2.11.1)
-------------------------------------------------------
Total Upload: 2.20 KiB / gzip: 0.88 KiB
Uploaded logpush-grafana-loki (1.31 sec)
Published logpush-grafana-loki (4.14 sec)
https://logpush-grafana-loki.example.workers.dev
Current Deployment ID: xxx-xxx-xxx-xxx-xxx
これで Logpush を待ち受けて、Grafana Loki (on Grafana Cloud) に Logpush する準備ができました。
Cloudflare 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": "grafana-loki",
"logpull_options": "fields='$FIELDS'",
"destination_conf": "https://logpush-grafana-loki.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"
Grafana Loki データソース確認
以下のクエリで Logpush されていることが確認できます。
また、各フィールドも JSON がパースされ、認識されていることがわかります。
{job="cloudflare-logpush-http-requests"} | json | __error__ = ""
ただし json
のみ記述だと、 BotDetectionIDs
や FirewallMatchesActions
などの Array はスキップされるので、Array フィールドを活用したい場合は、 BotDetectionIDs[0]
として個別に取得する必要があります。
参考:Log queries | Grafana Loki documentation
https://grafana.com/docs/loki/latest/logql/log_queries/#json
Note: Arrays are skipped.
Grafana ダッシュボードで可視化
上記のダッシュボードを参考に少しフィールドを微調整すれば、以下のように可視化できます。
感想
Grafana Cloud を活用して、無料でこれだけのことができるとテンション爆上がりですね。
Cloudflare の Logpush が無料プランでも使えるようになる日を祈って楽しみに待ちましょう。