표준 I/O 기능보다는이 종류의 것에 대해서 log4net을 사용합니다. Log4net을 구성하여 ConsoleAppender와 FileAppender 또는 RollingFileAppender를 사용하여 동시에 콘솔과 로그 파일에 모두 기록합니다.
좋은 점은 기록 된 메시지 이외에 모든 종류의 유용한 정보 (시간, 스레드/프로세스 ID, 시스템 이름 등)를 저장하도록 로그 메시지 템플리트를 설정할 수 있다는 점입니다.
SQL Server, 이벤트 로그 또는 원격 싱크에 로그온 할 수도 있습니다.
쉽지!
using System;
using System.IO;
using System.Text;
using log4net ;
namespace ConsoleApplication22
{
public class Log4NetTextWriter : TextWriter, IDisposable
{
private static ILog log = log4net.LogManager.GetLogger(typeof(Log4NetTextWriter)) ;
#region properties
private StringBuilder buffer { get ; set ; }
public override Encoding Encoding
{
get
{
// since this TextWrite is writing to log4net, we have no idea what the final encoding might be.
// It all depends on the log4net configuration: tthe appender or appenders that wind up handling the logged message
// determine the final encoding.
//
// Might make more sense to return Encoding.UTF8 though, just to return something.
throw new NotImplementedException() ;
}
}
#endregion properties ;
public override void Flush()
{
if (this.buffer != null && this.buffer.Length > 0)
{
this.WriteLine() ;
}
return ;
}
public override void Close()
{
base.Close();
}
protected override void Dispose(bool disposing)
{
this.Flush() ;
base.Dispose(disposing);
}
#region public constructors
public Log4NetTextWriter() : this(null)
{
return ;
}
public Log4NetTextWriter(IFormatProvider formatProvider) : base(formatProvider)
{
this.buffer = new StringBuilder() ;
}
#endregion public constructors
#region public Write() overloads
public override void Write(bool value)
{
this.buffer.Append(value) ;
return ;
}
public override void Write(char value)
{
this.buffer.Append(value) ;
return ;
}
public override void Write(char[] buffer)
{
this.buffer.Append(buffer) ;
return ;
}
public override void Write(char[] buffer , int index , int count)
{
this.buffer.Append(buffer , index , count) ;
return ;
}
public override void Write(decimal value)
{
this.buffer.Append(value) ;
return ;
}
public override void Write(double value)
{
this.buffer.Append(value) ;
return ;
}
public override void Write(float value)
{
this.buffer.Append(value) ;
return ;
}
public override void Write(int value)
{
this.buffer.Append(value) ;
return ;
}
public override void Write(long value)
{
this.buffer.Append(value) ;
return ;
}
public override void Write(object value)
{
this.buffer.Append(value) ;
return ;
}
public override void Write(string format , object arg0)
{
this.buffer.AppendFormat(this.FormatProvider , format , arg0) ;
return ;
}
public override void Write(string format , object arg0 , object arg1)
{
this.buffer.AppendFormat(this.FormatProvider , format , arg0 , arg1) ;
return ;
}
public override void Write(string format , object arg0 , object arg1 , object arg2)
{
this.buffer.AppendFormat(this.FormatProvider , format , arg0 , arg1 , arg2);
return ;
}
public override void Write(string format , params object[] arg)
{
this.buffer.AppendFormat(this.FormatProvider , format , arg) ;
return ;
}
public override void Write(string value)
{
this.buffer.Append(value);
return ;
}
public override void Write(uint value)
{
this.buffer.Append(value);
return ;
}
public override void Write(ulong value)
{
this.buffer.Append(value);
return ;
}
public override void WriteLine()
{
string logMessage = this.buffer.ToString() ;
this.buffer.Length = 0 ;
log.Info(logMessage) ;
return ;
}
#endregion public Write() overloads
#region public WriteLine() overloads
public override void WriteLine(bool value)
{
this.Write(value) ;
this.WriteLine() ;
return ;
}
public override void WriteLine(char value)
{
this.Write(value) ;
this.WriteLine() ;
return ;
}
public override void WriteLine(char[] buffer)
{
this.Write(buffer) ;
this.WriteLine() ;
return ;
}
public override void WriteLine(char[] buffer , int index , int count)
{
this.Write(buffer , index , count) ;
this.WriteLine() ;
return ;
}
public override void WriteLine(decimal value)
{
this.Write(value) ;
this.WriteLine() ;
return ;
}
public override void WriteLine(double value)
{
this.Write(value) ;
this.WriteLine() ;
return ;
}
public override void WriteLine(float value)
{
this.Write(value) ;
this.WriteLine() ;
return ;
}
public override void WriteLine(int value)
{
this.Write(value) ;
this.WriteLine() ;
return ;
}
public override void WriteLine(long value)
{
this.Write(value) ;
this.WriteLine() ;
return ;
}
public override void WriteLine(object value)
{
this.Write(value) ;
this.WriteLine() ;
return ;
}
public override void WriteLine(string format , object arg0)
{
this.Write(format , arg0) ;
this.WriteLine() ;
return ;
}
public override void WriteLine(string format , object arg0 , object arg1)
{
this.Write(format , arg0 , arg1) ;
this.WriteLine() ;
return ;
}
public override void WriteLine(string format , object arg0 , object arg1 , object arg2)
{
this.Write(format , arg0 , arg1 , arg2) ;
this.WriteLine() ;
return ;
}
public override void WriteLine(string format , params object[] arg)
{
this.Write(format , arg) ;
this.WriteLine() ;
return ;
}
public override void WriteLine(string value)
{
this.Write(value) ;
this.WriteLine() ;
return ;
}
public override void WriteLine(uint value)
{
this.Write(value) ;
this.WriteLine() ;
return ;
}
public override void WriteLine(ulong value)
{
this.Write(value) ;
this.WriteLine() ;
return ;
}
#endregion public WriteLine() overloads
}
}
다음은 샘플 log4net 설정 파일입니다 :
여기에 log4net을 통해 경로의 모든 것을 샘플 TextWriter를 구현합니다. 이 로그 파일은 콘솔과 로그 파일에 기록되며 크기에 따라 자동으로 롤오버됩니다 (날짜/시간 또는 실행 당 롤 수 있음). 프로그램이 실행되는
// Configure log4net using the .log4net file
[assembly: log4net.Config.XmlConfigurator(ConfigFileExtension="log4net",Watch=true)]
// This will cause log4net to look for a configuration file
// called TestApp.exe.log4net in the application base
// directory (i.e. the directory containing TestApp.exe)
// The config file will be watched for changes.
동안, 당신은 로깅 설정하거나 해제 또는 변경할 수 있습니다 log4net를 구성하려면
<log4net>
<!-- Log to the console -->
<appender name="Console" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<!-- Pattern to output the caller's file name and line number -->
<conversionPattern value="%5level [%thread] (%file:%line) - %message%newline" />
</layout>
</appender>
<!-- Log to a log file. This particular setup should log to a static file name 'log.txt' -->
<!-- When it hits 100KB in size, it rolls, keeping up to 10 archived files. The archived -->
<!-- files are named 'log.text.1', 'log.txt.2', ... , 'log.txt.10' -->
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="log.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="100KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="Console" />
<appender-ref ref="RollingFile" />
</root>
</log4net>
는 가장 쉬운 방법은, 따라서,의 AssemblyInfo.cs에 XmlConfigurator 속성을 넣어이다 구성 파일을 편집하고 저장하면됩니다. log4net은 설정 파일 변경을 감시하고 즉시 변경됩니다.
그래,이 방법으로, 내 DistributingTextWriter 콘솔 TextWriter 및 StreamWriter에 대한 참조를 보유한다고 가정합니다. 그런 다음 모든 Write 및 WriteLine 메서드를 덮어 써서이 호출을 모든 TextWriters에 '배포'해야합니까? – Nitax
걱정됩니다. TextWriter 클래스의 인터페이스와의 호환성을 유지하려면 모든 메서드를 다시 구현해야합니다.그러나 System.IO.StreamWriter 구현에서 대부분의 코드를 복사 할 수 있습니다. "SSCLI"및/또는 "로터"에 대한 Google 검색. –