0

有没有办法(NDC,属性,...?)在所有 log4net 消息中包含每个表单的名称/ID,所以我可以区分所有日志消息中的表单?

我在所有表单中都使用了许多服务方法等,并且我希望看到例如由于用户以什么形式输入而调用了服务(想想多个非模态的类似表单(同一类),在同一个UI线程,包含一个按钮,在按钮的Click-Event中,调用了一个服务方法。在服务方法内部,有日志调用。在日志消息中,我想有一个包含信息的属性正是在哪个表单实例中单击了按钮)。

我不想修改所有日志记录调用。网络上的日志上下文/ NDC 示例都只讨论了多个客户端/ asp.net 请求等,而不是1 个线程中的多个表单。

谢谢,蒂姆

4

1 回答 1

0

为此,请将表单的 Activated 事件中的属性设置为您要记录的内容:

private void Form1_Activated(object sender, System.EventArgs e)
{
    // for example
    log4net.GlobalContext.Properties["Name"] = this.GetType().Name;
    log4net.GlobalContext.Properties["Id"] = this.Id;
}

在您的日志记录配置中,您可以为每个附加程序引用 PatternLayout 中的属性:

<layout type="log4net.Layout.PatternLayout">
  <conversionPattern value="%property{Name} : %property{Id} : [%level]- %message%newline" />
</layout>

编辑:要保留多个值,请使用堆栈,如本单元测试中的输出:

现在在 TestClass1 现在在 TestClass2

using log4net.Appender;
using log4net.Config;
using log4net.Core;
using log4net.Layout;
using NUnit.Framework;

namespace log4net.Tests
{
    [TestFixture] // A NUnit test
    public class log4net_Stacks
    {
        [SetUp]
        public void Setup()
        {
            ConsoleAppender ca = new ConsoleAppender
            {
                Layout = new PatternLayout("%property{demo}"),
                Threshold = Level.All
            };

            ca.ActivateOptions();
            BasicConfigurator.Configure(ca);
        }

        [Test]
        public void Stacks_Demo()
        {
            new TestClass1().Method1();
            LogManager.GetLogger("logger").Debug("");
            ThreadContext.Stacks["demo"].Clear();
        }

        private abstract class BaseTestClass
        {
            protected static void AddToStack(string message)
            {
                ThreadContext.Stacks["demo"].Push(message);
            }
        }

        private class TestClass1 : BaseTestClass
        {
            public void Method1()
            {
                AddToStack("Now in " + GetType().Name);
                var tc2 = new TestClass2();
                tc2.Method2();
            }
        }

        private class TestClass2 : BaseTestClass
        {
            public void Method2()
            {
                AddToStack("Now in " + GetType().Name);
            }
        }    
    }
}
于 2015-08-24T12:21:10.717 回答