Cloudflare の Analytics データ
Cloudflare Analytics では、以下のようにダッシュボードで確認できるデータを提供しています。
そのデータは GraphQL Analytics API を使って取り出すことができます。
利用可能な Datasets の中には、ダッシュボードで確認することができない(UI 未実装や Beta の)ものもあり、活用できるデータの宝庫になっています。
ログとの違い
では Cloudflare Logs との違いはどこにあるのでしょうか。
Analytics データは
-
Sampling される可能性があります。
Adaptive
と名の付くデータセットは動的にサンプリングレートが調整され、サンプルデータから全体を推測する倍率をかけたデータとなります。一方でログはユーザ自身でサンプリングを制御でき、すべてのデータにアクセスが可能です。 - 集計データが提供されます。
Groups
と名の付くデータセットは、すでに集計された形でデータ提供されるため、ログから集計する手間が省ける点で便利なことがあります。
Analytics データ保持期間
「Limits · Cloudflare Analytics docs」にある通り、データセットやプランによってデータ保持期間が変わってきます。
Cloudflare GraphQL データセットの保管期間を確認する - Qiita
以前はこのような保管期間がドキュメントで公開されていましたが、現時点ではドキュメントで確認できないため、自身で該当データを取得し、確認する必要があります。
その中でも、特に httpRequests1dGroups
は過去1年に遡って確認できる集計データとして活用の余地があります。
また、データセットとして対応していても、ダッシュボードで遡れるデータ範囲も限られている(+ UI であまり遡ると取得に時間がかかることもある)ため、GraphQL API を使ってデータを取得することで最大限の活用が可能です。
httpRequests1dGroups
の取得例
以下の変数をセットし
export GQL_ENDPOINT='https://api.cloudflare.com/client/v4/graphql'
export ACCOUNT_ID='YOUR_ACCOUNT_ID'
export ACCOUNT_ID2='YOUR_ACCOUNT_ID2'
export ZONE_ID='YOUR_ZONE_ID'
GraphQL API をコールすることで Analytics データを取得できます。
スキーマの探索は「Explore the Analytics schema with GraphiQL」が参考になります。
http -A creds $GQL_ENDPOINT query='query
{
viewer {
accounts(filter: {accountTag: "'${ACCOUNT_ID}'"}) {
httpRequests1dGroups (limit:32,filter:{date_geq:"2022-09-01",date_lt:"2022-10-01"},orderBy:[date_ASC]) {
sum {
bytes,
cachedBytes,
cachedRequests,
encryptedBytes,
encryptedRequests,
pageViews,
requests,
threats
}
dimensions {
date
}
}
}
}
}
' | jq -r '.data.viewer.accounts[].httpRequests1dGroups[]'
http -A creds $GQL_ENDPOINT query='query
{
viewer {
zones(filter: {zoneTag: "'${ZONE_ID}'"}) {
httpRequests1dGroups (limit:32,filter:{date_geq:"2022-09-01",date_lt:"2022-10-01"},orderBy:[date_ASC]) {
sum {
bytes,
cachedBytes,
cachedRequests,
encryptedBytes,
encryptedRequests,
pageViews,
requests,
threats
}
dimensions {
date
}
}
}
}
}
' | jq -r '.data.viewer.zones[].httpRequests1dGroups[]'
2022 年 9 月を対象として、1日ごとに集計されたデータのリストが確認できます。
{
"dimensions": {
"date": "2022-09-01"
},
"sum": {
"bytes": 60514334,
"cachedBytes": 60447958,
"cachedRequests": 15161,
"encryptedBytes": 60466295,
"encryptedRequests": 15165,
"pageViews": 12,
"requests": 15205,
"threats": 1
}
}
{
"dimensions": {
"date": "2022-09-02"
},
"sum": {
"bytes": 1622933,
"cachedBytes": 987969,
"cachedRequests": 447,
"encryptedBytes": 1297520,
"encryptedRequests": 568,
"pageViews": 123,
"requests": 827,
"threats": 82
}
}
...
{
"dimensions": {
"date": "2022-09-30"
},
"sum": {
"bytes": 715675,
"cachedBytes": 300188,
"cachedRequests": 121,
"encryptedBytes": 547365,
"encryptedRequests": 146,
"pageViews": 44,
"requests": 247,
"threats": 2
}
}
前月(N-1
月)の集計
月間トラフィック量を把握するためにさらに整理して集計します。
% date -v -1m +"%Y-%m-01"
2022-09-01
% date +"%Y-%m-01"
2022-10-01
http -A creds $GQL_ENDPOINT query='query
{
viewer {
accounts(filter: {accountTag: "'${ACCOUNT_ID}'"}) {
httpRequests1dGroups (limit:32,filter:{date_geq:"'$(date -v -1m +"%Y-%m-01")'",date_lt:"'$(date +"%Y-%m-01")'"},orderBy:[date_ASC]) {
sum {
bytes,
cachedBytes,
cachedRequests,
encryptedBytes,
encryptedRequests,
pageViews,
requests,
threats
}
dimensions {
date
}
}
}
}
}
' | jq -r '[.data.viewer.accounts[].httpRequests1dGroups[].sum | to_entries[] ] | group_by(.key) | map({key: .[0].key,value: map(.value) | add}) | from_entries'
http -A creds $GQL_ENDPOINT query='query
{
viewer {
account1:accounts(filter: {accountTag: "'${ACCOUNT_ID}'"}) {
httpRequests1dGroups (limit:32,filter:{date_geq:"'$(date -v -1m +"%Y-%m-01")'",date_lt:"'$(date +"%Y-%m-01")'"},orderBy:[date_ASC]) {
sum {
bytes,
cachedBytes,
cachedRequests,
encryptedBytes,
encryptedRequests,
pageViews,
requests,
threats
}
dimensions {
date
}
}
},
account2:accounts(filter: {accountTag: "'${ACCOUNT_ID2}'"}) {
httpRequests1dGroups (limit:32,filter:{date_geq:"'$(date -v -1m +"%Y-%m-01")'",date_lt:"'$(date +"%Y-%m-01")'"},orderBy:[date_ASC]) {
sum {
bytes,
cachedBytes,
cachedRequests,
encryptedBytes,
encryptedRequests,
pageViews,
requests,
threats
}
dimensions {
date
}
}
}
}
}
' | jq -r '[.data.viewer[][].httpRequests1dGroups[].sum | to_entries[] ] | group_by(.key) | map({key: .[0].key,value: map(.value) | add}) | from_entries'
http -A creds $GQL_ENDPOINT query='query
{
viewer {
zones(filter: {zoneTag: "'${ZONE_ID}'"}) {
httpRequests1dGroups (limit:32,filter:{date_geq:"'$(date -v -1m +"%Y-%m-01")'",date_lt:"'$(date +"%Y-%m-01")'"},orderBy:[date_ASC]) {
sum {
bytes,
cachedBytes,
cachedRequests,
encryptedBytes,
encryptedRequests,
pageViews,
requests,
threats
}
dimensions {
date
}
}
}
}
}
' | jq -r '[.data.viewer.zones[].httpRequests1dGroups[].sum | to_entries[] ] | group_by(.key) | map({key: .[0].key,value: map(.value) | add}) | from_entries'
前月の月間トラフィック量は 138 MB とすぐに把握できます。
{
"bytes": 138328396, # 138 MB
"cachedBytes": 94041494,
"cachedRequests": 24703,
"encryptedBytes": 97772563,
"encryptedRequests": 23677,
"pageViews": 1203,
"requests": 56092,
"threats": 335
}
過去11ヶ月分の月間トラフィック量(bytes
)
過去11ヶ月分の月間トラフィック量について、データを取得します。
for ((i=0; i<11; i++)); do echo -n "$(date -v -$(expr ${i} + 1)m +"%Y年%m月") (MB) : " && http -A creds $GQL_ENDPOINT query='query
{
viewer {
accounts(filter: {accountTag: "'${ACCOUNT_ID}'"}) {
httpRequests1dGroups (limit:32,filter:{date_geq:"'$(date -v -$(expr ${i} + 1)m +"%Y-%m-01")'",date_lt:"'$(date -v -${i}m +"%Y-%m-01")'"},orderBy:[date_ASC]) {
sum {
bytes,
cachedBytes,
cachedRequests,
encryptedBytes,
encryptedRequests,
pageViews,
requests,
threats
}
dimensions {
date
}
}
}
}
}
' | jq -r '[.data.viewer.accounts[].httpRequests1dGroups[].sum | to_entries[] ] | group_by(.key) | map({key: .[0].key,value: map(.value) | add}) | from_entries | (.bytes/1000000)' ; done
for ((i=0; i<11; i++)); do echo -n "$(date -v -$(expr ${i} + 1)m +"%Y年%m月") (MB) : " && http -A creds $GQL_ENDPOINT query='query
{
viewer {
zones(filter: {zoneTag: "'${ZONE_ID}'"}) {
httpRequests1dGroups (limit:32,filter:{date_geq:"'$(date -v -$(expr ${i} + 1)m +"%Y-%m-01")'",date_lt:"'$(date -v -${i}m +"%Y-%m-01")'"},orderBy:[date_ASC]) {
sum {
bytes,
cachedBytes,
cachedRequests,
encryptedBytes,
encryptedRequests,
pageViews,
requests,
threats
}
dimensions {
date
}
}
}
}
}
' | jq -r '[.data.viewer.zones[].httpRequests1dGroups[].sum | to_entries[] ] | group_by(.key) | map({key: .[0].key,value: map(.value) | add}) | from_entries | (.bytes/1000000)' ; done
年間の計画やレポートに活用できるかと思います。
2022年09月 (MB) : 138.328396
2022年08月 (MB) : 133.454489
2022年07月 (MB) : 19.204661
2022年06月 (MB) : 27.104583
2022年05月 (MB) : 463.646896
2022年04月 (MB) : 472.347435
2022年03月 (MB) : 339.184971
2022年02月 (MB) : 67.263986
2022年01月 (MB) : 469.10907
2021年12月 (MB) : 21.728387
2021年11月 (MB) : 15.443249
過去11ヶ月分の月間リクエスト数(requests
)
for ((i=0; i<11; i++)); do echo -n "$(date -v -$(expr ${i} + 1)m +"%Y年%m月") (リクエスト数) : " && http -A creds $GQL_ENDPOINT query='query
{
viewer {
accounts(filter: {accountTag: "'${ACCOUNT_ID}'"}) {
httpRequests1dGroups (limit:32,filter:{date_geq:"'$(date -v -$(expr ${i} + 1)m +"%Y-%m-01")'",date_lt:"'$(date -v -${i}m +"%Y-%m-01")'"},orderBy:[date_ASC]) {
sum {
bytes,
cachedBytes,
cachedRequests,
encryptedBytes,
encryptedRequests,
pageViews,
requests,
threats
}
dimensions {
date
}
}
}
}
}
' | jq -r '[.data.viewer.accounts[].httpRequests1dGroups[].sum | to_entries[] ] | group_by(.key) | map({key: .[0].key,value: map(.value) | add}) | from_entries | (.requests)' ; done
for ((i=0; i<11; i++)); do echo -n "$(date -v -$(expr ${i} + 1)m +"%Y年%m月") (リクエスト数) : " && http -A creds $GQL_ENDPOINT query='query
{
viewer {
zones(filter: {zoneTag: "'${ZONE_ID}'"}) {
httpRequests1dGroups (limit:32,filter:{date_geq:"'$(date -v -$(expr ${i} + 1)m +"%Y-%m-01")'",date_lt:"'$(date -v -${i}m +"%Y-%m-01")'"},orderBy:[date_ASC]) {
sum {
bytes,
cachedBytes,
cachedRequests,
encryptedBytes,
encryptedRequests,
pageViews,
requests,
threats
}
dimensions {
date
}
}
}
}
}
' | jq -r '[.data.viewer.zones[].httpRequests1dGroups[].sum | to_entries[] ] | group_by(.key) | map({key: .[0].key,value: map(.value) | add}) | from_entries | (.requests)' ; done
2022年09月 (リクエスト数) : 56092
2022年08月 (リクエスト数) : 26505
2022年07月 (リクエスト数) : 8530
2022年06月 (リクエスト数) : 12554
2022年05月 (リクエスト数) : 359617
2022年04月 (リクエスト数) : 25629
2022年03月 (リクエスト数) : 41212
2022年02月 (リクエスト数) : 12793
2022年01月 (リクエスト数) : 66101
2021年12月 (リクエスト数) : 9344
2021年11月 (リクエスト数) : 6159
過去 365 日間の集計
過去1年分について、データを取得します。
% date -v -365d +"%Y-%m-%d"
2021-10-14
% date +"%Y-%m-%d"
2022-10-14
http -A creds $GQL_ENDPOINT query='query
{
viewer {
accounts(filter: {accountTag: "'${ACCOUNT_ID}'"}) {
httpRequests1dGroups (limit:365,filter:{date_geq:"'$(date -v -364d +"%Y-%m-%d")'",date_leq:"'$(date +"%Y-%m-%d")'"},orderBy:[date_ASC]) {
sum {
bytes,
cachedBytes,
cachedRequests,
encryptedBytes,
encryptedRequests,
pageViews,
requests,
threats
}
dimensions {
date
}
}
}
}
}
' | jq -r '[.data.viewer.accounts[].httpRequests1dGroups[].sum | to_entries[] ] | group_by(.key) | map({key: .[0].key,value: map(.value) | add}) | from_entries'
http -A creds $GQL_ENDPOINT query='query
{
viewer {
zones(filter: {zoneTag: "'${ZONE_ID}'"}) {
httpRequests1dGroups (limit:365,filter:{date_geq:"'$(date -v -364d +"%Y-%m-%d")'",date_leq:"'$(date +"%Y-%m-%d")'"},orderBy:[date_ASC]) {
sum {
bytes,
cachedBytes,
cachedRequests,
encryptedBytes,
encryptedRequests,
pageViews,
requests,
threats
}
dimensions {
date
}
}
}
}
}
' | jq -r '[.data.viewer.zones[].httpRequests1dGroups[].sum | to_entries[] ] | group_by(.key) | map({key: .[0].key,value: map(.value) | add}) | from_entries'
こちらも年間の計画やレポートに活用できるかと思います。
{
"bytes": 2289883831, # 2.2 GB
"cachedBytes": 1531715556,
"cachedRequests": 441301,
"encryptedBytes": 2204593863,
"encryptedRequests": 583508,
"pageViews": 154492,
"requests": 643433,
"threats": 282210
}
まとめ
GraphQL API で取得できるデータには、まだまだ活用の余地があると思います。
今回はその一部を確認しましたが、次はチャートを作って見ること等にトライしたいと思います。
↓
Grafana (無料アカウント)で可視化できたので、以下 GitHub リンク内の「HTTP-Requests.json」をご活用ください。
- 手順:Cloudflare R2 の GraphQL Analytics を Grafana で可視化する - Qiita
- ダッシュボードファイル:https://github.com/kyouheicf/cloudflare-graphql-grafana