How can I vary the behavior of an appender by logger - c#

I have an appender that calls a stored procedure to to write a log record. It looks like this (trimmed for brevity):
<log4net>
<root>
<level value="WARN" />
<appender-ref ref="ElsAppender" />
</root>
<appender name="LogAppender" type="LoggerAssembly.Appender, LoggerAssembly">
<bufferSize value="1" />
<reconnectonerror value="True" />
<parameter>
<parameterName value="#EntryDate" />
<dbType value="DateTime" />
<layout type="log4net.Layout.RawTimeStampLayout" />
</parameter>
<parameter>
<parameterName value="#message" />
<dbType value="String" />
<size value="40000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message" />
</layout>
</parameter>
</appender>
</log4net>
Note the size field of the message parameter is set to 40,000.
I have a logger however where I need the message length to be much longer. How do I change this setting for that specific logger. I tried cloning the LogAppender and changing the size value, like this:
<log4net>
<root>
<level value="WARN" />
<appender-ref ref="LogAppender" />
</root>
<logger name="SpecialLogger">
<level value="INFO" />
<appender-ref ref="SpecialLogAppender" />
</logger>
<appender name="LogAppender" type="LoggerAssembly.Appender, LoggerAssembly">
<bufferSize value="1" />
<reconnectonerror value="True" />
<parameter>
<parameterName value="#EntryDate" />
<dbType value="DateTime" />
<layout type="log4net.Layout.RawTimeStampLayout" />
</parameter>
<parameter>
<parameterName value="#message" />
<dbType value="String" />
<size value="40000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message" />
</layout>
</parameter>
</appender>
<appender name="SpecialLogAppender" type="LoggerAssembly.Appender, LoggerAssembly">
<bufferSize value="1" />
<reconnectonerror value="True" />
<parameter>
<parameterName value="#EntryDate" />
<dbType value="DateTime" />
<layout type="log4net.Layout.RawTimeStampLayout" />
</parameter>
<parameter>
<parameterName value="#message" />
<dbType value="String" />
<size value="400000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message" />
</layout>
</parameter>
</appender>
</log4net>
but that results in the message from the SpecialLogger being logged twice, once by the LogAppender and once by the SpecialLogAppender. Any ideas?

You need to add additivity="false" to your special logger definition:
<logger name="SpecialLogger" additivity="false">
<level value="INFO" />
<appender-ref ref="SpecialLogAppender" />
</logger>

You need to add a suitable <filter> element to your log4net appender(s). See
http://logging.apache.org/log4net/release/manual/configuration.html#filters
http://logging.apache.org/log4net/release/sdk/log4net.Filter.html
http://logging.apache.org/log4net/release/sdk/index.html
Log4net appenders are checked in document order, so your special appender needs to precede the default appender. Then something like this ought to do yo:
<appender name="SpecialAppender" type="log4net.Appender.FileAppender">
<file value="log.txt" />
<filter type="log4net.Filter.LoggerMatchFilter">
<loggerToMatch value="your-logger-name-here">
<acceptOnMatch="true"
</filter>
<layout type="log4net.Layout.SimpleLayout" />
</appender>
<appender name="DefaultAppender" type="log4net.Appender.FileAppender">
<file value="log.txt" />
<filter type="log4net.Filter.LoggerMatchFilter">
<loggerToMatch value="your-logger-name-here">
<acceptOnMatch="false"
</filter>
<layout type="log4net.Layout.SimpleLayout" />
</appender>

Related

log4net troubleshooting with Database in C# ConsoleApp

