この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
Amazon QuickSightは、分析結果をダッシュボードとして公開すると、参照のみ可能なリーダーと分析結果を共有出来ます。
ダッシュボードを公開した以上は、ダッシュボードのアクセス状況が気になるところです。
残念ながら、現在のAmazon QuickSightの管理画面はSPICE使用量などごく一部のメトリクスしか提供されておらず、CloudWatch連携もありません。
一方で、ダッシュボードへのアクセス(GetDashboard
API)はAWS CloudTrailに記録されます。
今回は、このAWS CloudTrailのAPIログにAmazon AthenaからSQLを投げてダッシュボードのアクセス数を復元する方法を紹介します。
AWS CloudTrailログクエリー用のAthenaテーブルを作成
AWS CloudTrailのEvent historyページからウィザード形式で作成出来ます。
詳細は次のページを参照ください。
GetDashboard APIのログ形式を確認
GetDashboard APIのログ形式を
- IAMユーザー経由のAuthorロール
- Readerロール
それぞれでアクセスして確認します。
違いは userIdentity
だけです。
IAMユーザー経由のAuthorには、principalId
の属性が存在します。
残りのフィールドは一緒です。
重要なフィールド
今回の目的では以下の3つのフィールドが重要です。
- 誰がアクセス? :
userIdentity
- どのダッシュボードにアクセス? :
serviceEventDetails.eventRequestDetails.dashboardId
- いつアクセス? :
eventTime
Readerロールの場合のログ形式
READER
{
"eventVersion": "1.05",
"userIdentity": {
"arn": "arn:aws:ds:us-east-1:123456789012:user/d-90672e24b8/bf1c0629-5635-407f-9d5f-e67defed5c3a",
"accountId": "123456789012",
"userName": "alice@example.com",
"type": "Directory"
},
"eventTime": "2018-12-17T18:24:06Z",
"eventSource": "quicksight.amazonaws.com",
"eventName": "GetDashboard",
"awsRegion": "us-east-1",
"requestParameters": null,
"responseElements": null,
"eventID": "3288f81f-6e7d-4a15-ab6e-f071b3fc0a62",
"readOnly": true,
"eventType": "AwsServiceEvent",
"recipientAccountId": "123456789012",
"serviceEventDetails": {
"eventRequestDetails": {
"dashboardId": "arn:aws:quicksight:us-east-1:123456789012:dashboard/5b1eb242-b3b9-461d-82ac-910a0b5435fe"
},
"eventResponseDetails": {
"dashboardDetails": {
"dashboardName": "dashboard name",
"dashboardId": "arn:aws:quicksight:us-east-1:123456789012:dashboard/5b1eb242-b3b9-461d-82ac-910a0b5435fe",
"analysisIdList": [
"arn:aws:quicksight:us-east-1:123456789012:analysis/cc5cc305-0e90-4a4a-8d4b-f9a1be821b3c"
],
"dataSetIdList": [
"arn:aws:quicksight:us-east-1:123456789012:dataset/e1115401-2d74-41e7-ab70-728efad7a289"
]
}
}
}
}
IAMユーザー経由のAuthorロールの場合のログ形式
userIdentity
以外の出力は Readerロールと同じ為、異なる箇所だけを抜粋します。
IAM user Author
{
"eventVersion": "1.05",
"userIdentity": {
"type": "IAMUser",
"principalId": "DUMMY-PRINCIPAL-ID",
"arn": "arn:aws:iam::123456789012:user/cm-jane.doe",
"accountId": "123456789012",
"userName": "cm-jane.doe"
},
...
}
Amazon Athena からAWS CloudTrailログに問い合わせる
Amazon AthenaからこのAWS CloudTrailログに問い合わせる上では
- userIdentity
- serviceEventDetails
の操作がややこしそうです。
userIdentityの操作
userIdentity
は次のように STRUCT
型をしています。
userIdentity STRUCT<
type: STRING,
principalId: STRING,
arn: STRING,
...
そのためuserIdentity
内の各値にはuserIdentity.principalId
というようにドットでアクセスできます。
serviceEventDetailsの操作
serviceEventDetails
はSTRING
型です。
"serviceEventDetails": {
"eventRequestDetails": {
"dashboardId": "arn:aws:quicksight:us-east-1:123456789012:dashboard/5b1eb242-b3b9-461d-82ac-910a0b5435fe"
},
"eventResponseDetails": {
"dashboardDetails": {
"dashboardName": "dashboard name",
"dashboardId": "arn:aws:quicksight:us-east-1:123456789012:dashboard/5b1eb242-b3b9-461d-82ac-910a0b5435fe",
"analysisIdList": [
"arn:aws:quicksight:us-east-1:123456789012:analysis/cc5cc305-0e90-4a4a-8d4b-f9a1be821b3c"
],
"dataSetIdList": [
"arn:aws:quicksight:us-east-1:123456789012:dataset/e1115401-2d74-41e7-ab70-728efad7a289"
]
}
}
}
という形をしているため、json_extract 関数を使い JSONPath 書式でエレメントを抽出してアクセスします。
json_extract のレスポンスは JSON 型であり、JSON型は順序関係が定まっていないため、ORDER BY したいときは cast(json_extract(serviceeventdetails, '$.eventRequestDetails.dashboardId') AS VARCHAR)
というように順序関係が定まっている型に CAST します。
目的別SQL例
ダッシュボード別アクセス数を知りたい
アクセスの多いダッシュボード上位5件を表示
SELECT cast(json_extract(serviceeventdetails,
'$.eventRequestDetails.dashboardId') AS VARCHAR) AS dashboardid , count(*) cnt
FROM cloudtrail_logs_cloudtrail_tbl
WHERE eventsource = 'quicksight.amazonaws.com'
AND eventname = 'GetDashboard'
AND eventtime >= '2018-12-01T00:00:00Z'
GROUP BY 1
ORDER BY 1
LIMIT 5
ユーザー別アクセス数を知りたい
アクセスの多いユーザー上位5件を表示
SELECT useridentity.type ,
useridentity.username ,
count(*) cnt
FROM cloudtrail_logs_cloudtrail_us_east_1_123456789012
WHERE eventsource = 'quicksight.amazonaws.com'
AND eventname = 'GetDashboard'
AND eventtime >= '2018-12-01T00:00:00Z'
GROUP BY 1,2
ORDER BY 3 desc, 1, 2
LIMIT 5
ダッシュボード x ユーザー別アクセス数を知りたい
SELECT cast(json_extract(serviceeventdetails,
'$.eventRequestDetails.dashboardId') AS VARCHAR) AS dashboardid , useridentity.type , useridentity.username , count(*) cnt
FROM cloudtrail_logs_cloudtrail_us_east_1_123456789012
WHERE eventsource = 'quicksight.amazonaws.com'
AND eventname = 'GetDashboard'
AND eventtime >= '2018-12-01T00:00:00Z'
GROUP BY 1,3, 2
ORDER BY 1, 2,3
謝辞
AWS CloudTrailからAmazon QuickSightダッシュボードのアクセス数を集計できることは、AWS re:Invent開催中にAmazon QuickSightのエンジニアから教わりました。
実際にサービス開発に携わっているエンジニアに直接質問できるのは、re:Inventの醍醐味の一つですね。