概要
「開発環境では動くのに、本番にデプロイしたら起動しない。しかもログが一行も出ていない...」
エンジニアにとって、これが最も恐ろしい状況の一つです。これを解決するのが、Serilogの 「Bootstrap Logger」 という設計です。
「卵が先か、鶏が先か」問題
なぜログが出ないという事態が起きるのでしょうか?
- ログを出すには、設定ファイル(appsettings.jsonやSecret Manager)から「どこにログを出すか」を読み取る必要がある。
- しかし、その設定ファイルを読み込んでいる最中にエラーが起きると、ロガーがまだ準備できていないため、エラー内容をどこにも出力できない。
これが「起動失敗の原因が闇に葬られる」仕組みです。
解決策:Bootstrap Logger(二段階起動)
この問題を解決するために、ロガーを二段階で立ち上げます。
ステップ1:暫定ロガー(Bootstrap)の起動
アプリの本当の1行目で、設定ファイルを読まずに動く「とりあえずコンソールに出すだけ」のシンプルなロガーを立ち上げます。
ステップ2:設定の読み込み
この暫定ロガーが見守る中で、Secret Managerなどの設定を読み込みます。もしここで失敗しても、暫定ロガーがコンソールに理由を書き残してくれます。
ステップ3:本番ロガーへの切り替え
無事に設定が読めたら、ファイル出力やDB出力など、本来の強力な設定を持ったロガーにバトンタッチします。
実装のイメージ
Program.cs の構造は以下のようになります。
// 1. まずは暫定ロガーを起動
Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.CreateBootstrapLogger();
try {
Log.Information("起動プロセス開始...");
// ここでエラーが起きても、暫定ロガーが記録してくれる!
builder.Configuration.AddGcpSecretManager();
// 設定が読めたので本番ロガーに切り替え
builder.Host.UseSerilog((ctx, lc) => lc.ReadFrom.Configuration(ctx.Configuration));
}
catch (Exception ex) {
Log.Fatal(ex, "起動に失敗しました。");
}
finally {
Log.CloseAndFlush();
}
まとめ
「ログが出る」ということは、アプリが「自分は今何をしようとしているか」を説明できるということです。
特にクラウド環境(GCPやAWS)では、コンソールの出力がそのままログ基盤に収集されるため、この起動直後からのログがトラブル解決の唯一の命綱になります。
「最初の一歩からログを出す」設計を心がけましょう!