LoginSignup
3
2

More than 3 years have passed since last update.

Bot Builder v4 : Application Insights を駆使した利用状況分析

Last updated at Posted at 2019-06-11

*2019/7/27 Web からダウンロードできるサンプルが変わっていたため、こちらの記事もアップデートします。

前回は Bot Connector のボット利用状況分析を紹介しましたが、今回から、より詳細な利用状況を分析するために、Application Insights を駆使する方法を紹介します。

参考: Telemetry Logging

今回は「基本ボット (C#)」で動作をためしました。事前に Bot Web App を作成してソースをダウンロードしてください。

ApplicationInsights の組み込み

NuGet パッケージとして公開されている Microsoft.Bot.Builder.Integration.ApplicationInsights.Core を使ってボットに Application Insights を組み込みます。

1. プロジェクトの NuGet パッケージ管理より、Microsoft.Bot.Builder.Integration.ApplicationInsights.Core を追加。
image.png

2. Startup.cs の ConfigureServices メソッドで、ダイアログやボットを追加する前に以下コードを追加。また Configuration プロパティが規定で存在しないため、プロパティとしても追加。

startup.cs
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
    Configuration = configuration;
}

public void ConfigureServices(IServiceCollection services)
{
    ...
    // Add Application Insights 
    services.AddBotApplicationInsights(Configuration);
    ...
}

3. appsettings.json に ApplicationInsights の項目を追加。自身のキーを指定。

appsettings.json
{
  ...
  "ApplicationInsights": {
    "InstrumentationKey": "2953fafa-ed74-431b-a25c-93ab2fda29ef" 
  }
}

以上で Application Insights の設定は完了です。

AddBotApplicationInsights で何をしているか

AddBotApplicationInsights は他のパターンの引数を取ることもできます。

GitHub: AddBotApplicationInsights

メソッドを見てわかる通り、IBotTelemetryClient を IoC に登録しています。

public static IServiceCollection AddBotApplicationInsights(this IServiceCollection services, IConfiguration config)
{
    if (config == null)
    {
        throw new ArgumentNullException(nameof(config));
    }

    string instrumentationKey = config.GetValue<string>("ApplicationInsights:instrumentationKey");

    CreateBotTelemetry(services);

    IBotTelemetryClient telemetryClient = null;
    if (!string.IsNullOrWhiteSpace(instrumentationKey))
    {
        services.AddApplicationInsightsTelemetry(instrumentationKey);
        telemetryClient = new BotTelemetryClient(new TelemetryClient());
    }
    else
    {
        telemetryClient = NullBotTelemetryClient.Instance;
    }

    services.AddSingleton(telemetryClient);

    return services;
}

また他のミドルウェアやイニシャライザーも登録。これらのコードでユーザーから受けた情報を加工して Application Insights に渡すデータを作っています。


        private static void CreateBotTelemetry(IServiceCollection services)
        {
            // Enables Bot Telemetry to save user/session id's as the bot user id and session
            services.AddTransient<TelemetrySaveBodyASPMiddleware>();
            services.AddSingleton<ITelemetryInitializer, OperationCorrelationTelemetryInitializer>();
            services.AddSingleton<ITelemetryInitializer, TelemetryBotIdInitializer>();
        }

ただここのコードを見てわかるとおり、これだけでは Application Insights に対して情報を送るコードはありません。

LUIS の結果を Application Insights に送る

サンプルでは LUIS のクエリ結果を取るために LuisRecognizer を使いますが、引数に TelemetryClient を渡すことで解析できるようになります。

1. FlightBookingRecognizer.cs で TelemetryClient を使うように変更。

  • コンストラクタで IBotTelemetryClient を受け取る
  • LuisRecognizer にオプションとして BotTelemetryClient を渡す
LuisHelper.cs
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.AI.Luis;
using Microsoft.Extensions.Configuration;

namespace Microsoft.BotBuilderSamples
{
    public class FlightBookingRecognizer : IRecognizer
    {
        private readonly LuisRecognizer _recognizer;

        public FlightBookingRecognizer(IConfiguration configuration, IBotTelemetryClient telemetryClient)
        {
            var luisIsConfigured = !string.IsNullOrEmpty(configuration["LuisAppId"]) && !string.IsNullOrEmpty(configuration["LuisAPIKey"]) && !string.IsNullOrEmpty(configuration["LuisAPIHostName"]);
            if (luisIsConfigured)
            {
                var luisApplication = new LuisApplication(
                    configuration["LuisAppId"],
                    configuration["LuisAPIKey"],
                    "https://" + configuration["LuisAPIHostName"]);
                // LuisRecognizer を作成する際、TelemetryClient を指定。
                _recognizer = new LuisRecognizer(luisApplication, new LuisPredictionOptions() { TelemetryClient = telemetryClient });                
            }
        }

