11using System ;
2+ using System . Collections . Generic ;
23using System . IO ;
34using System . Text ;
5+ using System . Threading ;
46using DotNetCampus . Logging . Writers . ConsoleLoggerHelpers ;
57using DotNetCampus . Logging . Writers . Helpers ;
68using C = DotNetCampus . Logging . Writers . ConsoleLoggerHelpers . ConsoleColors ;
@@ -15,7 +17,12 @@ namespace DotNetCampus.Logging.Writers;
1517/// </summary>
1618public class ConsoleLogger : ILogger
1719{
18- private static readonly TextWriter Out = GetStandardOutputWriter ( ) ;
20+ private readonly Lazy < TextWriter > _outLazy ;
21+
22+ /// <summary>
23+ /// 获取用于输出日志的文本写入流。
24+ /// </summary>
25+ private TextWriter Out => _outLazy . Value ;
1926
2027 /// <summary>
2128 /// 用于处理重复的日志,避免重复日志污染控制台输出内容。
@@ -35,24 +42,25 @@ public class ConsoleLogger : ILogger
3542 /// </summary>
3643 /// <param name="threadMode">指定控制台日志的线程安全模式。</param>
3744 /// <param name="mainArgs">Main 方法的参数。</param>
38- public ConsoleLogger ( LogWritingThreadMode threadMode = LogWritingThreadMode . NotThreadSafe , string [ ] ? mainArgs = null )
39- : this ( threadMode . CreateCoreLogWriter ( SafeWriteLine ) , TagFilterManager . FromCommandLineArgs ( mainArgs ?? [ ] ) )
40- {
41- }
42-
43- internal ConsoleLogger ( ICoreLogWriter coreWriter , TagFilterManager ? tagManager )
45+ public ConsoleLogger ( LogWritingThreadMode threadMode = LogWritingThreadMode . NotThreadSafe , IReadOnlyList < string > ? mainArgs = null )
4446 {
4547 _repeat = new RepeatLoggerDetector ( ClearAndMoveToLastLine ) ;
46- CoreWriter = coreWriter ;
47- TagManager = tagManager ;
48+ CoreWriter = threadMode . CreateCoreLogWriter ( SafeWriteLine ) ;
49+ TagManager = TagFilterManager . FromCommandLineArgs ( mainArgs ?? [ ] ) ;
4850 _isConsoleOutput = ConsoleInitializer . Initialize ( ) ;
51+ _outLazy = new Lazy < TextWriter > ( GetStandardOutputWriter , LazyThreadSafetyMode . ExecutionAndPublication ) ;
4952 }
5053
5154 /// <summary>
5255 /// 高于或等于此级别的日志才会被记录。
5356 /// </summary>
5457 public LogLevel Level { get ; init ; }
5558
59+ /// <summary>
60+ /// 指定控制台日志输出的目标。
61+ /// </summary>
62+ public LoggerConsoleOutputTo OutputTo { get ; init ; }
63+
5664 /// <summary>
5765 /// 最终日志写入器。
5866 /// </summary>
@@ -239,7 +247,7 @@ private void ConsoleMultilineMessage(string message,
239247 /// 安全地写入一行日志,避免出现 IO 异常。
240248 /// </summary>
241249 /// <param name="message"></param>
242- internal static void SafeWriteLine ( string ? message )
250+ internal void SafeWriteLine ( string ? message )
243251 {
244252 try
245253 {
@@ -309,14 +317,22 @@ private int SafeGetSpaceCount(params
309317 /// 如果当前在控制台中输出,则使用控制台的输出流;否则创建一个 UTF-8 编码的标准输出流。
310318 /// </summary>
311319 /// <returns>文本写入流。</returns>
312- private static TextWriter GetStandardOutputWriter ( )
320+ private TextWriter GetStandardOutputWriter ( )
313321 {
314322 if ( Console . OutputEncoding . CodePage is not 0 )
315323 {
316- return Console . Out ;
324+ return OutputTo switch
325+ {
326+ LoggerConsoleOutputTo . StandardError => Console . Error ,
327+ _ => Console . Out ,
328+ } ;
317329 }
318330
319- var standardOutput = Console . OpenStandardOutput ( ) ;
331+ var standardOutput = OutputTo switch
332+ {
333+ LoggerConsoleOutputTo . StandardError => Console . OpenStandardError ( ) ,
334+ _ => Console . OpenStandardOutput ( ) ,
335+ } ;
320336 var writer = new StreamWriter ( standardOutput , new UTF8Encoding ( encoderShouldEmitUTF8Identifier : false ) )
321337 {
322338 AutoFlush = true ,
@@ -351,3 +367,19 @@ private static TextWriter GetStandardOutputWriter()
351367 private static string CriticalExceptionTag => $ "{ B . Black } { D . Bold } { F . Red } X { Reset } { CriticalText } ";
352368 private static string EmptyExceptionTag => " " ;
353369}
370+
371+ /// <summary>
372+ /// 指定控制台日志输出的目标。
373+ /// </summary>
374+ public enum LoggerConsoleOutputTo
375+ {
376+ /// <summary>
377+ /// 输出到标准输出流。
378+ /// </summary>
379+ StandardOutput ,
380+
381+ /// <summary>
382+ /// 输出到标准错误流。
383+ /// </summary>
384+ StandardError ,
385+ }
0 commit comments