LoginSignup
4
2

Grafana Loki に Cloudflare Logpush する

Last updated at Posted at 2023-02-28

Grafana Loki とは

Grafana Loki に HTTP POST するには

/loki/api/v1/pushContent-Type: application/json で JSON ボディをポストできます。

sample.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/ 」から無料アカウントを作成します。

image-20230216172040540

「Forever Free」の枠があるので無料アカウントでも、それなりに使えます。
Loki には 14日間保持で 50GB logs を保存できます。

image-20230216172103405

すると Loki データソースが自動で構成されるので、URL と User の情報を使います。

image-20230228002256939

最後に「https://grafana.com/profile/org/api-keys?src=hg_home 」から API KEY を発行します。

image-20230228010811925

得られた情報を使ってテストデータを 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 データが以下のように確認できます。

image-20230228012206568

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

先にローカルでテストしたい場合は、以下のようにすると確認できます。

.dev.vars
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 のみ記述だと、 BotDetectionIDsFirewallMatchesActions などの Array はスキップされるので、Array フィールドを活用したい場合は、 BotDetectionIDs[0] として個別に取得する必要があります。

参考:Log queries | Grafana Loki documentation
https://grafana.com/docs/loki/latest/logql/log_queries/#json
Note: Arrays are skipped.

image-20230228121415744

Grafana ダッシュボードで可視化

上記のダッシュボードを参考に少しフィールドを微調整すれば、以下のように可視化できます。

image-20230228132130924

感想

Grafana Cloud を活用して、無料でこれだけのことができるとテンション爆上がりですね。

Cloudflare の Logpush が無料プランでも使えるようになる日を祈って楽しみに待ちましょう。

参考

4
2
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
4
2