見出し画像

CRM AnalyticsとAWS Lambdaを使ってAppExchange App Analyticsデータの可視化を自動化してみた。

こんにちは、co-meetingの町田です。今回は、SalesforceのAppExchangeアプリの分析サービス「AppExchange App Analytics」で取得できるログデータの可視化を自動化してみました。
では、App Analyticsの概要からはじめていきます!


そもそもApp Analyticsとは?

SalesforceのAppExchangeアプリの分析ログデータ収集サービスです。AppExchangeアプリが実行したApexやDML操作などのログデータ取得が可能です。
取得できるデータの具体例は、App Analytics パッケージ利用状況ログデータの読み方 | ISVforce ガイド | Salesforce Developers に記載されています。

App Analyticsのログデータ収集は以下の図のように行われています。

AppExchange の App Analytics のデータフロー | ISVforce ガイド | Salesforce Developers

各登録者組織のデータが「Salesforce Data Lake」に蓄積され、「Your AppAnalyticsQueryRequest」で、ログデータをダウンロードすることができます。
具体的には、PBO組織でAppAnalyticsQueryRequestオブジェクトのレコードを作成すると、Data Lakeでデータ処理が行われます。データ処理が完了すると、レコードの項目が更新され、ログデータのダウンロードURLなどが確認できます。

どうして自動化したくなった?

App Analyticsの機能はログデータの取得のみのため、都度手動でデータ取得を行い、グラフを作って可視化をするのは面倒だったので、自動化したくなりました。

自動化する上で意識したこと

現状App Analyticsのログデータに価値があるかわからないので、なるべくお金をかけないこと。運用のしやすさを確保するために、なるべくSalesforceの上で構成することを意識しました。

自動化システムの流れ

基本的にはSalesforce内となっていますが、AWS LambdaのみSalesforce外となっています。理由としては、ログデータのサイズが大きく、Apex ガバナ制限のヒープの合計サイズやApex トランザクションごとの最大実行時間を超えてしまうためです。
下図に自動化システムの流れを示してみました。

自動化システムの流れ

では、流れに沿って解説してみます。

[スケジュール済みApex] AppAnalyticsQueryRequest レコードの作成

ログデータは日々蓄積されていくため、定期的にデータを取得し、可視化用データセットに追加していく必要があります。
最初にスケジュール済みApexでAppAnalyticsQueryRequestレコードを作成を行います。これが自動化システムの起点となります。

AppAnalyticsQueryRequestについて

App AnalyticsのData Lakeに対してデータ取得クエリを発行するオブジェクトです。
AppAnalyticsQueryRequest | Salesforce プラットフォームのオブジェクトリファレンス | Salesforce Developers
データ発生日時の範囲の指定、データタイプの指定などが行なえます。今回は以下のように指定しました。スケジュール済みApexは日中1時間ごとの実行となってます。

AppAnalyticsQueryRequest queryRequest = new AppAnalyticsQueryRequest();
queryRequest.DataType = 'PackageUsageLog';
queryRequest.PackageIds = PACKAGE_ID;
queryRequest.FileType = 'csv';
queryRequest.StartTime = Datetime.now().addDays(-7).addHours(-1);
queryRequest.EndTime = Datetime.now().addDays(-7);
insert queryRequest;

注) 一度にダウンロードできるデータ量はAWS Lambdaのメモリリミットの都合で1.9GBぐらいまで

AWS Lambdaのメモリリミットの最大値は10240MBです。650MBくらいのデータでテストしたところ、使用済みメモリは3499 MBとなりました。これより、取り扱えるおおよそのデータサイズは 10240 / 3500 × 650 ≒ 1900 MB と推測しました。
ログデータはアプリ規模に比例して大きくなります。弊社アプリでは1時間毎の取得で問題ありませんでしたが、データ量が多くなった場合はクエリと定期実行間隔の調整を行わう必要がありそうです。

[App Analytics] AppAnalyticsQueryRequestレコードの更新

Data Lakeへデータ取得クエリが発行され、処理が完了するとAppAnalyticsQueryRequestレコードが更新されます。

