Log4net 使用自定义附加程序将自定义对象写入 sql 数据库?
Log4net writing custom object to sql database using custom appender?
使用 SQL Server 2012 这是我的 table:
CREATE TABLE [dbo].[Test]
(
[One] [VARCHAR](50) NOT NULL,
[Two] [VARCHAR](50) NOT NULL
) ON [PRIMARY]
这是我的附加程序:
<appender name="TestAppender" type="log4net.Appender.AdoNetAppender">
<bufferSize value="1" />
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<connectionString value="data source=localhost;initial catalog=ApplicationLog;integrated security=false;persist security info=True;User ID=someUser;Password=somePassword" />
<commandText value="INSERT INTO [dbo].[Test] ([One],[Two]) VALUES (@one, @two)" />
<parameter>
<parameterName value="@one"/>
<dbType value="String"/>
<size value="50"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%one"/>
</layout>
</parameter>
<parameter>
<parameterName value="@two"/>
<dbType value="String"/>
<size value="50"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%two"/>
</layout>
</parameter>
</appender>
以下是我在代码中获取记录器实例并尝试写入的方法:
private static readonly ILog TestLogger = LogManager.GetLogger("TestAppender");
TestLogger.Info(new Test {One = "someOne", Two = "someTwo"});
这是我的测试class:
public class Test
{
public string One { get; set; }
public string Two { get; set; }
}
完成此操作后,我的 table 中有一条记录,列的内容是:
One: "one" Two: "12wo"
“12wo”到底是什么?我知道我在这里遗漏了一些东西。我认为我的转换模式是错误的。我试过这个:
<conversionPattern value="%property{one}"/>
..但这也不起作用。我是否必须编写自定义模式布局或其他内容?谢谢。
This site 给我指明了正确的方向。
我必须创建自定义 LayoutPattern 和 PatternConverter 才能将我的对象成功写入日志。原来我在数据库中得到的奇怪的“12wo”文本是因为转换模式使用 printf c 样式语法。无论如何,这是一些代码。
public class TestLayoutPattern : PatternLayout
{
public TestLayoutPattern()
{
AddConverter(new ConverterInfo
{
Name = "test",
Type = typeof (TestConverter)
});
}
}
public class TestConverter : PatternConverter
{
protected override void Convert(System.IO.TextWriter writer, object state)
{
if (state == null)
{
writer.Write(SystemInfo.NullText);
return;
}
var loggingEvent = state as LoggingEvent;
if (loggingEvent == null)
throw new NullReferenceException("loggingEvent");
var test = loggingEvent.MessageObject as Test;
if (test == null)
{
writer.Write(SystemInfo.NullText);
}
else
{
switch (Option.ToLower())
{
case "one":
writer.Write(test.One);
break;
case "two":
writer.Write(test.Two);
break;
default:
writer.Write(SystemInfo.NullText);
break;
}
}
}
}
以下是按名称获取记录器实例的方法:
private static readonly ILog TestLogger = LogManager.GetLogger("TestLogger");
以下是将测试对象写入日志的方法。
TestLogger.Info(new Test {One = "field one", Two = "field two"});
下面是如何在 web.config 中定义参数。
<parameter>
<parameterName value="@one" />
<dbType value="String" />
<size value="50" />
<layout type="MyApp.TestLayoutPattern">
<conversionPattern value="%test{one}" />
</layout>
</parameter>
另一件需要注意的事情是 web.config 的根和记录器部分。在根部分是默认记录器定义其级别集的地方。我可以在记录器部分定义我的自定义 TestLogger,它将引用如下所示的附加程序。这允许我按名称访问 TestLogger,如上所示。
<root>
<level value="ALL"/>
<appender-ref ref="ADONetAppender"/>
</root>
<logger additivity="false" name="TestLogger">
<level value="ALL"/>
<appender-ref ref="TestAppender" />
</logger>
我还发现,如果您只想向默认的 ADONetAppender 添加一些属性(并向 table 添加一些字段),您可以改用 log4net.ThreadContext 来设置这些属性像这样:
log4net.ThreadContext.Properties["MyCustomPrperty"] = value;
然后在参数部分下的 web.config 中,您可以像这样访问 属性:
<parameter>
<parameterName value="@myCustomProperty"/>
<dbType value="String"/>
<layout type="log4net.Layout.RawPropertyLayout">
<key value="MyCustomProperty" />
</layout>
</parameter>
使用 SQL Server 2012 这是我的 table:
CREATE TABLE [dbo].[Test]
(
[One] [VARCHAR](50) NOT NULL,
[Two] [VARCHAR](50) NOT NULL
) ON [PRIMARY]
这是我的附加程序:
<appender name="TestAppender" type="log4net.Appender.AdoNetAppender">
<bufferSize value="1" />
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<connectionString value="data source=localhost;initial catalog=ApplicationLog;integrated security=false;persist security info=True;User ID=someUser;Password=somePassword" />
<commandText value="INSERT INTO [dbo].[Test] ([One],[Two]) VALUES (@one, @two)" />
<parameter>
<parameterName value="@one"/>
<dbType value="String"/>
<size value="50"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%one"/>
</layout>
</parameter>
<parameter>
<parameterName value="@two"/>
<dbType value="String"/>
<size value="50"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%two"/>
</layout>
</parameter>
</appender>
以下是我在代码中获取记录器实例并尝试写入的方法:
private static readonly ILog TestLogger = LogManager.GetLogger("TestAppender");
TestLogger.Info(new Test {One = "someOne", Two = "someTwo"});
这是我的测试class:
public class Test
{
public string One { get; set; }
public string Two { get; set; }
}
完成此操作后,我的 table 中有一条记录,列的内容是:
One: "one" Two: "12wo"
“12wo”到底是什么?我知道我在这里遗漏了一些东西。我认为我的转换模式是错误的。我试过这个:
<conversionPattern value="%property{one}"/>
..但这也不起作用。我是否必须编写自定义模式布局或其他内容?谢谢。
This site 给我指明了正确的方向。
我必须创建自定义 LayoutPattern 和 PatternConverter 才能将我的对象成功写入日志。原来我在数据库中得到的奇怪的“12wo”文本是因为转换模式使用 printf c 样式语法。无论如何,这是一些代码。
public class TestLayoutPattern : PatternLayout
{
public TestLayoutPattern()
{
AddConverter(new ConverterInfo
{
Name = "test",
Type = typeof (TestConverter)
});
}
}
public class TestConverter : PatternConverter
{
protected override void Convert(System.IO.TextWriter writer, object state)
{
if (state == null)
{
writer.Write(SystemInfo.NullText);
return;
}
var loggingEvent = state as LoggingEvent;
if (loggingEvent == null)
throw new NullReferenceException("loggingEvent");
var test = loggingEvent.MessageObject as Test;
if (test == null)
{
writer.Write(SystemInfo.NullText);
}
else
{
switch (Option.ToLower())
{
case "one":
writer.Write(test.One);
break;
case "two":
writer.Write(test.Two);
break;
default:
writer.Write(SystemInfo.NullText);
break;
}
}
}
}
以下是按名称获取记录器实例的方法:
private static readonly ILog TestLogger = LogManager.GetLogger("TestLogger");
以下是将测试对象写入日志的方法。
TestLogger.Info(new Test {One = "field one", Two = "field two"});
下面是如何在 web.config 中定义参数。
<parameter>
<parameterName value="@one" />
<dbType value="String" />
<size value="50" />
<layout type="MyApp.TestLayoutPattern">
<conversionPattern value="%test{one}" />
</layout>
</parameter>
另一件需要注意的事情是 web.config 的根和记录器部分。在根部分是默认记录器定义其级别集的地方。我可以在记录器部分定义我的自定义 TestLogger,它将引用如下所示的附加程序。这允许我按名称访问 TestLogger,如上所示。
<root>
<level value="ALL"/>
<appender-ref ref="ADONetAppender"/>
</root>
<logger additivity="false" name="TestLogger">
<level value="ALL"/>
<appender-ref ref="TestAppender" />
</logger>
我还发现,如果您只想向默认的 ADONetAppender 添加一些属性(并向 table 添加一些字段),您可以改用 log4net.ThreadContext 来设置这些属性像这样:
log4net.ThreadContext.Properties["MyCustomPrperty"] = value;
然后在参数部分下的 web.config 中,您可以像这样访问 属性:
<parameter>
<parameterName value="@myCustomProperty"/>
<dbType value="String"/>
<layout type="log4net.Layout.RawPropertyLayout">
<key value="MyCustomProperty" />
</layout>
</parameter>