ASP.NET Core に Application Insights を組み込んでいるのに、ILogger のログが Warning だけ届いて Information が見えない――この症状は、ほとんどの場合「ログレベル設定」「Application Insights ロギングプロバイダーのフィルター」「環境変数や Key Vault による上書き」のどれかに原因があります。送信経路を分解しながら、再現しやすい落とし穴と、最短で直す手順を具体例付きで解説します。
まず押さえる:ILogger のログが Application Insights に届くまでの流れ
「コンソールには Information が出ているのに、Application Insights には Warning しか来ない」場合、同じ ILogger でも出力先(プロバイダー)ごとにフィルターが別であることが原因になりやすいです。つまり、Console には Information を許可していても、Application Insights(AI)向けには Warning 以上しか許可していない、という状態が普通に起こります。
| 段階 | どこで落ちる? | Warning だけになる典型 | 確認ポイント |
|---|---|---|---|
| アプリ内 | ILogger のフィルター(構成・AddFilter) | AI プロバイダーだけ最小レベルが Warning | Logging:ApplicationInsights:LogLevel / AddFilter の有無 |
| SDK | TelemetryProcessor / Sampling | Information が間引かれて「ほぼ見えない」 | Adaptive Sampling の設定、カスタム Processor |
| ポータル | 画面のフィルター / 参照先の違い | Search/Live Metrics では見えない(Logs ではある) | Logs(Kusto)で traces を直接確認 |
| 設定供給 | appsettings と環境変数/Key Vault の優先順位 | JSON を直しても実行時は Warning に戻る | 実行時の構成値を出力して“最終値”を確認 |
この記事では、上の表の順に「疑う場所」を狭めていきます。特に最初の2つ(ログレベル設定とフィルター)が原因の大半です。
本当に Information が届いていないかを最初に確定する
Azure ポータルの見た目(Search や Live Metrics)だけで判断すると、実は届いていたのに見落としていることがあります。まずは Logs(Analytics)で traces テーブルを直接確認して、現実を確定させます。
Application Insights リソースの「Logs(ログ)」で、次のクエリを実行してください。
traces
| summarize count() by severityLevel
| order by severityLevel asc
ここで severityLevel が 2(Warning)しか出ていないなら「送信前に落ちている」可能性が高いです。逆に severityLevel 0/1(Verbose/Information)が出ているなら、AI 側は受け取っていて、画面のフィルターや検索条件で見えていないだけのケースです。
次に、直近のログを並べて確認します。
traces
| project timestamp, severityLevel, message, operation_Id, cloud_RoleName, customDimensions
| order by timestamp desc
| take 50
この時点で「Information が無い」と確定したら、次のセクションへ進みます。
原因になりやすい:Application Insights 向け LogLevel が Warning になっている
ASP.NET Core のログ設定は、大きく分けて次の2層があります。
- 全体の LogLevel(Logging:LogLevel):すべてのプロバイダーの基準になりやすい
- プロバイダー別 LogLevel(Logging:ApplicationInsights:LogLevel など):出力先ごとに上書きできる
「コンソールは Information が出る」という事実は、Console プロバイダーのフィルターは Information を許可していることを意味します。しかし Application Insights プロバイダー側だけが Warning 以上になっていれば、AI には Warning しか届きません。
appsettings.json の基本形(AI も Information にする)
まずは JSON 側で、AI 向けと全体の両方を Information に揃えてください。
{
"Logging": {
"ApplicationInsights": {
"LogLevel": {
"Default": "Information"
}
},
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}
ポイントは次の通りです。
- Logging:ApplicationInsights:LogLevel:Default が Warning だと、AI は Warning 以上しか送らない
- カテゴリ別(Microsoft など)の設定は想定外に効くので、まずは「Default を揃える」
- 最終的にノイズが多いなら、Microsoft 系だけ Warningにするのは現実的(上の例)
環境変数で上書きされるキーの例(見落としがち)
appsettings.json を直しても直らない場合、環境変数(または Key Vault / App Service 設定)で Warning が強制されていることがとても多いです。ASP.NET Core の環境変数は「:(コロン)」が「__(ダブルアンダースコア)」に置き換わります。
| 設定キー(JSON) | 環境変数名 | この値が Warning だと… |
|---|---|---|
| Logging:LogLevel:Default | Logging__LogLevel__Default | 全体が Warning 以上になりやすい |
| Logging:ApplicationInsights:LogLevel:Default | Logging__ApplicationInsights__LogLevel__Default | AI だけ Warning 以上になりやすい |
| Logging:LogLevel:Microsoft | Logging__LogLevel__Microsoft | Microsoft 系カテゴリが抑制される |
| Logging:ApplicationInsights:LogLevel:Microsoft | Logging__ApplicationInsights__LogLevel__Microsoft | AI 上で Microsoft 系だけ強く抑制される |
特に Azure App Service やコンテナ環境では、運用都合でこの環境変数がセットされていることがあります。設定が分散している現場ほど、まずここを疑うのが近道です。
実行時の“最終値”を表示して、上書きの有無を一発で見抜く
appsettings.json は「書いた値」ですが、あなたが知りたいのは「実際にアプリが使っている最終値」です。起動時に一度だけ、次のキーをログに出して確認します(値自体は秘密情報ではないので、出しても安全なことが多いです)。
// 起動直後(builder.Build() 前後)などで確認用に出す例
var aiLevel = builder.Configuration["Logging:ApplicationInsights:LogLevel:Default"];
var globalLevel = builder.Configuration["Logging:LogLevel:Default"];
Console.WriteLine($"Logging:ApplicationInsights:LogLevel:Default = {aiLevel}");
Console.WriteLine($"Logging:LogLevel:Default = {globalLevel}");
ここで aiLevel が Warning になっていたら、JSON ではなく 上書き元(環境変数、Key Vault、App Service 設定、コンテナの ConfigMap/Secret 等)が原因です。
さらに深掘りしたい場合は、カテゴリ別も併せて出します。
var msAiLevel = builder.Configuration["Logging:ApplicationInsights:LogLevel:Microsoft"];
var msGlobalLevel = builder.Configuration["Logging:LogLevel:Microsoft"];
Console.WriteLine($"Logging:ApplicationInsights:LogLevel:Microsoft = {msAiLevel}");
Console.WriteLine($"Logging:LogLevel:Microsoft = {msGlobalLevel}");
Program.cs 側の落とし穴:AI ロギングプロバイダーとフィルターの設定
Application Insights には大きく2種類の導入があります。
- テレメトリ(Request/Dependency/Exception など):AddApplicationInsightsTelemetry()
- ILogger のログ(TraceTelemetry):Application Insights ロギングプロバイダー(AddApplicationInsights など)
「AddApplicationInsightsTelemetry() は入れているのに ILogger の挙動が期待と違う」場合、ログ用プロバイダーの追加やフィルターが原因になりがちです。
最小構成の例:AI に Information 以上を送る
以下は概念的に「これで揃う」構成です(.NET 6+ の最小ホスティングを想定)。プロジェクトの構成に合わせて調整してください。
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.ApplicationInsights;
var builder = WebApplication.CreateBuilder(args);
// テレメトリ(Request/Dependency など)
builder.Services.AddApplicationInsightsTelemetry(options =>
{
// 推奨:接続文字列を使う(環境変数や Key Vault から供給される想定)
options.ConnectionString = builder.Configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"];
});
// ILogger -> Application Insights(TraceTelemetry)
builder.Logging.AddApplicationInsights();
// 重要:AI プロバイダーに対して Information を許可
builder.Logging.AddFilter<ApplicationInsightsLoggerProvider>("", LogLevel.Information);
// ノイズが多い Microsoft 系は AI でも Warning 以上(任意)
builder.Logging.AddFilter<ApplicationInsightsLoggerProvider>("Microsoft", LogLevel.Warning);
var app = builder.Build();
app.Run();
もし AddApplicationInsights() が見つからない場合は、参照パッケージや using が足りない可能性があります。Application Insights SDK とロギング拡張がプロジェクトに入っているかを確認してください(テンプレートやバージョンで差が出やすい部分です)。
ClearProviders を使っている場合は要注意
次のようなコードがあると、プロバイダー構成が変わり、意図しないフィルターになったり、設定の読み込み順が変わったりします。
// 例:プロバイダーを全消ししてから追加している
builder.Logging.ClearProviders();
builder.Logging.AddConsole();
builder.Logging.AddApplicationInsights();
ClearProviders 自体が悪いわけではありませんが、「設定ファイル側で制御するつもりだったのに、コード側の AddFilter が勝っていた」などの混乱が起きやすいです。トラブルシュート中は、いったん appsettings と Program.cs の両方で “Information を許可” して、どちらが原因か切り分けるのが安全です。
Key Vault / 環境変数が設定を上書きしているときの典型パターン
「設定は Key Vault と環境変数から読み込んでいる」と書かれている通り、この構成だと appsettings.json を直しても効果がないことがあります。理由はシンプルで、実行時の構成は “後から入ったプロバイダー” が勝つことが多いからです。
特に Key Vault を構成として読み込む場合、キー名は次のような形になりがちです(実装や命名規則により異なりますが、よくあるパターンです)。
- Logging–ApplicationInsights–LogLevel–Default
- Logging–LogLevel–Default
- Logging–ApplicationInsights–LogLevel–Microsoft
上記のどれかが Warning になっていると、AI 側だけ Warningの挙動になります。運用中に「コスト対策」で誰かが設定を変えていた、というケースも珍しくありません。
上書きの場所を推測するコツ
次のような状況が揃うと、上書きがほぼ確定です。
- ローカル実行では Information が届く
- 本番(App Service / コンテナ / AKS)では Warning だけ届く
- appsettings.Production.json を直しても変化がない
この場合、アプリのコードよりも ホスティング環境の設定(App Service のアプリ設定、コンテナ環境変数、Key Vault のシークレット) を見に行くのが最短です。
Adaptive Sampling で Information が「ほとんど見えない」状態になることがある
ログレベル設定が正しいのに Information が極端に少ない場合、Adaptive Sampling(自動サンプリング)が影響している可能性があります。これは「大量のテレメトリを自動で間引いて、コストと負荷を抑える」仕組みで、トラフィックが多い環境だと 低優先度の traces がほぼ残らない見え方になることがあります。
切り分けのために、デバッグ期間だけサンプリングを無効化して挙動を見ます。
builder.Services.AddApplicationInsightsTelemetry(options =>
{
options.ConnectionString = builder.Configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"];
options.EnableAdaptiveSampling = false; // 切り分け中だけ推奨
});
ここで Information が見えるようになったら、原因はサンプリングです。恒久対策としては次の方向性があります。
- ログを減らす(カテゴリやメッセージの見直し)
- AI 側に送るログレベルを環境別に調整(本番は Warning、検証は Information など)
- サンプリングの方針を調整(プロセッサ構成の見直し)
なお、カスタムの TelemetryProcessor を導入している場合は、その処理内で severityLevel 1 を除外していないかも確認してください。チーム内で「ノイズ削減」のために追加して、後から忘れられていることがよくあります。
「送られているのに見えない」系の勘違いも潰しておく
Application Insights で ILogger の Information を探すとき、見ている場所が違うと「無い」と錯覚しがちです。
- ILogger のログは基本的に traces テーブルへ入ります
- 例外(Exception)は exceptions に入ることがあります(設定や呼び方による)
- Search 画面は便利ですが、フィルターや表示対象の都合で見落としやすいです
- Live Metrics は「リアルタイム監視」向けで、すべての traces を網羅する画面ではありません
迷ったら、まず Logs で traces を叩く。これが一番確実です。
最短で直すチェックリスト(現場向け手順)
手戻りを減らすために、「疑う順番」を固定します。
- Logs(Analytics)で traces を確認し、Information が本当に無いか確定する
- 実行時の構成値(Logging:ApplicationInsights:LogLevel:Default 等)を出力して、最終値が Warning になっていないか確認する
- appsettings.json / appsettings.{Environment}.json で AI 向け LogLevel が Information になっているか確認する
- 環境変数 / App Service 設定 / Key Vault で同キーが Warning に上書きされていないか確認する
- Program.cs の AddFilter が AI プロバイダーに対して Warning 以上を強制していないか確認する
- トラフィックが多い場合は Adaptive Sampling を一時的に無効化して差分を確認する
- カスタム TelemetryProcessor / サードパーティのロガー(Serilog 等)を使っているなら、そこにフィルターがないか確認する
“直った状態”のテンプレ:設定ファイルと Program.cs を揃える
トラブルシュート中は「設定とコードで二重に担保」すると、原因の切り分けが速くなります。まずは AI に Information を出せる状態を作り、最後に好みのレベルへ落とすのが安全です。
appsettings.json(AI も Information、Microsoft は Warning)
{
"Logging": {
"ApplicationInsights": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning"
}
},
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}
Program.cs(AI フィルターを明示)
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.ApplicationInsights;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddApplicationInsightsTelemetry(options =>
{
options.ConnectionString = builder.Configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"];
});
builder.Logging.AddApplicationInsights();
// ここで AI の最小レベルを担保(設定が崩れても“最後の砦”になる)
builder.Logging.AddFilter("", LogLevel.Information);
builder.Logging.AddFilter("Microsoft", LogLevel.Warning);
var app = builder.Build();
app.MapGet("/", (ILogger logger) =>
{
logger.LogInformation("Information のテストログ");
logger.LogWarning("Warning のテストログ");
return "ok";
});
app.Run();
この状態で AI 側の traces を見ると、Information と Warning の両方が出るはずです。出ない場合は、ほぼ確実に 環境側の上書きか プロセッサ/サンプリングです。
運用まで見据えたログレベル設計(Information を出しつつ破綻しない)
Information を出すこと自体は正しいのですが、何でもかんでも送るとノイズとコストが増えます。おすすめは「アプリ自作カテゴリは Information、フレームワークは Warning」という分離です。
| カテゴリ | 推奨レベル | 狙い | 例 |
|---|---|---|---|
| 自分のアプリ(MyApp.*) | Information | 業務ログ・重要イベントを拾う | 注文確定、外部API呼び出し結果、処理時間 |
| Microsoft / System | Warning | フレームワークのノイズを抑制 | HTTP パイプラインの詳細ログなど |
| Microsoft.Hosting.Lifetime | Information | 起動/停止ログは残す | Listening on / Application started |
この設計にすると「AI に Information を送っても、必要以上に爆発しない」状態を作りやすいです。
よくある質問
Serilog や NLog を使っている場合でも同じ?
結論は「同じ現象が起きます」。ただし原因箇所が増えます。Serilog/NLog の場合は、ASP.NET Core の Logging 設定とは別に、シンク(Application Insights への出力先)の最小レベルやフィルターが存在することがあります。まずは「組み込み ILogger + AI プロバイダー」で Information が出る状態を作ってから、Serilog/NLog 側へ戻すと切り分けが速いです。
本番だけ Information を落としたい(コストが心配)
現実的な落としどころは次のどれかです。
- 本番は Logging:ApplicationInsights:LogLevel:Default=Warning にして、検証/ステージングだけ Information
- 本番でもアプリ独自カテゴリだけ Information(MyApp は Information、Microsoft は Warning)
- 大量イベントはメトリクス化(カウンタや所要時間)して、ログは要点に絞る
Information を送っているはずなのに、特定の時間帯だけ消える
トラフィック増加と同時に起きるなら、Adaptive Sampling の影響が濃厚です。まずは一時的に無効化して差分を確認し、原因確定後にログ量やサンプリング方針を調整してください。
まとめ:Warning だけ届くときは「AI 側の最小レベル」と「上書き元」を疑う
Application Insights に Warning しか届かない問題は、難しく見えても原因はかなりパターン化されています。最初に Logs(Analytics)で traces を確定し、次に実行時の構成値で「AI 向け LogLevel が最終的に何になっているか」を見れば、ほぼ一直線で解決できます。設定ファイル、Program.cs の AddFilter、環境変数/Key Vault の上書き、サンプリングの順に潰していきましょう。

コメント