はじめに
ログには様々なパターンがあると思いますが、最低限これをやっておけば運用後に困らない、というものをまとめたものとなります。
皆様の参考となれば幸いです。
環境
今回ご紹介するサンプルソースは以下の構成となります。
- C#
- Nlog
また、フィールドにはNLogを呼び出すための変数を定義しています。
private static NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger();
メソッドの開始、終了
各メソッドの開始、終了にログを出力することで、どのメソッドで停止または異常が起きたかを正確に特定できます。特に、複数の非同期処理や並列処理が絡むプログラムでは、処理の流れを追いやすくなります。
public void HogeHoge()
{
_logger.Info("HogeHoge:Start");
// 処理
_logger.Info("HogeHoge:End");
}
途中で処理を終了したい場合もreturnの前にログを出力するようにします。
public void HogeHoge()
{
_logger.Info("HogeHoge:Start");
// 処理
if(条件)
{
_logger.Info("HogeHoge:End");
return;
}
_logger.Info("HogeHoge:End");
}
このほか、複雑なビジネスロジックや多層アーキテクチャにおいて、「どのメソッドがどの順番で実行されるか」を確認するのに役立ちます。
パラメータや変数の出力
パラメーターや変数の値を出力する事で、実際にプログラムがどのような入力を受け取っていたか把握でき、問題の再現が容易になります。
本番環境で問題が発生した際、パラメーターや変数の値を記録しておけば、デバッグ環境を構築せずに原因を特定できます。
public void HogeHoge(int param_A , int param_B)
{
_logger.Info("HogeHoge:Start");
int param_C = 外部APIのパラメーター();
_logger.Info($"param_A:{param_A}");
_logger.Info($"param_B:{param_B}");
_logger.Info($"param_C:{param_C}");
_logger.Info("HogeHoge:End");
}
外部APIからパラメーターを取得する場合、想定していないパラメーターが入ってくる場合もあるので、潜在的なバグや不具合を未然に発見することが可能です。
条件分岐の動作確認
(この様な大量のネストは避けたいですが)実行時にどの条件が成立してどのコードが実行されたかを正確に把握できます。
if(条件A)
{
_logger.Info("条件A");
if(条件B)
{
_logger.Info("条件B");
if(条件C)
{
_logger.Info("条件C");
}
}
}
今回はif文の条件を「条件A」という簡単な表現にしましたが、複雑な条件式である場合、パラメーターをログで出力していてもどの条件式を通過したのか分かりやすくなります。
また、条件分岐だけでなく、その前後の処理や関連するパラメーター値と合わせてログを出力することで、処理フロー全体を把握しやすくなります。
_logger.Info($"条件A成立: param_X={param_X}, param_Y={param_Y}");
テスト環境や本番環境での挙動が設計通りであることを確認する助けになります。
特定の条件が成立しない場合や、予期せぬ分岐が実行された場合に、その箇所を特定しやすくなります。
例外処理
最後に、例外処理のメッセージを出力しておくと後の解析に役立ちます。
try
{
// 処理
}
catch (Exception e)
{
_logger.Error(e.Message);
}