プログラムを書こう!

実務や自作アプリ開発で習得した役に立つソフトウェア技術情報を発信するブログ

C#でログを出力する

この記事は2022年06月22日に投稿しました。

目次

  1. はじめに
  2. C#でログを出力する
  3. おわりに

1. はじめに

こんにちは、iOSのエディタアプリPWEditorの開発者の二俣です。
今回は業務で使用しているC#でログを出力する方法についてです。

目次へ

2. C#でログを出力する

C#でログを出力するには、以下のような実装にします。

実装例

using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;

namespace SampleLogUtils
{
    internal class Program
    {
        static void Main(string[] args)
        {
            try
            {
                // メッセージのみ出力する場合
                LogUtils.Trace("トレースログ");

                // メッセージにパラメータを埋め込んで出力します。
                LogUtils.Debug("{0}", "デバッグログ");

                var x = 1;
                var y = 0;
                var a = x / y;
            }
            catch (Exception e)
            {
                // 例外メッセージを出力します。
                LogUtils.Error(e);
            }

            Console.ReadKey();
        }
    }

    /// <summary>
    /// ログユーティリティクラス
    /// </summary>
    public class LogUtils
    {
        /// <summary>
        /// コンストラクタ
        /// インスタンス化させません。
        /// </summary>
        private LogUtils() { }

        /// <summary>
        /// トレースレベルのログを出力します。
        /// </summary>
        /// <param name="format">メッセージ(フォーマット)</param>
        /// <param name="args">パラメータ</param>
        public static void Trace(string format, params string[] args)
        {
            // 自身のメソッド名をログレベルとして取得します。
            // 以下同様
            var level = MethodBase.GetCurrentMethod().Name;
            Out(level, format, args);
        }

        /// <summary>
        /// デバッグレベルのログを出力します。
        /// </summary>
        /// <param name="format">メッセージ(フォーマット)</param>
        /// <param name="args">パラメータ</param>
        public static void Debug(string format, params string[] args)
        {
            var level = MethodBase.GetCurrentMethod().Name;
            Out(level, format, args);
        }

        /// <summary>
        /// 情報レベルのログを出力します。
        /// </summary>
        /// <param name="format">メッセージ(フォーマット)</param>
        /// <param name="args">パラメータ</param>
        public static void Info(string format, params string[] args)
        {
            var level = MethodBase.GetCurrentMethod().Name;
            Out(level, format, args);
        }

        /// <summary>
        /// 警告レベルのログを出力します。
        /// </summary>
        /// <param name="format">メッセージ(フォーマット)</param>
        /// <param name="args">パラメータ</param>
        public static void Warn(string format, params string[] args)
        {
            var level = MethodBase.GetCurrentMethod().Name;
            Out(level, format, args);
        }

        /// <summary>
        /// エラーレベルのログを出力します。
        /// </summary>
        /// <param name="format">メッセージ(フォーマット)</param>
        /// <param name="args">パラメータ</param>
        public static void Error(string format, params string[] args)
        {
            var level = MethodBase.GetCurrentMethod().Name;
            Out(level, format, args);
        }

        /// <summary>
        /// エラーレベルのログを出力します。
        /// エラーメッセージとスタックトレースを出力します。
        /// </summary>
        /// <param name="e">例外</param>
        public static void Error(Exception e)
        {
            var level = MethodBase.GetCurrentMethod().Name;
            var format = "{0}\r\n{1}";
            Out(level, format, e.Message, e.StackTrace);
        }

        /// <summary>
        /// 致命的レベルのログを出力します。
        /// </summary>
        /// <param name="format">メッセージ(フォーマット)</param>
        /// <param name="args">パラメータ</param>
        public static void Fatal(string format, params string[] args)
        {
            var level = MethodBase.GetCurrentMethod().Name;
            Out(level, format, args);
        }

        /// <summary>
        /// 致命的レベルのログを出力します。
        /// エラーメッセージとスタックトレースを出力します。
        /// </summary>
        /// <param name="e">例外</param>
        public static void Fatal(Exception e)
        {
            var level = MethodBase.GetCurrentMethod().Name;
            var format = "{0}\r\n{1}";
            Out(level, format, e.Message, e.StackTrace);
        }

        /// <summary>
        /// ログを出力します。
        /// サンプルのためコンソールに出力します。
        /// </summary>
        /// <param name="level">ログレベル</param>
        /// <param name="format">メッセージ</param>
        /// <param name="args">パラメータ</param>
        public static void Out(string level, string format, params string[] args)
        {
            // ログ出力メソッドが呼び出された場所の情報(ファイル名、メソッド名、行番号)を取得します。
            var stackFrame = new StackFrame(2, true);
            var fileName = Path.GetFileName(stackFrame.GetFileName());
            var method = stackFrame.GetMethod().Name;
            var fileLineNumber = stackFrame.GetFileLineNumber();
            // 以下をログヘッダとします。
            // <ファイル名>#<メソッド名>(行番号) 
            var header = $"{fileName}#{method}({fileLineNumber})[{level}] ";
            
            // メッセージをフォーマットします。
            var message = string.Format(format, args);

            // ヘッダとメッセージをログ出力します。
            var log = $"{header}{message}";
            Console.WriteLine(log);
        }
    }
}

実行結果

Program.cs#Main(15)[Trace] トレースログ
Program.cs#Main(18)[Debug] デバッグログ
Program.cs#Main(27)[Error] 0 で除算しようとしました。
   場所 SampleLogUtils.Program.Main(String[] args) 場所 D:\@Data\Sample\SampleLogUtils\SampleLogUtils\Program.cs:行 22

目次へ

3. おわりに

以前紹介した

www.paveway.info

www.paveway.info

www.paveway.info

を応用して、ある程度汎用的なログ出力処理を実装してみました。

紹介している一部の記事のコードはGitlabで公開しています。
興味のある方は覗いてみてください。

目次へ


私が勤務しているニューラルでは、主に組み込み系ソフトの開発を行っております。
弊社製品のハイブリッドOS Bi-OSは高い技術力を評価されており、特に制御系や通信系を得意としています。
私自身はiOSモバイルアプリウィンドウズアプリを得意としております。
ソフトウェア開発に関して相談などございましたら、お気軽にご連絡ください。

また一緒に働きたい技術者の方も随時募集中です。
興味がありましたらご連絡ください。

EMAIL : info-nr@newral.co.jp / m-futamata@newral.co.jp
TEL : 042-523-3663
FAX : 042-540-1688

目次へ