log4net:如何区分同一UI线程上的不同形式?
log4net: How to distinguish between different forms on the same UI thread?
有没有办法(NDC、Properties,...?)让每个表单包含在所有 log4net 消息中的 name/id,这样我就可以区分所有日志消息中的表单?
我有很多服务方法等用于我所有的表格,我想看看例如由于用户以何种形式输入而调用服务(想想多个非模态相似形式(相同 class),运行 在同一个 UI 线程中,包含一个按钮,并且在按钮的 Click-Event,调用了一个服务方法。在服务方法内部,有日志记录调用。在日志消息中,我想要一个 属性 包含按钮在哪个表单实例中的信息被点击了)。
我不想修改所有的记录调用。 Web 中有关日志上下文/NDC 的示例都只讨论多个客户端/asp.net 请求等,而不是 1 个线程中的多个表单。
谢谢,
蒂姆
为此,请将表单的 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>
编辑:要保留多个值,请使用堆栈,如本单元测试中输出的那样:
Now in TestClass1 Now in 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);
}
}
}
}
有没有办法(NDC、Properties,...?)让每个表单包含在所有 log4net 消息中的 name/id,这样我就可以区分所有日志消息中的表单?
我有很多服务方法等用于我所有的表格,我想看看例如由于用户以何种形式输入而调用服务(想想多个非模态相似形式(相同 class),运行 在同一个 UI 线程中,包含一个按钮,并且在按钮的 Click-Event,调用了一个服务方法。在服务方法内部,有日志记录调用。在日志消息中,我想要一个 属性 包含按钮在哪个表单实例中的信息被点击了)。
我不想修改所有的记录调用。 Web 中有关日志上下文/NDC 的示例都只讨论多个客户端/asp.net 请求等,而不是 1 个线程中的多个表单。
谢谢, 蒂姆
为此,请将表单的 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>
编辑:要保留多个值,请使用堆栈,如本单元测试中输出的那样:
Now in TestClass1 Now in 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);
}
}
}
}