【Dynamics CRM】【Azure】Application Insights連携を試してみた
前回投稿した、Azure Application Insightsをもうちょっと突っ込んだ記事になります。
Application Insightsとは?
あらためて、Application Insightsとは?
以下、引用ですが、どちらかといえば、developer向けのAzure PaaSかなぁと思いますが、今回の組み込み内容としては、エンドユーザー向けの分析データ採取という観点が強いかと思います。(機能的にはSaaSに近いかも?)
Visual Studio Application Insights は、実行中の Web アプリケーションを監視する拡張可能な分析サービスです。パフォーマンスの問題の検出と診断や、ユーザーがアプリを使用して実際に実行する操作の理解に役立ちます。開発者向けに設計された Application Insights を使用して、パフォーマンスやユーザビリティを継続的に向上させることができます。オンプレミスまたはクラウドでホストされている .NET、Node.js、J2EE などのさまざまなプラットフォーム上のアプリで機能します。
https://azure.microsoft.com/ja-jp/documentation/articles/app-insights-overview/
基本的なアプローチとしては、例えば.NET MVCのスクラッチ系アプリに、Application InsightsのSDKで提供されているライブラリを組み込むことで、Web アプリの稼働状況、パフォーマンス問題などを検出・分析するための基盤になるかと思います。
ただ、今回はスクラッチ系アプリに組み込むのではなく、Application Insightsが提供しているJavaScriptベースの連携用コードを利用することで、既存のWeb系アプリ(SaaS系かつJavaScriptが埋め込めるものであれば、なんでも)に組み込んで、分析を可能にするというアプローチを応用するスタイルをとっています。
(個人的には、Visual Studioのアドオンとして機能するApplication Insightsの機能も結構好きなのですが。まあ、またそれは別のお話し https://azure.microsoft.com/ja-jp/documentation/articles/app-insights-visual-studio/)
Dynamics CRMに組み込むことのメリット
Dynamics CRMでは監査という機能で、CRMを操作しているユーザーの行動を記録していますが、基本的に、ユーザーの操作(Create・Update・Delete)の取得が中心であり、かつログとしての提供しかしていません。
また、ユーザーアクセスは取得できるますが、どのレコード・どのビューを表示したかまではわからないというのが現状です。

ですが、Application Insightsを組み込むことで、CRMのどの「レコード」「ビュー」をどのユーザーがいつアクセスしたのか、ユーザーが使っている「ブラウザ」「ロケーション」「IPアドレス」はどのようなものか、を取得することができ、かつ、Application Insightsの画面である程度の分析できるインターフェースが提供されます。(そのままではいまいちかと思いますが)
また、JavaScriptを埋め込めるところであれば、どこでも可能といえば可能ですので、
理屈的にはコマンドバーへ組み込んで、Excelエクスポートの実行者までとれるかなと思います。
使い方1 Application Insightsの構成
以下のような感じでApplication Insightsをはじめに構成します。

アプリケーションはASP.NETで構成


構成後、「はじめに」から、JavaScriptのサンプルコードを取得します。これをベースとして、Dynamics CRMに登録します。

使い方2 Dynamics CRMへの組み込み
前述のとおり、Application InsightsのJavaScript版をDynamics CRMに組み込みます。
ただ、初期状態で提供されているJavaScriptのサンプルコードでは、送信するためのメソッドへの引数が何も設定されていない状態です。以下のCodePlexにサンプルソリューションが提供されていますので、今回はそれを参考に調整してみました。
Dynamics CRM and App Insights
dynamicsandappinsights.codeplex.com
下記コードの「instrumentationKey」の部分を提供されているinstrumentationKeyに置き換えてください。
var UserName;
var Alias;
var serverUrl;
function Getinfo() {
var context;
var UserID;
var ODataPath;
var selectFields = "$select=DomainName,FullName";
context = Xrm.Page.context;
serverUrl = context.getClientUrl();
UserID = context.getUserId();
ODataPath = serverUrl + "/XRMServices/2011/OrganizationData.svc";
var retrieveUserReq = new XMLHttpRequest();
retrieveUserReq.open("GET", ODataPath + "/SystemUserSet(guid'" + UserID + "')?" + selectFields, false);
retrieveUserReq.setRequestHeader("Accept", "application/json");
retrieveUserReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
retrieveUserReq.onreadystatechange = function () {
retrieveUserReqCallBack(this);
};
retrieveUserReq.send();
}
function retrieveUserReqCallBack(retrieveUserReq) {
if (retrieveUserReq.readyState == 4 /* complete */) {
if (retrieveUserReq.status == 200) {
var retrievedUser = JSON.parse(retrieveUserReq.responseText).d;
if (retrievedUser.FullName != null) {
UserName = retrievedUser.FullName;
Alias = retrievedUser.DomainName;
}
}
}
}
function captureTelemetry() {
var appInsights = window.appInsights || function (config) {
function s(config) { t[config] = function () { var i = arguments; t.queue.push(function () { t[config].apply(t, i) }) } } var t = { config: config }, r = document, f = window, e = "script", o = r.createElement(e), i, u; for (o.src = config.url || "//az416426.vo.msecnd.net/scripts/a/ai.0.js", r.getElementsByTagName(e)[0].parentNode.appendChild(o), t.cookie = r.cookie, t.queue = [], i = ["Event", "Exception", "Metric", "PageView", "Trace"]; i.length;)s("track" + i.pop()); return config.disableExceptionTracking || (i = "onerror", s("_" + i), u = f[i], f[i] = function (config, r, f, e, o) { var s = u && u(config, r, f, e, o); return s !== !0 && t["_" + i](config, r, f, e, o), s }), t
} ({
instrumentationKey: "REPLACE"
});
window.appInsights = appInsights;
appInsights.trackPageView(Xrm.Page.data.entity.getEntityName(), serverUrl, { User: Xrm.Page.context.getUserName(), DomainName: Alias });
}
Getinfo();
captureTelemetry();
ポイントはtrackPageViewメソッドですね。
trackPageViewメソッドの第1引数がページ名、第2引数がページURL、第3引数がカスタムデータとして、様々にオブジェクトをカスタムして渡せる感じかなと思います。
これを、以下の通り、Dynamics CRM のWebリソースとして登録して、実行したい箇所に登録します。
今回は単純にフォームを表示した時に動作するものとして、登録してみました。

Webリソースに上記コードを入力。

Webリソースに登録後、フォームのライブラリに登録。Scriptにそのままメソッドの実行が記載されていますので、OnLoadなどに登録する必要はありません。


こんな感じに見えますよ

カスタムデータを工夫すれば、もっといろいろと情報の分析材料をApplication Insightsに提供できる感じかなと思います。
注意点
Application Insightsのデータの保存期間は7日間みたいです。
定性的なデータ分析として利用したい場合は、間にAzure StorageやStream Analytics、Power BIなども交えて、うまくエンドユーザー向け提供の形を整える必要があるかなと思います。
Application Insights のデータを Power BI に入力する
