ログの構成
Azure Cosmos DB for NoSQL SDK が "見えないところで" 実行する HTTP 要求をログしたいことがよくあります。この SDK には、カスタム ハンドラーを HTTP の要求と応答に簡単に挿入できる便利なクライアント ビルダー クラスが含まれています。 この機能を利用して、単純なログ記録メカニズムを構築できます。
クライアント ビルダー
Microsoft.Azure.Cosmos.Fluent.CosmosClientBuilder クラスは、新しいクライアント インスタンスをスムーズに構成するビルダー クラスです。 CosmosClientOptions クラスの代わりに使用される複数のメソッド含まれていますが、これだけに限られません。
方法 | 説明 |
---|---|
WithApplicationRegion または WithApplicationPreferredRegions | 優先リージョンを構成します |
WithConnectionModeDirect と WithConnectionModeGateway | 接続モードを設定します。 |
WithConsistencyLevel | 整合性レベルをオーバーライドします。 |
ビルダーを使用するには、まず using ディレクティブを Microsoft.Azure.Cosmos.Fluent 名前空間に追加する必要があります。
using Microsoft.Azure.Cosmos.Fluent;
これで、接続文字列またはエンドポイントとキーのペアをコンストラクター パラメーターとして渡す CosmosClientBuilder クラスの新しいインスタンスを作成できます。
CosmosClientBuilder builder = new (connectionString);
CosmosClientBuilder builder = new (endpoint, key);
この時点で、任意の Fluent メソッドを追加してクライアントを構成できます。 Fluent メソッドを実行したら、Build メソッドを呼び出して、CosmosClient 型のインスタンスを作成できます。
CosmosClient client = builder.Build();
カスタム ログ ハンドラーを作成する
HTTP 要求をログに記録するには、抽象 RequestHandler クラスから継承する新しいクラスを作成する必要があります。 ハンドラーでは、HTTP 要求の送信前と送信後にロジックを追加できます。 この例では、HTTP 要求の送信時に次のワークフローを実行するハンドラーを作成します。
- 元の要求の HTTP メソッドと URI をコンソールに書き込む
- 基本の実装に要求を送信し、応答を変数に格納する
- HTTP 状態コード番号と説明をコンソールに書き込む
- 応答を返す
カスタム RequestHandler 実装を作成する
これを実装するには、RequestHandler から継承する新しいクラスを作成する必要があります。
public class LogHandler : RequestHandler
{
}
抽象クラスには、要求に関する新しいロジックを挿入するためにオーバーライドする必要がある SendAsync メソッドが含まれています。
public override async Task<ResponseMessage> SendAsync(RequestMessage request, CancellationToken cancellationToken)
{
}
SendAsync メソッド内では、RequestMessageパラメーターの RequestUri および Methodプロパティがコンソールに出力されます。 次に、基本メソッド SendAsync が呼び出され、実際の要求が送信され、応答がローカル変数に格納されます。
Console.WriteLine($"[{request.Method.Method}]\t{request.RequestUri}");
ResponseMessage response = await base.SendAsync(request, cancellationToken);
応答がローカル変数に格納されると、応答の StatusCode が数値および文字列形式の両方で出力されます。 その後、非同期メソッドの結果として応答が返されます。
Console.WriteLine($"[{Convert.ToInt32(response.StatusCode)}]\t{response.StatusCode}");
return response;
このクラスのコード全体を次に示します。
public class LogHandler : RequestHandler
{
public override async Task<ResponseMessage> SendAsync(RequestMessage request, CancellationToken cancellationToken)
{
Console.WriteLine($"[{request.Method.Method}]\t{request.RequestUri}");
ResponseMessage response = await base.SendAsync(request, cancellationToken);
Console.WriteLine($"[{Convert.ToInt32(response.StatusCode)}]\t{response.StatusCode}");
return response;
}
}
クライアント ビルダーでカスタム RequestHandler 実装を使用する
要求ハンドラーの実装の準備ができたら、カスタム要求ハンドラーの新しいインスタンスを渡すCosmosClientBuilder インスタンスのAddCustomHandler メソッドを呼び出します。
builder.AddCustomHandlers(new LogHandler());
ビルダーを使用してクライアントを完全に作成するコードを次に示します。
CosmosClientBuilder builder = new (endpoint, key);
builder.AddCustomHandlers(new LogHandler());
CosmosClient client = builder.Build();
カスタム ロガーをテストする
クライアント インスタンスを使用して CreateDatabaseIfNotExistsAsync メソッドを呼び出す架空のシナリオを想定します。 クライアント インスタンスでは、最初にデータベースの存在を確認する必要があります。データベースが見つからない場合は、指定した名前を使用して新しいデータベースが作成されます。
この架空のシナリオでは、このコード行の例を使用して、CreateDatabaseIfNotExistsAsync メソッドを呼び出します。
Database result = await client.CreateDatabaseIfNotExistsAsync("cosmicworks");
アプリケーションを初めて実行すると、次のアクションを実行したことがロガーで出力されます。
dbs/<database-name>
エンドポイントで特定のデータベースに対してクエリを実行する HTTP GET要求を送信しました。- データベースが見つからなかったことを示す 404 の応答を受信しました。
- データベースの詳細が要求の本文に含まれる HTTP POST要求を
dbs/
エンドポイントに送信しました。 - データベースの詳細が応答の本文含まれるデータベースが作成されたことを示す 201 の応答を受信しました。
[GET] dbs/cosmicworks
[404] NotFound
[POST] dbs/
[201] Created
アプリケーションを再度実行した場合、はるかに短いワークフローがロガーで出力されます。
dbs/<database-name>
エンドポイントで特定のデータベースに対してクエリを実行する HTTP GET要求を送信しました。- データベースの詳細が応答の本文含まれるデータベースが見つかったことを示す 200 の応答を受信しました。
[GET] dbs/cosmicworks
[200] OK