2011-03-28 4 views
1

나는 자신의 log4net appender를 구현하려고하는데, 이것은 네임 스페이스별로 메시지를 그룹으로 묶을 것이다. 문제는 내가 원하는대로 Log4net에 LocationInformation을 기록 할 수 없다는 것입니다.네임 스페이스별로 log4net에서 로깅 메시지를 그룹화하는 방법은 무엇입니까?

class Program 
{ 
    protected static IWindsorContainer container; 
    static void Main(string[] args) 
    { 
     container = new WindsorContainer(); 
     container.Kernel.Resolver.AddSubResolver(new ArrayResolver(container.Kernel)); 

     // add facilities 
     container.AddFacility("logging.facility", new LoggingFacility(LoggerImplementation.Log4net, "log4net.config")); 
     container.Register(Component.For<ParentClass>().ImplementedBy<ParentClass>()); 
     container.Register(Component.For<ChildClass>().ImplementedBy<ChildClass>());      

     var parentClass = container.Resolve<ParentClass>(); 
     var childClass = container.Resolve<ChildClass>(); 
     parentClass.Init(); 
     childClass.Init(); 

    } 
} 

public class ParentClass 
{ 
    private readonly ILogger logger; 

    private ILog localLogger; 

    public ParentClass(ILogger logger) 
    { 
     this.logger = logger; 
     localLogger = LogManager.GetLogger(GetType()); 
     logger.Info("ctor ioc logger, type: {0}",GetType().Name); 
     localLogger.Info(string.Format("ctor local logger, type: {0}", GetType().Name)); 
    } 

    public void Init() 
    { 
     logger.Info("init ioc logger, type: {0}", GetType().Name); 
     localLogger.Info(string.Format("init local logger, type: {0}", GetType().Name)); 
    } 
} 

public class ChildClass : ParentClass 
{ 
    public ChildClass(ILogger logger) : base(logger) 
    { 

    } 
} 

출력은 log4net 클래스 이름은 항상 기본 클래스 이름 (에 ParentClass)로 출력

2011-03-28 09:58:55 INFO 10 ParentClass - ctor ioc logger, type: ParentClass 
2011-03-28 09:58:55 INFO 10 ParentClass - ctor local logger, type: ParentClass 
2011-03-28 09:58:55 INFO 10 ParentClass - ctor ioc logger, type: ChildClass 
2011-03-28 09:58:55 INFO 10 ParentClass - ctor local logger, type: ChildClass 
2011-03-28 09:58:55 INFO 10 ParentClass - init ioc logger, type: ParentClass 
2011-03-28 09:58:55 INFO 10 ParentClass - init local logger, type: ParentClass 
2011-03-28 09:58:55 INFO 10 ParentClass - init ioc logger, type: ChildClass 
2011-03-28 09:58:55 INFO 10 ParentClass - init local logger, type: ChildClass 

문제가있다. 처음에는 Castle Windsor가 그런 문제를 일으킬 수 있다고 생각했지만 결과가 표시되면 수동으로 로거 인스턴스를 만들지 만 기본 클래스 이름도 기록합니다. 누구든지 아이디어를 가지고 있습니다, 어떻게 log4net 실제 인스턴스 클래스 이름을 작성 강제로?

2011-03-28 09:58:55 INFO 10 ParentClass - ctor ioc logger, type: ParentClass 
2011-03-28 09:58:55 INFO 10 ParentClass - ctor local logger, type: ParentClass 
2011-03-28 09:58:55 INFO 10 ChildClass - ctor ioc logger, type: ChildClass 
2011-03-28 09:58:55 INFO 10 ChildClass - ctor local logger, type: ChildClass 
2011-03-28 09:58:55 INFO 10 ParentClass - init ioc logger, type: ParentClass 
2011-03-28 09:58:55 INFO 10 ParentClass - init local logger, type: ParentClass 
2011-03-28 09:58:55 INFO 10 ChildClass - init ioc logger, type: ChildClass 
2011-03-28 09:58:55 INFO 10 ChildClass - init local logger, type: ChildClass 
: 위의

<appender name="RollingFile" type="log4net.Appender.RollingFileAppender"> 
    <file value="c:\temp\testlog.log" /> 
    <appendToFile value="true" /> 
    <maximumFileSize value="10MB" /> 
    <maxSizeRollBackups value="2" /> 

    <layout type="log4net.Layout.PatternLayout"> 
    <conversionPattern value="%utcdate{yyyy-MM-dd HH:mm:ss} %level %thread %C{1} - %message%newline" /> 
    </layout> 
