http://logging.apache.org/log4net/index.html
log4net은 java 에서 logging 을 위해 널리 사용되는 라이브러리인 log4j 를 닷넷용으로 포팅한 것이다.
공식 사이트에서 메뉴얼을 열심히 읽고 정리해둔다.
1.Overview
log4net 은 Apache License, Version 2.0 라이센스라서 상업적 이용이 가능하다고 한다.
logging이 너무 자세할 경우 어플리케이션의 퍼포먼스저하를 심하게 일으킬 수 있기 때문에
log4net은 퍼포먼스에 초점을 맞추어 설계되었다고 한다.
2.지원하는 framework
현재 닷넷 프레임워크 2.0 까지 지원되는듯. ( 그 이상도 문제없는듯)
3.구성 요소
Logger - logging을 하는 객체
Appender - logger에 1개 이상을 붙여서 사용함.
text file로 할건지, console에 할 건지, DB에 할건지 등에 따라 여러가지 appender 클래스가 존재.
Layout - log message의 출력 format 을 지정
Filter - log message를 필터링. filter chain을 형성. filter는 설정파일(xml임)에 명시한 순서대로 적용
Object Renderer - 특정 오브젝트를 렌더링(log message로)하는 역할
4.Logger hierarchy
logger 는 "Named Hierarchy"를 가지고 있다.
logger에 이름을 부여하는데, java의 package나 C#의 namespace hierachy와 동일한 규칙을 따른다.
즉 logger A의 이름이 A 이고 logger B의 이름이 A.B 이고 logger C의 이름이 A.B.C 라면
A - B - C 의 hierachy가 형성된다.
root logger를 설정파일에 항상 명시해야 하며 root logger가 모든 logger의 ancestor 가 된다.
logger의 이름을 어떻게 짓든 자유이지만 type name으로 하는 것이 가장 괜찮은 방법이다.
로그 메세지만 보고 어느 클래스에서 발생한 로그메세지인지 짐작할 수 있기 때문이다.
ex)
namespace가 Foo 이고 클래스 이름이 Bar 일때
namespace Foo
{
class Bar { ...}
}
logger의 이름을 typeof(Bar) 라고 하면 Foo.Bar 라는 string이 된다.
logger 는 다음과 같이 얻는다.
private static ILog log = LogManager.GetLogger(typeof(Form1));
각 클래스에 static 멤버로 넣어두는 것이 좋다.
5.level & ILog interface
ILog interface에는 여러 함수들이 있는데 몇가지만 살펴보면
void Debug(object message); void Info(object message); void Warn(object message); void Error(object message); void Fatal(object message);
각 함수의 이름이 log message의 level을 나타내고 있다.
ALL
DEBUG
INFO
WARN
ERROR
FATAL
OFF
log message(또는 logger)의 level은 위와 같다. 아래로 갈수록 priority 가 높아진다.
앞서 언급한 logger hierachy에 따라 logger level이 상속된다.
logger에 level을 명시적으로 부여할 경우 그 level을 사용하게 되고
명시적으로 부여하지 않으면 자신의 조상 logger중 명시적으로 level을 부여한 것중 가장 자신과 가까운 것의 level을 상속받는다.
예제는 공식문서를 보기 바란다.
logging request는 그것의 level 이 logger의 level보다 크거나 같으면 enabled 라고 말한다.
앞서 언급했듯이 DEBUG < INFO < WARN < ERROR < FATAL 순의 level을 가지는데,
예를들어 logger의 level이 WARN 이면 logging request 의 level이 WARN,ERROR,FATAL 인것만 로그에 남고 DEBUG,INFO인 것은 무시된다.
6.Appender
자세한 내용은 공식문서를 참고하기 바란다.
ConsoleAppender와 RollingFileAppender 가 제일 많이 쓰일 것 같다.
AdoNetAppender 로 DB에 기록해도 되지만 콘솔이나 plain text로 기록하는 것에 비해 오버헤드가 클 것 같다.
plain text를 한가할때 parsing 해서 DB에 넣는 녀석을 따로 만드는 것이 나을듯.
Appender Additivity
이것 역시 Logger hierachy에 따른 특징이다.
logger 마다 Additivity flag를 설정하여 기능을 켜고 끌 수 있다.
그냥 다음을 읽어보도록 하자.
- Appender Additivity
The output of a log statement of logger X will go to all the appenders in X and its ancestors. This is the meaning of the term "appender additivity".
However, if an ancestor of logger X, say Y, has the additivity flag set to false, then X's output will be directed to all the appenders in Xand it's ancestors up to and including Y but not the appenders in any of the ancestors of Y.
Loggers have their additivity flag set to true by default.
The table below shows an example:
Logger Name | Added Appenders | Additivity Flag | Output Targets | Comment |
---|---|---|---|---|
root | A1 | not applicable | A1 | There is no default appender attached toroot. |
x | A-x1, A-x2 | true | A1, A-x1, A-x2 | Appenders of "x" androot. |
x.y | none | true | A1, A-x1, A-x2 | Appenders of "x" androot. |
x.y.z | A-xyz1 | true | A1, A-x1, A-x2, A-xyz1 | Appenders in "x.y.z", "x" and root. |
security | A-sec | false | A-sec | No appender accumulation since the additivity flag is set tofalse. |
security.access | none | true | A-sec | Only appenders of "security" because the additivity flag in "security" is set tofalse. |
7.filter
이 부분은 공식문서 ( http://logging.apache.org/log4net/release/manual/configuration.html ) 의 filters 부분을 읽는게 좋을듯
8.layout
9.object renderer
둘다 7번과 같음.
10.설정파일
설정파일은 xml 형식이다.
설정파일을 쓰는 방법은 두가지가 있다.
1) System.Configuration API를 이용
장점 - permission이 덜 필요함
단점 - 설정파일 수정시 auto reload가 안됨
파일명을 App.config 이런걸로 해야만 함
2) 파일에서 직접 읽기
장점 - 파일명 맘대로 할 수 있음.
auto reload 지원됨
단점 - permission이 더 필요함
그러니까 난 2번을 택했다..
사용법은 다음과 같다.
namespace WindowsFormsApplication3
{
public partial class Form1 : Form
{
private static ILog log = LogManager.GetLogger(typeof(Form1));
public Form1()
{
InitializeComponent();
XmlConfigurator.ConfigureAndWatch(new FileInfo(@"App.config"));
}
private void button1_Click(object sender, EventArgs e)
{
log.Debug("SPECIAL CHAT");
log.Info("CHAT SPEICAL");
log.Warn("1 CHAT");
log.Error("1 CHAT SPECIAL");
log.Fatal("CHAT CHAT SPECIAL");
log.Fatal("SPECIAL SPECIAL CHAT");
log.Fatal("CHAT CHAT SPECIAL");
}
}
}
설정파일은 다음과 같이 작성한다.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net xsi:noNamespaceSchemaLocation="http://csharptest.net/downloads/schema/log4net.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline" />
</layout>
<filter type="log4net.Filter.StringMatchFilter">
<stringToMatch value="1"/>
</filter>
<filter type="log4net.Filter.DenyAllFilter" />
</appender>
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender" >
<param name="File" value="E:\log.txt" />
<param name="AppendToFile" value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%-5p%d{yyyy-MM-dd hh:mm:ss} – %m%n" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="ConsoleAppender" />
<appender-ref ref="LogFileAppender"/>
</root>
<logger name="ConsoleApplication2.Program" additivity="false">
<appender-ref ref="ConsoleAppender"/>
</logger>
</log4net>
</configuration>
log4net element에 dtd 정보를 셋팅하고 있는데 이것은 log4net에서 공식지원하는 것이 아니다.
어떤 위대한 선삽자분께서 만드신 것이다[..]
appender element를 보면 name,type을 명시하고 child로 layout,filter 등을 명시하고 있다.
root element에는 root logger의 level을 명시하고 appender를 명시하고 있다.
가장 하단의 logger element에서는 appender를 명시하고 있다.
'C#, .NET' 카테고리의 다른 글
listbox auto scroll (0) | 2011.06.17 |
---|---|
network 상태 체크하기 (0) | 2011.06.17 |
as vs casting (0) | 2011.06.17 |
synchronization (0) | 2011.06.17 |
exception, try-catch performance (0) | 2011.06.17 |