はじめに
Usage Metrics (利用状況総計値) という機能をご存知でしょうか?
管理パッケージとして配布したアプリケーションが
インストールされた組織でどのくらい利用されているのかを知ることができる、という
アプリケーションベンダーにとってはちょっと気になる機能です。
しかしながらこの機能、Summer'14 から正式リリースになったにも関わらず
いまだにWeb上には公式ドキュメント以外の記事がなかなか出てきません。
というわけで、今回はこの機能についてざっくり紹介してみようと思います。
有効化の手順
本機能はデフォルトでは有効化されていないので、Salesforce にケース申請して有効化してもらう必要があります。
その手順については以前こちらの記事に書きました。
Usage Metrics(利用状況総計値)のインストール手順 - dackdive's blog
ポイントとしては
- 環境ハブを有効化しておく必要がある
- 以下2つの組織が環境ハブで接続されている必要がある
- リリース組織:パッケージのアップロードに使用する Development Edition 組織
- レポート組織:利用状況データが毎日配信される組織
ということでしょうか。レポート組織は LMO でいいと思います。
Usage Metrics で取得できる情報
管理パッケージをインストールした組織から取得できるのはカスタムオブジェクトとVisualforceページの情報です。
カスタムオブジェクトについてはレコード件数が、
VisualforceページについてはPV数やユニークユーザー数、平均読み込み時間が取得できます。
(詳しいデータ構造については後述)
Usage Metrics データ収集のしくみ
Usage Metrics を有効化すると、レポート組織に毎日自動的にデータが配信されます。
データは MetricsDataFile
というオブジェクト名で通常のSObjectと同じように扱うことができますが
SOQLやAPIでのアクセスのみ可能で、UIから参照することはできません。
また、特殊なデータだからか データストレージは消費しません。
MetricsDataFile
のレコードはSalesforce のインスタンスごとに作成されます。
ので、1日に作成されるレコードは
2(カスタムオブジェクトとVisualforce) * Salesforce のインスタンス数
となります。
※ 複数のアプリケーションを開発している場合、さらに * アプリケーション数
Usage Metrics のデータ型
Usage Metrics (というより MetricsDataFile
) のデータ構造から主なものを抜き出してみます。
ref. https://developer.salesforce.com/docs/atlas.ja-jp.196.0.packagingGuide.meta/packagingGuide/usage_metrics_metricsdatafile_object.htm
項目名 | 型 | 説明 |
---|---|---|
MetricsDataFile | Base64 | Base64で符号化された利用状況データが含まれるテキストファイル |
MetricsDataFileContentType | string | データファイルの形式。 現在有効なのは text/csv のみ |
MetricsDataFileLength | int | データファイルのサイズ(バイト) |
MetricsStartDate | dateTime | データ収集の開始日時 |
MetricsEndDate | dateTime | データ収集の終了日時 |
MetricsRunDate | dateTime | データ収集ジョブが実行された日付 |
MetricsType | picklist | データの種別 ( CustomObject もしくはVisualforce ) |
NamespacePrefix | string | データ収集の対象であるパッケージの 名前空間プレフィックス |
SendingInstance | string | このデータの収集元であるサーバインスタンス。 |
MetricsDataFile
というオブジェクトに MetricsDataFile
というフィールドがあってややこしいですね。
また、Base64 で〜と書いてますが、少なくともApexの場合は toString()
するだけでデータは取得できるのであまり気にしなくていいと思います。
List<MetricsDataFile> mdfList = [
SELECT
Id,
SendingInstance,
MetricsStartDate,
MetricsEndDate,
MetricsRunDate,
MetricsType,
MetricsDataFile
FROM MetricsDataFile
WHERE SendingInstance LIKE 'AP%'
AND MetricsType = 'Visualforce'
LIMIT 10];
for (MetricsDataFile mdf : mdfList) {
String mdfDataCSV = mdf.MetricsDataFile.toString();
System.debug(LoggingLevel.INFO, '-------------------');
System.debug(LoggingLevel.INFO, mdf.SendingInstance);
System.debug(LoggingLevel.INFO, mdf.MetricsStartDate);
System.debug(LoggingLevel.INFO, mdf.MetricsEndDate);
System.debug(LoggingLevel.INFO, mdf.MetricsRunDate);
System.debug(LoggingLevel.INFO, mdf.MetricsType);
System.debug(LoggingLevel.INFO, '**Data**');
System.debug(LoggingLevel.INFO, mdfDataCSV);
}
MetricsDataFile
というフィールドにお目当ての統計データがCSV形式で格納されるわけですが、
CSVのフォーマットはカスタムオブジェクトとVisualforceで異なります。
カスタムオブジェクトの場合
- 組織 ID
- 組織名
- 組織のエディション
- 組織のステータス (Active, Trial など)
- カスタムオブジェクト名
- カスタムオブジェクトのレコード件数
例)
"00Dxx0000001gbk","org1","Enterprise Edition","TRIAL","Alpha", "3500"
"00Dxx0000001gbk","org1","Enterprise Edition","TRIAL","Beta", "1500"
org1 という組織では、ある日の時点で Alpha
というカスタムオブジェクトが3500件、Beta
というカスタムオブジェクトが1500件存在したことを示します。
Visualforceの場合
- 組織 ID
- 組織名
- 組織のエディション
- 組織のステータス
- パッケージバージョン番号
- Visualforce ページの名前
- ページがアクセスされた回数
- ページにアクセスしたユニークユーザ数
- ページの平均読み込み時間 (ミリ秒)
例)
"00Dxx0000001gbk","org1","Enterprise Edition","TRIAL","1.0","/apex/gm12__f1","65","11","353"
"00Dxx0000001gbk","org1","Enterprise Edition","TRIAL","1.0","/apex/gm12__f2","1","1","128.0"
"00Dxx0000001gbk","org1","Enterprise Edition","TRIAL","1.0","/apex/gm12__f3","1","1","107.0"
"00Dxx0000001gbf","org1","Enterprise Edition","TRIAL","1.0","/apex/gm12__f1","5","1","73.6"
"00Dxx0000001gbf","org1","Enterprise Edition","TRIAL","1.0","/apex/gm12__f2","1","1","72.0"
"00Dxx0000001gbf","org1","Enterprise Edition","TRIAL","1.0","/apex/gm12__f3","7","1","50.8"
org1 という組織ではある日の gm12__f1
というページのPV数は65、ユニークユーザー数は11、平均読み込み回数は353msであったことを示します。
開発時のポイント
まずは Usage Metrics Visualization から始めよう
どんなデータが見れるかいまいちイメージできない、何から始めたらいいかわかんないという人は
Usage Metrics Visualization というパッケージをインストールしてとりあえずデータを表示してみるのがいいと思います。
https://developer.salesforce.com/docs/atlas.ja-jp.196.0.packagingGuide.meta/packagingGuide/usage_metrics_visualization.htm
Usage Metrics Visualization は AppExchange で配布されている未管理パッケージです。
https://appexchange.salesforce.com/listingDetail?listingId=a0N3000000B5FMvEAN
コードを読んだり独自でカスタマイズを加えることができるので
ここから徐々に自分の欲しいデータが見られるよう修正を加え、データの扱いに慣れてきたら自社に合った分析ツールを自作すると良いと思います。
Sandbox でもMetricsDataFile
は使えるが、データはコピーされない
MetricsDataFile
がどの組織でも使えるものではない以上、開発はレポート組織のSandbox組織で行うことになると思います。
レポート組織でMetricsDataFile
が有効になると、そのSandboxについてもメタデータにはアクセスできます。
ただ注意したいのが、フルSandboxであってもMetricsDataFile
のレコードはコピーされない ということです。
(なんとかしてくれって IdeaExchange に投稿しました)
ですので、開発時は
- 本番組織から1週間分ぐらいの
MetricsDataFile
をダウンロードする - 加工してテスト用のデータを作成し、Sandboxに静的リソースとしてアップロードする
- コード中の SOQL を実行している箇所でフラグに応じて静的リソースのデータを使うよう修正する
みたいなことが必要になると思います。
例として、Usage Metrics Visualization で実際にSOQLを実行しているのは MDFQueryDAOImpl.cls
というクラスですが、
これを書き換えるとこんな感じでしょうか。
public with sharing class MDFQueryDAOImpl implements MDFQueryDAO {
private static final boolean IS_DEV = true;
public List<MetricsDataFile> findMDFs(String sendingInstanceId, Date lookbackStartDate, Date lookbackEndDate) {
if (IS_DEV) {
return MDFMock.createMDFs(sendingInstanceId, lookbackStartDate, lookbackEndDate);
} else {
return [SELECT NamespacePrefix, MetricsDataFileLength, MetricsDataFile FROM MetricsDataFile
WHERE SendingInstance = :sendingInstanceId
AND MetricsStartDate >= :lookbackStartDate
AND MetricsStartDate <= :lookbackEndDate];
}
}
// (略)
public without sharing class MDFMock {
public static List<MetricsDataFile> createMDFs(String sendingInstanceId, Date lookbackStartDate, Date lookbackEndDate) {
List<MetricsDataFile> mdfList = new List<MetricsDataFIle>();
// Custom Object
List<StaticResource> srListCO = [SELECT Name, Body FROM StaticResource WHERE Name = 'MDFSampleCO' LIMIT
1];
// Visualforce
List<StaticResource> srListVF = [SELECT Name, Body FROM StaticResource WHERE Name = 'MDFSampleVF' LIMIT 1];
// --- 静的リソース -> MetricsDataFile への変換 ---
return mdfList;
}
with sharing
だと MetricsDataFile
にデータをセットできない
これもなにげにハマりポイントです。
たとえば、以下のVisualforceは表示時にエラーになります。
<apex:page controller="MDFController">
</apex:page>
public with sharing class MDFController {
public MDFController() {
MetricsDataFile mdf = new MetricsDataFile();
mdf.MetricsStartDate = Date.today(); // System.SObjectException: Field is not writeable
}
}
正直 MetricsDataFile
に関しては Daoクラスを with sharing
にする意味があるのかもよくわかりませんが、
MDFQueryDAOImpl.cls
を参考にするならば注意が必要です。
テストクラスでも MetricsDataFile
の insert は不可
MetricsDataFile
は読み取り専用なのでレコードを insert しようとするとエラーになります。
これはテストクラスにおいても同様です。
さすがにこれもどうにかならんのかということで IdeaExchange に投稿してます。
(こっちの方は多少Voteがあってうれしい)
ぶっちゃけ Usage Metrics Visualization の実運用には無理がある?
ここまで話しといてなんですが。
Usage Metrics Visualization がイケてないというより、Apex + Visualforce で実運用に耐える分析ツールを開発するのは難しいかも、という話です。
Usage Metrics Visualization を使ってみた印象ですが、ガバナ制限エラーが頻発します。
制限を超えてしまうのは CPU time であったりヒープサイズです。
参考までに、Winter'16 時点でのそれぞれの上限値は以下のようになっています。
Description | Synchronous Limit | Asynchronous Limit |
---|---|---|
Total heap size | 6 MB | 12 MB |
Maximum CPU time on the Salesforce servers5 | 10,000 milliseconds | 60,000 milliseconds |
(https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_gov_limits.htm より引用)
それではどうすれば良いのかというと、MetricsDataFile
はCSV部分だけ 日次で外部にエクスポートし、
分析ツールごと外部に構築してしまう というのが現実的なんじゃないかなと思ってます。
幸い REST API からも MetricsDataFile
にはアクセスできるので、REST API を定期的に叩いてデータをエクスポートするのがいいんではないでしょうか。
実はこれを私の好きなGoogle Apps Scriptで試してみようかなと思ったんですが今回は時間切れです。
Google Apps ScriptはOAuth2認証のためのライブラリがありますしクーロンを登録してメソッドを定期的に実行することもできますのでオススメです。
前にGitHubとOAuth2で連携するというのを試したことがあるんですが、認証まわりは同じノリでいけないかなーと思ってます。
[GoogleAppsScript]OAuth2でGitHubと連携し、issueをスプレッドシートに出力する - dackdive's blog
おわりに
というわけで、マイナーだけど気になる機能を知ってもらおうと思って書き始めたんですが
いかに使いづらいか を宣伝する結果になってしまった感があります。
ただ、冒頭でも書きましたが MetricsDataFile
は有効化してもデータストレージを消費しません し、
紹介した Usage Metrics Visualization も カスタムオブジェクトを含まない ことを考えると
とりあえず入れてみてもいいのかなと思っています。
リファレンス
ISVforce ガイド(日本語版は最新がSummer'15)
https://developer.salesforce.com/docs/atlas.ja-jp.196.0.packagingGuide.meta/packagingGuide/usage_metrics_intro.htm
Summer'14 リリースノート
http://releasenotes.docs.salesforce.com/ja-jp/summer14/release-notes/rn_forcecom_isvforce_usage_metrics.htm