今回は Azure の Table Storage に、チャットボットの会話のやり取りをロギングする方法を整理します。
前回は、ログ出力の重要な要素、IActivityLogger
インターフェースについて概要を整理しました。それを応用して…と言いたいところですが、Nuget で用意されているライブラリを使うだけで簡単に実現できます。
https://www.nuget.org/packages/Microsoft.Bot.Builder.Azure/
Overview
Environment
- Visual Studio 2017
- .NET Framework 4.6
Azure のアカウントは必要です。そしてなんらかのリソースを作ると課金がかかる場合があるので、ご注意ください。
Table Storage の作成
リソースグループの作成
Azure のリソースグループについてざっくり説明しておきます。Azureでは、さまざまなサービスがありますのでたくさん作るとごっちゃごちゃになり、どれがどれに依存しているとかどのプロジェクトでどれを使っているかわからなくなりがちです。それを何らかの単位でグルーピングするための機能がリソースグループです。
私は、だいたいプロジェクト単位で作ります。あとで一括で削除しやすくするのが目的です。
前置きが長くなりましたが、Azure ポータル(portal.azure.com)にログインし、リソースグループのアイコンをクリックして作っていきましょう。今回は、「botbuilder-azure」という名前にしました。
そのリソースグループの中に、Storage を作ります。ここら辺は細かく操作方法は書きませんが、追加する際、検索で「blob」と入力するといい感じに Storage が検索できます。(tableだと検索出てこなかった…)
あとは適当のポチポチ作ればOKです。ちなみに、後でQueueとかも使う予定なので、Storage を作る際の項目「アカウントの種類」は、「汎用」を選択しました。
ちなみに今回の Storage のカウント名は「bot2azurestorage」にしています。
Bot.Builder.Azureを使ったアプリの作成
プロジェクトの作成
Bot のアプリケーションを作成するだけなので手順省略。 (前回のここらへんにあります)
Nuget パッケージの追加と更新
検索で「bot.builder.azure」と入力し、「Microsoft.Bot.Builder.Azure」をインストールしましょう。今回だと、バージョンは、3.2.3 になります。
そのほかのパッケージを最新にしておきましょう。恒例の「パッケージマネージャーコンソールから update-package
です(詳しくは前回)。
Table Storage へのログ出力
Bot.Builder 内の IActivityLogger
インターフェースを実装しているクラスは、ユーザーからボットがメッセージを受け取ったとき、ボットがユーザーにメッセージを送信したタイミングで保存されます。
つまり今回やることは2つ。IActivityLogger
を実装したクラスを作ってでログを出力処理を実装と、DIコンテナーへの登録です。
IActivityLogger
を実装したクラスの作成
Microsoft.Bot.Builder.Azure
の中に TableLogger
クラスが用意されていますのでこれを使います。
DIコンテナーに登録
TableLogger
を使うには、TableStorageの接続の文字列から CloudStorageAccount を作り、それから CloudTableClient をつくって TableReference を作って…というお決まりの処理が必要ですが、 TableLoggerModule
が用意されていて、すべてやってくれます。
このモジュールを、いつも通りに Global.asax.cs
に登録するだけです。
まずは RegisterDependencies()
メソッド(19行目)を簡単に解説します。
- (21行目)Azure の Storage アカウントの文字列を取得
- (22行目)StorageAccontのインスタンスを作成
- (24行目~)"MessageLog" というテーブル名を指定してDIコンテナーに登録で完了。
21行目の接続文字列の取得ですが、接続文字列は、Azure Portal のStorage アカウントの アクセス キー
を開くと、接続文字列
がありますので取ってきましょう。
(キーが見えかけてますが、すぐリソースグループごと削除するので気にしません。)
その接続文字列を、Web.config の configuration
> connectionStrings
内に、以下のように設定して取得できるようにしています。
<configuration> <connectionStrings> <add name="StorageConnectionString" connectionString="接続文字列!をAzure Portal から取ってきて張り付ける!"/> </connectionStrings>
最後に Application_Start
メソッドで、RegisterDependencies()
を呼び出します(14行目)。
動作確認
デバッグ実行
Azure Storage Explorer を使って Table の中身の確認。
MessageLog
というテーブルが作られ、2件のログが出力(ユーザー→ボットと、ボット→ユーザーへのメッセージ)されていて、想定通り動いていますね。
出力内容の確認
BotBuilder-Azure の TableLogger
がどうなっているか理解しておかないと意味がないですね。
内部実装をみるとすぐわかりますが、IActivity
の内容を出力しているだけです。ざっくりメモしておきます。
項目 | IActivity のどの値を使っているか |
---|---|
PartitionKey | channelId と conversationId をくっつけたもの |
RowKey | Timestamp の Ticks |
Timestamp | Timestamp |
Version | 3で固定 |
From | From |
Recipient | Recipient |
Activity0 | IActivity 全体をシリアル化して、圧縮した値 |
Activity0 を Azure Storage Explorer で見るとこんな感じです。
圧縮は、内部の実装を見ての通りですので、展開は適当にやればできます。
今回検証したときは、setterで展開して文字列のプロパティ(Activity
)にセットする以下のクラスを作りました。
Table Storage からデータ読み込み時に、こいつに値をぶっこんでいけばとりあえず中身が見れます。
(以下はコンソールアプリでデータを出力してみました。)