I am new to logging in .Net and was trying to learn log4net as a logging tool. I am running into a problem which is
I have created a log4net config file and trying to add values of logs into SSMS but values are not populating as expected. Here is my log4net config file
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %5level %logger.%method [%line] - %message%newline" />
</layout>
</appender>
<appender name="DatabaseAppender" type="ToolsCommon.logging.AdoNetAppender">
<filter type="log4net.Filter.LoggerMatchFilter">
<loggerToMatch value="Startup" />
<acceptOnMatch value="false" />
</filter>
<bufferSize value="1" />
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />0
<connectionString value="dynamicly created" />
<commandText value="INSERT INTO Log ([EntryID],[Message],[TimeStamp],[SeverityId]) VALUES (#entryid, #message, #log_date, #severityId)" />
<parameter>
<parameterName value="#entryid" />
<dbType value="String" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%entryid" />
</layout>
</parameter>
<parameter>
<parameterName value="#log_date" />
<dbType value="DateTime" />
<layout type="log4net.Layout.RawTimeStampLayout" />
</parameter>
<parameter>
<parameterName value="#message" />
<dbType value="String" />
<size value="4000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message" />
</layout>
</parameter>
<parameter>
<parameterName value="#severityId" />
<dbType value="Int64" />
<layout type="log4net.Layout.PatternLayout">
<converter>
<name value="severityId" />
<type value="ToolsCommon.logging.QCSeverityConverter" />
</converter>
<conversionPattern value="%severityId" />
</layout>
</parameter>
</appender>
<appender name="FileAppender" type="ToolsCommon.logging.CustomFileAppender">
<file value="%property{logFilePath}/ToolLog.log" />
<appendToFile value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %5level %logger.%method [%line] - %message%newline" />
</layout>
</appender>
<root>
<level value="ALL"/>
<appender-ref ref="ConsoleAppender" />
<appender-ref ref="DatabaseAppender" />
<appender-ref ref="FileAppender" />
</root>
</log4net>
Issue with above code is EntryID is not getting populated as expected rather it gets populated with some other value which I have no idea where that value is coming from.
Is there any way I can debug this and find out how EntryID value is populated?
I tried debugging it but since this is a config file I cannot debug it using Visual Studios debugger. I think this is getting invoked as and when logger is called but I am not sure where EntryId value is coming from? I am expecting any clue so I can figure out how EntryId is getting populated.
You can turn on internal debugging with:
<configuration>
<appSettings>
<add key="log4net.Internal.Debug" value="true"/>
</appSettings>
</configuration>
see here for more info.
Please edit your configuration file according to this format:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,
log4net-net-1.0" />
</configSections>
<log4net>
..
</log4net>
</configuration>

log4net not saving in Database in ASP.NET

I have problem with log4net. In localhost works fine and save in the database (Production1), then in QA not save the log in the same database (Production1)
AssemblyInfo.cs
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Web.config", Watch = true)]
Web.config
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" requirePermission="false" />
</configSections>
<!-- Log4Net -->
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="wsaopc.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="1024KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
</appender>
<appender name="debug" type="log4net.Appender.DebugAppender">
<immediateFlush value="true" />
<layout type="log4net.Layout.SimpleLayout" />
</appender>
<appender name="sql" type="log4net.Appender.AdoNetAppender">
<bufferSize value="1" />
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<connectionStringName value="CSLog4Net" />
<commandText value="INSERT INTO aopc_sce_ws_log (wslog_fecha, wslog_tarea, wslog_nivel,wslog_logger, wslog_mensaje, wslog_excepcion) VALUES (#log_date, #thread, #log_level, #logger, #message, #exception)" />
<parameter>
<parameterName value="#log_date" />
<dbType value="DateTime" />
<layout type="log4net.Layout.RawTimeStampLayout" />
</parameter>
<parameter>
<parameterName value="#thread" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%thread" />
</layout>
</parameter>
<parameter>
<parameterName value="#log_level" />
<dbType value="String" />
<size value="50" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level" />
</layout>
</parameter>
<parameter>
<parameterName value="#logger" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%logger" />
</layout>
</parameter>
<parameter>
<parameterName value="#message" />
<dbType value="String" />
<size value="4000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message" />
</layout>
</parameter>
<parameter>
<parameterName value="#exception" />
<dbType value="String" />
<size value="2000" />
<layout type="log4net.Layout.ExceptionLayout" />
</parameter>
</appender>
<logger name="WS">
<level value="ALL" />
<appender-ref ref="sql" />
<appender-ref ref="debug" />
<appender-ref ref="RollingFileAppender" />
</logger>
<logger name="EF">
<level value="ALL" />
<appender-ref ref="RollingFileAppenderEF" />
</logger>
<logger name="BD">
<level value="ALL" />
<appender-ref ref="sql" />
</logger>
</log4net>
</configuration>
I review in QA and have the same web.config.

Log4net with MySql not logging

