Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何按名称空间对log4net中的日志消息进行分组?_C#_Log4net_Ioc Container - Fatal编程技术网

C# 如何按名称空间对log4net中的日志消息进行分组?

C# 如何按名称空间对log4net中的日志消息进行分组?,c#,log4net,ioc-container,C#,Log4net,Ioc Container,我正在尝试实现自己的log4net appender,它将消息按名称空间分组。 问题是,我不能像我希望的那样让log4net记录位置信息 class Program { protected static IWindsorContainer container; static void Main(string[] args) { container = new WindsorContainer(); container.Kernel.Re

我正在尝试实现自己的log4net appender,它将消息按名称空间分组。 问题是,我不能像我希望的那样让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输出。我最初认为,可能是castle windsor造成了这样的问题,但正如结果所示,即使我手动创建logger实例,它仍然会记录基类名称。可能是任何人都有想法,如何强制log4net写实际的实例类名

更新

下面是使用的log4net配置:

更新2

如果有人需要这样的东西,下面是正在工作的appender实现:

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);
通过使用%logger而不是%C{1},您将至少获得本地记录器所需的结果


我认为对于国际奥委会来说,你需要做得更多一些。必须对此进行更多调查…

我们可以看看您的log4net.config吗?这是您想要的输出还是您得到的输出?从你所说的来看,这似乎是你想要的输出,但我想知道你得到的输出,特别是在init方面,我在阅读本文时希望它与你所说的相同,然后我提出一个可能与发现的行为不匹配的建议。我根据你的评论更新了我的问题,希望现在更清楚。从我在互联网上读到的内容来看,我猜您的IoC容器已经做了所有正确的事情。问题是我在附录中使用了loggingEvent.LocationInformation.ClassName而不是loggingEvent.LoggerName,或者正如您所提到的,在示例的配置中使用了%C{1}而不是%logger。
<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>
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
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);