Application Insights の Python SDK は 本記事でご紹介している OpenCensus 版は2024年9月のリタイアが発表されており、OpenTelemetry 版への移行が推奨されています。
OpenTelemetry 版の使い方については、こちらの記事をご参照ください。
本記事について
本記事では、Azure Container Apps でのログ監視のアーキテクチャや取りうる方法の選択肢を見ていきます。Container Apps のログと一言で言っても、コンテナーのログやシステムのログ、アプリケーションのログなどがあります。また、サービス側の登場人物としては、Azure Log Analytics, Azure Application Insights, Azure Monitor になります。それぞれ、どのレイヤー (Container Apps 環境、Container Apps, アプリケーションコード) で実装が必要になるか、を見ていきます。
Azure Container Apps でのログ監視の全体像
Azure Container Apps でのアプリとログ収集サービスの概略をまとめると以下の図のようになります。
まず、Container Apps 環境では作成時にひとつの Log Analytics ワークスペースを指定します。これにより、Container Apps 環境上の各 Container Apps のコンソールログとシステムログが集約されます。もしアプリケーションからコンソールにログが吐き出されるように設定される場合、そのまま Log Analytics ワークスペースでコンソールログとしてそのログが検索できるようになります。ただし、コンソールログの場合は、コンソールに吐き出されたすべてのログデータをそのまま取り込むことになります。
一方で、Application Insights を利用する方法もあります。Application Insights では単なるログ収集に加え、分散トレーシングや可用性テスト、メトリックの解析なども行えます。もし、アプリケーションからのログ送信をより詳細にコントロールしたい場合や、Application Insights の別機能も併せて監視に利用したい場合は、Application Insights の利用がおすすめです。Container Apps で Application Insights を利用したい場合には、SDK を利用してコードにインストルメンテーションする必要があります。
また、もし Dapr を Container Apps で利用している場合は、Dapr の分散トレーシングのテレメトリーを Dapr から Application Insights に吐き出すことができます。これを利用すると、Dapr のサイドカーコンテナーからどこに通信されているかを、コードの修正なしで簡単にとらえることができます。
実装手順
ここからは、実際にどう設定を行えば、どのようなログが収集できるかを見ていきます。3 パターン ( ① Container Apps から Log Analytics への転送、② Application Insights への SDK を使った転送、③ Dapr から Application Insights への転送)それぞれで確認していきます。
1. Container Apps からのコンソールログ・システムログの Log Analytics ワークスペースへの送信 (Container Apps 環境での設定)
2023年6月現在、Container Apps からコンソールログ・システムログの Log Analytics ワークスペースへの送信には、下記の2つのオプションがあります。
Option 1. Log Analytics ワークスペースの設定
Azure ログ分析を選んだ場合には、Log Analytics ワークスペースを指定するだけです。これでワークスペースへログが送信されます。
Option 2. (Preview) Azure Monitor の設定
Azure Monitor を選んだ場合は、詳細な設定は後から行います。
Container Apps 環境の作成後、診断設定より Log Analytics ワークスペースを設定します。こちらの設定の場合は取得するログを選択できたり、複数のワークスペースへのログ送信ができたり、ストレージアカウントや Event Hubs といった別リソースへログが転送できたり、といったメリットがあります。
コンソールログとシステムログの確認
コンソールログは、Log Analytics の ContainerAppConsoleLogs テーブルに格納されます。例えば、下記のクエリは、コンソールログで直近一時間のものを取り出して、時間順に並べています。(project 句で、特定の列だけ表示しています。)
ContainerAppConsoleLogs | where TimeGenerated > ago(1h) | sort by TimeGenerated desc
| project TimeGenerated, ContainerAppName, Stream, Log
こちらはコンソールログなので、アプリケーションから吐き出されたログ以外のレコードも多く入っていることがわかります。アプリケーションからのログのみを取り出したい場合は、次の Application Insights を利用します。
一方、システムログは ContainerAppSystemLogs テーブルに入ってきます。こちらはコンテナーの起動や停止、リビジョンの更新、プローブなどのログを記録しています。
同じくクエリ例になります。
ContainerAppSystemLogs | where TimeGenerated > ago(1h) | sort by TimeGenerated desc
| project TimeGenerated, ContainerAppName, Type, Log, Reason, EventSource
2. Container Apps 上の各コンテナー化されたアプリから Application Insights へのログ送信
これは、Container Apps 上のアプリに限らず、SDK を使ってアプリケーションから Application Insights にログを送信する方法になります。本記事では、Python のアプリを例に、SDK 経由でのログ送信を見ていきます。
SDK の設定とコーディング
基本的には、下記の公式ドキュメントの記載の通りに実装すれば、ログが Application Insights の trace テーブルに格納されます。
ざっくりだけ抽出すると、pip install で下記のモジュールをインストールし、logger を下記のようにセットすると簡単にテストができます。(接続文字列は実際には、別の方法を使って保存・取得してください。)
pip install opencensus-ext-azure opencensus-ext-fastapi
import logging
from opencensus.ext.azure.log_exporter import AzureLogHandler
from opencensus.ext.fastapi.fastapi_middleware import FastAPIMiddleware
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
logger.addHandler(AzureLogHandler(connection_string="<Application Insights の接続文字列>"))
logger.info("出力したい内容")
Application Insights に格納されたログの確認
Application Insights 側では、traces テーブル (Log Analytics では AppTraces テーブル) に格納されています。
たとえば、直近1時間以内のログを抽出し、時間順に並べ替えるには、下記のようなクエリを実行します。
traces | where timestamp > ago(1h) | sort by timestamp desc
*補足 - ログファイルに書き出されたものを Log Analytics に送信したい場合
ログファイルがすでにあり、その内容ごと、Log Analytics に送信したいというニーズもあるかもしれません。その場合は、Log Analytics の Log Ingest API (Python SDK) を利用してください。詳細については、下記の記事をご参照ください。
3. Dapr (on Container Apps 環境) から Application Insights へのテレメトリーの送信
2023年6月現在、Dapr から直接分散トレーシングのテレメトリーを Application Insights へ送るには、Container Apps 環境の作成時に、送り先の Application Insights を指定しておく必要があります。これだけ行っていれば、あとは Container Apps 環境上のアプリが Dapr を経由して通信を行うと、自動的にテレメトリーを収集し、Application Insights で分析ができるようになります。
CLI コマンドによる Container Apps 環境作成とその設定
この設定を行うには、CLI コマンドにて Container Apps 環境を作成します。コマンドは以下になります。(その他のオプションは任意で追加してください。)
az containerapp env create \
--name <環境名> \
--resource-group <リソースグループ名> \
--location <リージョン名> \
--dapr-instrumentation-key <利用する Application Insights のインストルメンテーションキー>
この Container Apps 環境の上に、Container Apps を作ります。その際に、すべての Container Apps 上で、Dapr を有効化しておきます。現在は、Azure Portal 上で簡単に有効化ができます。
Dapr が有効化されると、コンテナーアプリで Dapr のサイドカーコンテナーが動き始めます。レプリカやログストリームでも確認ができます。
Python のアプリケーションコード側では、Dapr を使うようにします。たとえば、request モジュールのメソッドの場合は、headers に Dapr の App ID を追加し、URL を Localhost に変更します。(Dapr のデフォルトのポートは3500ですが、変更も可能です。)
headers = {'dapr-app-id': '<呼び出し先のアプリの Dapr App ID>'}
response = requests.get(url="http://localhost:3500/<path>", headers=headers)
Application Insights でのアプリケーションマップとログの確認
アプリ間の呼び出しが、Dapr 経由で正常に行われると、自動的に Application Insights のアプリケーションマップに通信状況が可視化されます。
ログとしては、Application Insights の requests や dependencies のテーブルに格納されています。
最後に
*本稿は、個人の見解に基づいた内容であり、所属する会社の公式見解ではありません。また、いかなる保証を与えるものでもありません。正式な情報は、各製品の販売元にご確認ください。