In properties of log I noticied all the level logs (IsErrorEnabled) have value false, in log.Logger.Repository.Configured has value false.
I dont know if LogManager can't find the log4net node in app.config or there's something wrong in xml.
I'm trying:
[TestMethod]
public void TestLog()
{
ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
log.Debug("teste");
}
Before, I used Sql and all worked perfectly, but since I changed to MySql the logs dont work anymore.
Can anyone help me?
This is my XML
<log4net>
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
<bufferSize value="1" />
<connectionType value="MySql.Data.MySqlClient.MySqlConnection, MySql.Data" />
<connectionString value="Server=localserver;Database=DataBaseName;Uid=user;Pwd=pass;" />
<commandText value="INSERT INTO LogServico ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (#log_date, #thread, #log_level, #logger, #message, #exception);" />
<parameter>
<parameterName value="#log_date" />
<dbType value="DateTime" />
<layout type="log4net.Layout.RawTimeStampLayout" />
</parameter>
<parameter>
<parameterName value="#thread" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%thread" />
</layout>
</parameter>
<parameter>
<parameterName value="#log_level" />
<dbType value="String" />
<size value="50" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level" />
</layout>
</parameter>
<parameter>
<parameterName value="#logger" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%logger" />
</layout>
</parameter>
<parameter>
<parameterName value="#message" />
<dbType value="String" />
<size value="4000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message" />
</layout>
</parameter>
<parameter>
<parameterName value="#exception" />
<dbType value="String" />
<size value="2000" />
<layout type="log4net.Layout.ExceptionLayout" />
</parameter>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="AdoNetAppender" />
</root>
</log4net>
I'm find the errors.
Thanks [stuartd] for reply.
First I forget the XmlConfigurator.Configure()
After I enable the log4net debug by:
<add key="log4net.Internal.Debug" value="true"/>
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add
name="textWriterTraceListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="C:\tmp\log4net.txt" />
</listeners>
</trace>
</system.diagnostics>
So Log4net logged the error:
The command text was wrong
"INSERT INTO LogServico ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (#log_date, #thread, #log_level, #logger, #message, #exception);"
The rigth way is:
"INSERT INTO LogServico (Date,Thread,Level,Logger,Message,Exception) VALUES (?log_date, ?thread, ?log_level, ?logger, ?message, ?exception);"
And change all parameter name to ?name like:
<parameterName value="?log_date" />
So my final app.config is:
<log4net>
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
<bufferSize value="1" />
<connectionType value="MySql.Data.MySqlClient.MySqlConnection, MySql.Data" />
<connectionString value="Server=127.0.0.1;Database=dbname;Uid=user;Pwd=pass;" />
<commandText value="INSERT INTO LogServico (Date,Thread,Level,Logger,Message,Exception) VALUES (?log_date, ?thread, ?log_level, ?logger, ?message, ?exception);" />
<parameter>
<parameterName value="?log_date" />
<dbType value="DateTime" />
<layout type="log4net.Layout.RawTimeStampLayout" />
</parameter>
<parameter>
<parameterName value="?thread" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%thread" />
</layout>
</parameter>
<parameter>
<parameterName value="?log_level" />
<dbType value="String" />
<size value="50" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level" />
</layout>
</parameter>
<parameter>
<parameterName value="?logger" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%logger" />
</layout>
</parameter>
<parameter>
<parameterName value="?message" />
<dbType value="String" />
<size value="4000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message" />
</layout>
</parameter>
<parameter>
<parameterName value="?exception" />
<dbType value="String" />
<size value="2000" />
<layout type="log4net.Layout.ExceptionLayout" />
</parameter>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="AdoNetAppender" />
</root>
</log4net>
My funcional method test:
[TestMethod]
public void TestLog()
{
log4net.Config.XmlConfigurator.Configure();
ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
log.Error("test", new Exception("test"));
}
It's important remember all that is to log in mysql. In Sql the command text can use [namecolumn] and the parameter has #nameparameter
There are a number of possible reasons:
Your log4net config file is not set to "Copy Local" on build
You are not initialising log4net (ie calling XmlConfigurator.Configure or using an assembly attribute).
Your config is invalid.
As you say this worked previously, then it seems probable that it is 3, and your config is invalid.

Configuring log4net to write on a database