        // Returns true if luis is configured in the appsettings.json and initialized.
        public virtual bool IsConfigured => _recognizer != null;

        public virtual async Task<RecognizerResult> RecognizeAsync(ITurnContext turnContext, CancellationToken cancellationToken)
            => await _recognizer.RecognizeAsync(turnContext, cancellationToken);

        public virtual async Task<T> RecognizeAsync<T>(ITurnContext turnContext, CancellationToken cancellationToken)
            where T : IRecognizerConvert, new()
            => await _recognizer.RecognizeAsync<T>(turnContext, cancellationToken);
    }
}

2. Dialog を実行している DialogBot.cs で渡された Dialog に対して TelemetryClient を設定。

  • コンストラクタで IBotTelemetryClient を受け取る
DialogBot.cs_コンストラクタ
public DialogBot(ConversationState conversationState, UserState userState, T dialog, ILogger<DialogBot<T>> logger, IBotTelemetryClient telemetryClient)
{
    ConversationState = conversationState;
    UserState = userState;
    Dialog = dialog;
    Logger = logger;
    dialog.TelemetryClient = telemetryClient;
}

3. DialogBot を継承している DialogAndWelcomeBot.cs でも同様にコンストラクタに設定。

DialogAndWelcomeBot.cs
public DialogAndWelcomeBot(ConversationState conversationState, UserState userState, T dialog, ILogger<DialogBot<T>> logger, IBotTelemetryClient telemetryClient)
    : base(conversationState, userState, dialog, logger, telemetryClient)
{
}

※以前のサンプルに含まれていた DialogExtension.cs は v4.4 からライブラリに統合されました。
GitHub: DialogExtensions

LuisRecognizer でのロギング

LuisRecognizerITelemetryRecognizer を継承し、TelemetryClient.TrackEvent にて自然言語処理の解析結果を Application Insights に保存しています。

結果の解析

結果は Application Insights をクエリすればすぐに分かります。

1. Azure Portal からログ先の Application Insights を開き、「分析」をクリック。
image.png

2. GitHub: Application Insights Analytics にあるクエリを実行。

customEvents
| where timestamp >= ago(24h)
| where name startswith "LuisResult"
| extend intent = tostring(customDimensions.['intent'])
| summarize count() by intent
| order by count_ desc
| render piechart

3. 結果を確認。
image.png

TelemetryLoggerMiddleware

ユーザーからのメッセージ受信時や送信時にログするためには、TelemetryLoggerMiddleware ミドルウェアを使います。

1. AdapterWithErrorHandler.cs に TelemetryLoggerMiddleware を追加

  • IBotTelemetryClient をコンストラクタで受け取る
  • Use を使ってミドルウェアを追加
AdapterWithErrorHandler.cs
using System;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.Integration.AspNet.Core;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace Microsoft.BotBuilderSamples
{
    public class AdapterWithErrorHandler : BotFrameworkHttpAdapter
    {
        public AdapterWithErrorHandler(IConfiguration configuration, ILogger<BotFrameworkHttpAdapter> logger, IBotTelemetryClient telemetryClient, ConversationState conversationState = null)
            : base(configuration, logger)
        {
            OnTurnError = async (turnContext, exception) =>
            {
                ...
            };

            Use(new TelemetryLoggerMiddleware(telemetryClient));
        }
    }
}

2. ボットを利用

結果の解析

1. 分析で以下のクエリを実行。以下はイベント毎の解析。

customEvents
| where timestamp >= ago(24h)
| where name startswith "BotMessage"
| summarize count() by name, bin(timestamp, 10m)
| render timechart

2. 結果を確認。
image.png

3. チャネル毎の場合

customEvents
| where timestamp >= ago(1d)
| where name startswith "BotMessage"
| extend channelId = tostring(customDimensions.['channelId'])
| summarize count() by channelId, bin(timestamp, 10m)
| render timechart

4. 結果を確認。
image.png

その他のロギング

GitHub: telemetrylogging にもある通り、Custom Events として各種イベントが取得できます。

  • 外部依存サービスのトラック
  • ウォーターフォールダイアログの実行状況

クエリは GitHub: applicationinsights を参照してください。

まとめ

Application Insights を統合することで詳細が確認できるようになり、より詳しく利用状況が見えるようになりました。次回は Power BI でその状況を見てみます。

次の記事
目次に戻る

サンプルコード

3
2
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2