2 using System.Collections.Generic;
3 using System.Diagnostics;
12 private static readonly string tagINFO = "[INFORMATION]";
13 private static readonly string tagWARNING = "[ WARNING ]";
14 private static readonly string tagERROR = "[ ERROR ]";
15 private static readonly string tagINTERVAL = "[ INTERVAL ]";
18 /// これを設定しておくと、スレッドID の横に (名前) と出力されるようになる。
20 public static void 現在のスレッドに名前をつける( string 名前 )
25 var ID = Log.GetCurrentThreadId();
27 if( Log._IDto名前.ContainsKey( ID ) )
28 Log._IDto名前.Remove( ID );
30 Log._IDto名前.Add( ID, 名前 );
33 System.Threading.Thread.CurrentThread.Name = 名前;
37 public static void Info( string 出力 )
41 Log._一定時間が経過していたら区切り線を表示する();
42 Trace.WriteLine( $"{tagINFO} {Log._日時とスレッドID}{Log._インデックスを返す( Log._深さ )}{出力}" );
46 public static void WARNING( string 出力 )
50 Log._一定時間が経過していたら区切り線を表示する();
51 Trace.WriteLine( $"{tagWARNING} {Log._日時とスレッドID} {出力}" );
55 public static void ERROR( string 出力 )
59 Log._一定時間が経過していたら区切り線を表示する();
60 Trace.WriteLine( $"{tagERROR} {Log._日時とスレッドID} {出力}" );
64 public static void ERRORandTHROW( string 出力, Exception inner = null )
67 throw new FDKException( 出力, inner );
70 public static void Header( string ヘッダ出力 )
74 Log._一定時間が経過していたら区切り線を表示する();
76 Log.Info( $"======== {ヘッダ出力} ========" );
80 public static LogBlock Block( string ブロック名 )
82 return new LogBlock( ブロック名 );
86 /// 連続して呼び出しても、前回の同一識別キーでの表示から一定時間が経たないと表示しないInfoメソッド。
89 /// 毎秒60回の進行描画の進捗など、連続して呼び出すと膨大な数のログが出力されてしまう場合に使用する。
91 /// <param name="識別キー"></param>
92 /// <param name="出力"></param>
93 public static void 定間隔Info( string 識別キー, string 出力, double 間隔sec = 0.25 )
97 if( Log._識別キー別最終表示時刻.ContainsKey( 識別キー ) )
99 if( ( DateTime.Now - Log._識別キー別最終表示時刻[ 識別キー ] ).TotalSeconds >= 間隔sec )
101 Log._識別キー別最終表示時刻[ 識別キー ] = DateTime.Now;
102 Trace.WriteLine( $"{tagINFO} {Log._日時とスレッドID} {出力}" );
107 Log._識別キー別最終表示時刻.Add( 識別キー, DateTime.Now );
108 Trace.WriteLine( $"{tagINFO} {Log._日時とスレッドID} {出力}" );
114 /// 指定されたフォルダ内に配置可能な、新しいログファイル名を生成して返す。
116 /// <param name="ログフォルダパス">ログファイルを配置するフォルダのパス。</param>
117 /// <param name="ログファイルの接頭辞">ログファイル名に付与する接頭辞。</param>
118 /// <param name="最大保存期間">フォルダ内に保存しておく最大の期間。</param>
119 /// <returns>生成されたログファイル名。パス付き。</returns>
121 /// ログファイル名は、現在時刻をベースに名付けられる。
122 /// 同時に、フォルダ内に存在するすべてのファイルの更新時刻をチェックし、最大保存期間を超える古いファイルは、自動的に削除する。
124 public static string ログファイル名を生成する( string ログフォルダパス, string ログファイルの接頭辞, TimeSpan 最大保存期間 )
126 var 現在の日時 = DateTime.Now;
128 if( Directory.Exists( ログフォルダパス ) )
130 // (A) フォルダがある場合 → 最大保存期間を超える古いファイルを削除する。
131 var 削除対象ファイルs = Directory.GetFiles( ログフォルダパス ).Where(
132 ( file ) => ( File.GetLastWriteTime( file ) < ( 現在の日時 - 最大保存期間 ) ) );
134 foreach( var path in 削除対象ファイルs )
139 // (B) フォルダがない場合 → 作成する。
140 Directory.CreateDirectory( ログフォルダパス );
143 // 現在の時刻をもとに、新しいログファイル名を生成して返す。
144 return Path.Combine( ログフォルダパス, $"{ログファイルの接頭辞}{現在の日時.ToString( "yyyyMMdd-HHmmssffff" )}.txt" );
148 internal static void BeginInfo( string 開始ブロック名 )
152 Log._一定時間が経過していたら区切り線を表示する();
153 Trace.WriteLine( $"{tagINFO} {Log._日時とスレッドID}{Log._インデックスを返す( Log._深さ )}{開始ブロック名} --> 開始" );
159 internal static void EndInfo( string 終了ブロック名 )
163 Log._深さ = Math.Max( ( Log._深さ - 1 ), 0 );
165 Log._一定時間が経過していたら区切り線を表示する();
166 Trace.WriteLine( $"{tagINFO} {Log._日時とスレッドID}{Log._インデックスを返す( Log._深さ )}{終了ブロック名} <-- 終了" );
171 private const double _最小区切り時間 = 2.0; // 区切り線を入れる最小の間隔[秒]。
173 private static string _日時とスレッドID
177 var NETスレッドID = System.Threading.Thread.CurrentThread.ManagedThreadId;
178 var Win32スレッドID = Log.GetCurrentThreadId();
179 var スレッド識別文字列 = ( Log._IDto名前.ContainsKey( Win32スレッドID ) ) ? $"({Log._IDto名前[ Win32スレッドID ]})" : "";
180 return $"{DateTime.Now.ToLongTimeString()} [{NETスレッドID:00},0x{Win32スレッドID:x}{スレッド識別文字列}]";
184 private static readonly Dictionary<uint, string> _IDto名前 = new Dictionary<uint, string>();
186 private static Dictionary<string, DateTime> _識別キー別最終表示時刻 = new Dictionary<string, DateTime>();
188 private static TimeSpan _経過時間
192 var 現在時刻 = DateTime.Now;
193 var 経過時間 = 現在時刻 - Log._最終表示時刻;
194 Log._最終表示時刻 = 現在時刻; // 更新
199 private static DateTime _最終表示時刻 = DateTime.Now;
201 private static int _深さ = 0;
203 private static readonly object _スレッド間同期 = new object();
206 private static void _一定時間が経過していたら区切り線を表示する()
208 var span = Log._経過時間.TotalSeconds;
210 if( Log._最小区切り時間 < span )
239 int faceNow = ( (int) ( span * 1000.0 ) ) % faces.Length;
243 Trace.WriteLine( $"{tagINTERVAL} ...... {faces[ faceNow ]} ......" );
247 private static string _インデックスを返す( int 長さ )
249 var sb = new StringBuilder();
251 for( int i = 0; i < 長さ; i++ )
252 sb.Append( ( 0 < i ) ? "| " : " " );
254 return sb.ToString();
260 [System.Runtime.InteropServices.DllImport( "kernel32.dll" )]
261 private static extern uint GetCurrentThreadId();