Amazon AppStream 2.0の利用状況をGlue/Athenaを使って解析する

Amazon AppStream 2.0の使用状況レポートを有効化すると

  • スタック
  • フリート
  • アプリケーション
  • ユーザー
  • セッション時間

などに関するレポートを取得することができます。

本ブログでは、使用状況レポートを有効化し、レポートを分析する方法を紹介します。

構成

使用状況レポートを有効にすると、日次で

  • セッションレポート
  • アプリケーションレポート

の2種類のレポートが S3 に CSV 出力されます。

このレポートを AWS Glue でカタログ化し、Amazon Athena から SQL で問い合わせます。

制限事項

AppStream 2.0 使用状況レポートを利用するには、使用するイメージで、2019 年 5 月 7 日以降にリリースされたバージョンの AppStream 2.0 エージェントが実行されている必要があります。(参考)

やってみた

以下の流れで行います

  1. 使用状況レポートを有効化(AppStream2.0を利用)
  2. レポートのカタログ化(AWS Glueを利用)
  3. レポートを分析(Amazon Athenaを利用)

1. 使用状況レポートを有効化

AppStream 2.0 コンソール から「Usage Reports」に遷移し、レポート出力を有効化します。

2. レポートのカタログ化(AWS Glueを利用)

2.1 クローラーの設定

S3 に出力されたレポートを Athena からシームレスに利用するように、AWS Glue を使ってカタログ化します。

カタログ化用クローラー(AWS Glue Catalog)をデプロイする CloudFormation テンプレートが予め用意されています。

Usage Reports ページの Report Details タブにある "CloudFormation template" のリンクをクリックすると、クローラーをデプロイする CloudFormation スタックの作製画面が立ち上がります。

スタック起動時にパラメーターはすべて補完されています。デフォルト値のままスタックを作成して問題ありません。

各パラメーターの意味は下記表の通りです。

パラメーター 説明
AppStreamUsageReportsBucket 使用状況レポートの出力先S3バケット名
DatabaseName Glue Catalogのデータベース名
AppsCrawlerName アプリケーションレポートテーブル向けクローラー名
SessionsCrawlerName セッションレポートテーブル向けクローラー名
ScheduleExpression クローラー起動スケジュール

スタックの作製が完了すると、AWS Glue の Crawlers に CloudFormation で作成されたクローラーを確認できます。

2.2 カタログの確認

使用状況レポートを有効化し、レポートが出力されるようになると、そのレポートのクローリングを元にデータがカタログ化されます。

3. レポートを分析(Amazon Athenaを利用)

Amazon Athena は AWS Glue Catalog のカタログを利用できます。

Athena コンソールのデータベース一覧を確認すると、クローラーによってカタログ化された AppStream 2.0 用のデータベース・テーブルを確認できます。

テーブルの JOIN について

2つのテーブルを JOIN するには user_session_id フィールドを利用してください。

パーティショニング

Athena の問い合わせ時間・コストを減らすにはスキャン範囲を減らすことが効果的です。 Athena のスキャン範囲を減らすには、パーティショニング(year=[YYYY]/month=[MM]/day=[DD])を意識してください。

session_end_time BETWEEN '2019-05-19' AND '2019-05-26' と制限すると、データ全体をスキャンします。

year='2019' AND month='05' AND day BETWEEN '19' AND '25' とすることで、指定された日のデータだけをスキャンします。

カスタムレポート用 SQL 例

以下ではユースケース別にカスタムレポート用 SQL を紹介します。

カスタムレポートを作成して AppStream 2.0 使用状況データを分析する - Amazon AppStream 2.0 で紹介されている SQL をベースにしています。

アプリケーションレポートを参照

SELECT *
FROM "appstream-usage"."applications"
WHERE year='2019'
        AND month='07'

セッションレポートを参照

SELECT *
FROM "appstream-usage"."sessions"
WHERE year='2019'
        AND month='07' 

アプリケーションとユーザーの組み合わせを出力

SELECT DISTINCT apps.application_name,
         sessions.user_id