I am trying to configure log4net to log in the database, it is already configured to write in a file, but when I change the appender to the database it doesn't do anything. The connection to the database is ok because if I change the password I can see an entry in the eventviewer saying the password is wrong.
Here it is my app.config:
<log4net>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date{ABSOLUTE} [%thread] %level %logger - %message%newlineExtra Info: %property{testProperty}%newline%exception"/>
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="INFO"/>
<levelMax value="FATAL"/>
</filter>
</appender>
<securitycontext type="log4net.Util.WindowsSecurityContext">
<credentials value="Process">
</credentials>
</securitycontext>
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
<bufferSize value="100" />
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<connectionString value="data source=PCKMA0348\SQLEXPRESS;initial catalog=dbServicesLog;User ID='rb';Password='Test1234';multipleactiveresultsets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
<commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (#log_date, #thread, #log_level, #logger, #message, #exception)" />
<parameter>
<parameterName value="#log_date" />
<dbType value="DateTime" />
<layout type="log4net.Layout.RawTimeStampLayout" />
</parameter>
<parameter>
<parameterName value="#thread" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%thread" />
</layout>
</parameter>
<parameter>
<parameterName value="#log_level" />
<dbType value="String" />
<size value="50" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level" />
</layout>
</parameter>
<parameter>
<parameterName value="#logger" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%logger" />
</layout>
</parameter>
<parameter>
<parameterName value="#message" />
<dbType value="String" />
<size value="2000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message" />
</layout>
</parameter>
<parameter>
<parameterName value="#exception" />
<dbType value="String" />
<size value="1000" />
<layout type="log4net.Layout.ExceptionLayout" />
</parameter>
</appender>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="mylogfile.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="5" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %level %logger - %message%newline" />
</layout>
</appender>
<root>
<level value="FATAL"/>
<appender-ref ref="AdoNetAppender"/>
</root>
<logger name="Log4NetTest.OtherClass">
<level value="DEBUG"/>
<appender-ref ref="AdoNetAppender"/>
</logger>
</log4net>
Any guess?
Do I need to create the database and the table manually or it will be automatically created?
You need to create the database and the Log table yourself.
If you want to diagnose possible issues with log4net, you can create a diagnostic trace by adding this to your .config file:
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add
name="textWriterTraceListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="C:\whatever\your\path\is\log4net.txt" />
</listeners>
</trace>
</system.diagnostics>
and adding the debug switch:
<appSettings>
<add key="log4net.Internal.Debug" value="true"/>
</appSettings>

File and Database multiple configuration for log4net

I have Web API that needs to write log data, both to a file and to the database.
Is it possible to configure such a setup? I am trying to understand ILoggerRepository but I am confused.
Can someone give me the some tips on how to configure it and how to use it in application?
It sounds to me like you want to write to two different style appenders at the same time.
The good news is that this is built right into the log4Net library.
What you want to do so configure you configuration file to two different appenders. A file Appender and a Database appender.
Examples of the different appenders can be found here.
http://logging.apache.org/log4net/release/config-examples.html
Here is an example of an web.config that i whipped together. You are going to have to tweak it to get it to work for you, but it will get you on the right start.
One last point, your log4net configuration does not have to be in your web.config but IMHO it just makes things easier to get started. Worry about breaking it out once your web.config starts to get a little cluttered.
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<log4net>
<appender name="FileAppender" type="log4net.Appender.FileAppender">
<file value="log-file.txt" />
<appendToFile value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
<bufferSize value="100" />
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<connectionString value="data source=[database server];initial catalog=[database name];integrated security=false;persist security info=True;User ID=[user];Password=[password]" />
<commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (#log_date, #thread, #log_level, #logger, #message, #exception)" />
<parameter>
<parameterName value="#log_date" />
<dbType value="DateTime" />
<layout type="log4net.Layout.RawTimeStampLayout" />
</parameter>
<parameter>
<parameterName value="#thread" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%thread" />
</layout>
</parameter>
<parameter>
<parameterName value="#log_level" />
<dbType value="String" />
<size value="50" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level" />
</layout>
</parameter>
<parameter>
<parameterName value="#logger" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%logger" />
</layout>
</parameter>
<parameter>
<parameterName value="#message" />
<dbType value="String" />
<size value="4000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message" />
</layout>
</parameter>
<parameter>
<parameterName value="#exception" />
<dbType value="String" />
<size value="2000" />
<layout type="log4net.Layout.ExceptionLayout" />
</parameter>
</appender>
<root>
<level value="INFO" />
<appender-ref ref="AdoNetAppender" />
<appender-ref ref="FileAppender" />
</root>
</log4net>
</configuration>

Categories

Resources