[Apex Trigger] Apex Queueableを追加

AppAnalyticsQueryRequestのApex Trigger で更新を検知し、ダウンロードURLが発行されていた場合、Apex Queueableを追加します。

[Apex Queueable] AWS Lambdaへリクエスト

AWS Lambdaへリクエストを行います。クエリパラメータにはダウンロードURLとファイル名を指定します。

[AWS Lambda] CSVファイルのダウンロードとCRM Analyticsデータセットへアップロード

クエリパラメータから受け取ったダウンロードURLから表データをダウンロードします。ダウンロードURLはパブリックなので、特に何も考えずにダウンロードできました。
その後、InsightsExternalDataを用いてCRM Analyticsのデータセットへアップロードを行います。

InsightsExternalDataを用いたCRM Analyticsのデータセットへのアップロード

REST APIを用いてInsightsExternalDataでデータセットへアップロードします。
処理の流れは

  1. 認証リクエスト、アクセストークンを取得

  2. InsightsExternalDataレコードを作成

  3. ファイルをチャンクに分け、それぞれInsightsExternalDataPartを作成

  4. InsightsExternalData.Actionを"Process"に更新

となっています。4以降のデータ処理の進捗はCRM Analyticsのジョブ監視で確認することができます。

認証について
今回はClient Credentials Flowを使ってみました。
OAuth 2.0 Client Credentials Flow for Server-to-Server Integration 

InsightsExternalDataとInsightsExternalDataPartについて
ファイルサイズが15MBを超える場合は、ファイルをチャンクに分けてアップロードする必要があります。チャンクごとに作成されるレコードがInsightsExternalDataPartとなっています。
以下に、InsightsExternalDataとInsightsExternalDataPartを作成した際に指定した項目を抜き出してみます。
まずはInsightsExternalDataです。

  • Action : デフォルト"None"。InsightsExternalDataPartをすべて作成後に"Process"に更新することでデータ処理を行います。

  • EdgemartAlias : データセットの別名。組織全体で一意にする必要があります。

  • EdgemartContainer : データセットが含まれるアプリケーションの名前。

  • EdgemartLabel : データセットの表示名。

  • FileName : 外部データファイルの識別子 (ファイル名など)。

  • Operation : データセットへデータを追加/上書き/削除など操作を示します。設定値は、Append, Delete, Overwrite, Upsert。 

  • MetadataJson : アップロードするファイルの構造を記述します。CRM Analyticsページから、手動でデータセットをアップロードする際に取得可能でした。Blob (Base64 符号化文字列)型のため、Base64エンコードが必要でした。

MetadataJsonに指定するJSONはここで取得できました。

つづいてInsightsExternalDataPartです。

  • InsightsExternalDataId : このパーツが属する InsightsExternalData オブジェクトの ID。

  • DataFile : データ部分。各パーツは、10 MB 未満にする必要があります。

  • PartNumber : パーツ番号。パーツ番号は、1 から始まる連番にする必要があります (たとえば、1、2、3 など)。

アップロード部のコード例

AWS LambdaのNode.jsからInsightsExternalDataをREST APIで作成する例です。

[CRM Analytics] データの可視化

アップロード完了後、データをCRM Analyticsで可視化することができます。

CRM Analyticsの保存容量について

データ行数による制限があるようです。弊社組織では185,000,000行でした。
650MB程のデータはおよそ37,000行だったので保存できるデータ量は
185,000,000 / 37,000 × 650 ≒ 3,250,000 MB 程であると推測できます。

以上、自動化のシステムについてでした。

今後の課題

  • アプリの利用者が増え、データ量が増えたときのクエリ戦略

  • データをどのように活用するか

  • 弊社メンバー全員が見れるようにしたい。(App ExchangeアプリパートナーはCRM Analyticsライセンスが2つまで)

今後はこれらを解消して行きたいです。

おわりに

普段あまり触らないAWS LambdaやREST APIなどに触れるいい機会になりました。
ここまでやりましたが、できればApp AnalyticsとCRM Analyticsが接続してくれることを願うばかりです。