FROM "appstream-usage"."applications" apps
INNER JOIN "appstream-usage"."sessions" sessions
    ON (apps.user_session_id = sessions.user_session_id
        AND apps.year = sessions.year
        AND apps.month = sessions.month)
WHERE apps.year='2019'
        AND apps.month='07'
ORDER BY  1, 2

ユーザー別にセッション数・セッションの合計時間を求める

SELECT user_id,
         count(distinct user_session_id) AS num_sessions,
         sum(session_duration_in_seconds) AS total_session_duration
FROM sessions
WHERE year='2019'
        AND month='07'
GROUP BY  1
ORDER BY  1 

セッション x フリート別にセッションの合計時間を求める

SELECT stack_name,
         fleet_name,
         sum(session_duration_in_seconds) AS total_session_duration
FROM sessions
WHERE year='2019'
        AND month='07'
GROUP BY  1, 2
ORDER BY  1, 2 

セッション x フリート x アプリケーション別にセッションの合計時間を求める

SELECT sessions.stack_name,
         sessions.fleet_name,
         apps.application_name,
         sum(sessions.session_duration_in_seconds) AS total_session_duration
FROM "appstream-usage"."applications" apps
INNER JOIN "appstream-usage"."sessions" sessions
    ON (apps.user_session_id = sessions.user_session_id
        AND apps.year = sessions.year
        AND apps.month = sessions.month)
WHERE apps.year='2019'
        AND apps.month='07'
GROUP BY  1, 2, 3
ORDER BY  1, 2, 3

日別でセッション数を求める

SELECT SUBSTRING(session_start_time,
         1,
         1)  AS report_date,
         COUNT(DISTINCT user_session_id) AS num_sessions
FROM "appstream-usage"."sessions"
WHERE year='2019'
        AND month='07'
        AND day
    BETWEEN '01'
        AND '07'
GROUP BY  1
ORDER BY  1

S3 に出力されるレポートについて

使用状況レポート用S3バケットが作成され、日次で

  • セッションレポート
  • アプリケーションレポート

の2種類のレポートが S3 に CSV 出力されます。

S3 バケット名

使用状況レポートを有効にすると、次の命名規則の S3 バケットが作成されます。

appstream-logs-[リージョン]-[AWSアカウントID]-[ランダム文字列]

例)appstream-logs-us-west-2-1234567890123-abcdefg

S3 パス

Athena のパーティション機能を使えるように、S3 のパスが切られています。

  • セッションレポートのパス : [bucket_name]/sessions/schedule=DAILY/year=[YYYY]/month=[MM]/day=[DD]/daily-session-report-YYYY-MM-DD.csv
  • アプリケーションレポートのパス : [bucket_name]/applications/schedule=DAILY/year=[YYYY]/month=[MM]/day=[DD]/daily-app-report-YYYY-MM-DD.csv

具体的には、次の様に出力されます。

$ tree .
.
├── applications
│   └── schedule=DAILY
│       └── year=2019
│           └── month=07
│               ├── day=07
│               │   └── daily-app-report-2019-07-07.csv
│               ├── day=08
│               │   └── daily-app-report-2019-07-08.csv
│               ├── day=09
│               │   └── daily-app-report-2019-07-09.csv
│               └── day=10
│                   └── daily-app-report-2019-07-10.csv
└── sessions
    └── schedule=DAILY
        └── year=2019
            └── month=07
                ├── day=07
                │   └── daily-session-report-2019-07-07.csv
                ├── day=08
                │   └── daily-session-report-2019-07-08.csv
                ├── day=09
                │   └── daily-session-report-2019-07-09.csv
                └── day=10
                    └── daily-session-report-2019-07-10.csv

レポートのフィールド仕様

セッション・アプリケーションそれぞれのフィールド仕様は次のドキュメントを参照ください。

AppStream 2.0 Usage Reports Fields - Amazon AppStream 2.0

セッションデータとアプリケーションデータは user_session_id で JOIN します。

最後に

AppStream の使用状況レポートをAthenaで分析してみました。 カタログクローリング用のCloudFormationが用意されているため、簡単に分析を始めることができます。

レポートが出力されていれば、分析はあとからどうとでもできるため、何はともあれ使用状況レポートを出力しましょう。

参照