</appender> 

<root> 
    <level value="INFO" /> 
    <appender-ref ref="RollingFile" />  
</root> 

출력 내가 얻을 것으로 기대하는 것은 내가 무엇을 얻을 수 있습니다 :

여기 갱신

사용 log4net 설정을 간다경우 누구의 17,451,515,

갱신이

여기 펜더 구현을 작동하고, 같은 일을해야합니다 :

public class GroupStringListAppender : log4net.Appender.AppenderSkeleton 
{ 
    private readonly int listLength = 30; 
    private readonly Func<string, string> pathFuction; 
    private readonly Dictionary<string, List<string>> messagesDictionary = new Dictionary<string, List<string>>(); 

    public GroupStringListAppender(int listLength, Func<string, string> pathFuction) 
    { 
     this.listLength = listLength; 
     this.pathFuction = pathFuction; 
    } 

    public List<string> GetMessages(string path) 
    { 
     return messagesDictionary[path]; 
    }   

    protected override void Append(LoggingEvent loggingEvent) 
    { 
     var msg = loggingEvent.RenderedMessage; 
     var path = pathFuction.Invoke(loggingEvent.LoggerName); 

     if (!messagesDictionary.ContainsKey(path)) 
     { 
      messagesDictionary.Add(path, new List<string>()); 
      OnNewPathCreated(path); 
     } 

     var list = messagesDictionary[path];   

     while (list.Count - listLength > 0) 
     { 
      list.RemoveAt(0);  
     } 

     list.Add(msg); 

     OnAppended(path, list);   
    } 

    public event AppendedEventHandler Appended; 

    public void OnAppended(string path, List<string> list) 
    { 
     AppendedEventHandler handler = Appended; 
     if (handler != null) handler(this, new LoggerMessageAppendedEventArgs(path, list)); 
    } 

    public event NewPathCreatedHandler NewPathCreated; 

    public void OnNewPathCreated(string path) 
    { 
     var handler = NewPathCreated; 
     if (handler != null) handler(this, new NewPathCreatedHandlerArgs(path)); 
    } 
} 

public delegate void NewPathCreatedHandler(object sender, NewPathCreatedHandlerArgs args); 

public class NewPathCreatedHandlerArgs : EventArgs 
{ 
    public string Path { get; set; } 

    public NewPathCreatedHandlerArgs(string path) 
    { 
     Path = path; 
    } 
} 

public class LoggerMessageAppendedEventArgs : EventArgs 
{ 
    public string Path { get; set; } 
    public List<string> List { get; set; } 

    public LoggerMessageAppendedEventArgs(string path, List<string> list) 
    { 
     Path = path; 
     List = list; 
    } 
} 

public delegate void AppendedEventHandler(object sender, LoggerMessageAppendedEventArgs e); 
+0

log4net.config를 볼 수 있습니까? – svrist

+0

당신이 원하는 결과물이나 출력물을 가지고 있습니까? 그것은 당신이 원하는 결과물이라고 생각되지만, 출력물에 대해 궁금해합니다. (특히 init과 관련하여, 여러분이 원했던 것과 같은 것으로 이것을 읽는 것을 기대하고 있습니다) 나는 발견 된 행동조차도 일치하지 않을 수도있는 제안에 무게를 둔다. –

+0

귀하의 의견에 따라 제 질문이 업데이트되었습니다. – Giedrius

답변

0

최소한 로컬 로거 원하는 결과를 얻을 것이다 %logger를 사용하는 대신 %C{1}에 의해.

IoC에 대해서는 좀 더해야한다고 생각합니다. 이것에 대해 더 자세히 조사해야합니다 ...

+0

내가 인터넷에서 읽은 것에서 나는 당신의 IoC 컨테이너가 이미 모든 것을 수행한다고 추측한다. –

+0

맞다. 문제는 내 appender에서 loggingEvent.LoggerName 대신 loggingEvent.LocationInformation.ClassName을 사용하고 있었다는 것이다. (또는 언급 한대로 % C { 1} 대신에 % logger를 사용하십시오. – Giedrius

관련 문제