I found similar questions, but non of the answers worked.
Log4Net doesn't write anything in the log database and I don't really know how to find the error.
This is my config file:
<log4net>
<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=sqlServer;initial catalog=Logging;integrated security=false;persist security info=True;User ID=logUser;Password=logPassword" />
<commandText value="INSERT INTO dbo.myLogTable ([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>
</log4net>
It's actually a complete copy of the SQL Server example on the apache page. I've only changed the connection string. The connection itself should work fine, I've tested the connection string with a SqlConnection.
This is how I create the logging object and load the config:
public static class LogFactory
{
public const string Log4NetConfig = "log4net.config";
public static ILog GetLogger()
{
var uri = new Uri(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase), Log4NetConfig));
var configFile = new FileInfo(Path.GetFullPath(uri.LocalPath));
XmlConfigurator.ConfigureAndWatch(configFile);
ILog log = LogManager.GetLogger(typeof(LogFactory));
return log;
}
}
Logging itself:
private static readonly ILog Log = LogFactory.GetLogger();
[...]
Log.Info("Test 123");
Logging works fine if I replace the config with my usual "log to file" config, so I guess the error has to be somewhere in the config, but the config is the default example from the homepage.
Can you see an error somewhere?
you did not define when the appender should be used and also with bufferSize you postponed writing to db.
<log4net>
<root>
<level value="ALL" /> <!--send all logs to appenders-->
<appender-ref ref="AdoNetAppender" />
</root>
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
<bufferSize value="100" /> <!--THIS WILL POSTPONE DB WRITING UNTIL A BUFFER OF 100 LOG IS REACHED-->
<threshold value="INFO"/> <!--log when >= INFO -->
.....
</appender>
</log4net>
Final thoughts:
You are calling the log4net configurator every time you need a logger and this is not how you should do it.
It should be called only the first time when you start your app (static Main method) or website (global.asax applicationStart).
Then your classes should have the readonly ILog property:
private static ILog logger = LogManager.GetLogger(typeof(MyClass));
<bufferSize value="100" />
This mean that Log4Net will keep 100 records in memory before inserting into the database.
This is by design to limit round trip to the database. Try setting <bufferSize value="1" /> or maybe 0 could work.
While using AdoNetAppender, i am unable to write the log details into the database.
Following are the changes that has been done to make it a workable solution :
1) Use bufferSize value="1" or bufferSize value="0"
2) 'root' directory should be used before all the Appenders that has been used
Eg.
<root>
<level value="ALL"></level>
<appender-ref ref="AdoNetAppender"></appender-ref>
<appender-ref ref="RollingFileAppender"></appender-ref>
</root>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="mylogfile.txt" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %level %logger - %message%newline" />
</layout>
</appender>
<appender name="AdoNetAppender" 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=server_name; initial catalog=database_name;integrated security=false; persist security info=True;User ID=user_id;Password=password" />
<commandText value="INSERT INTO ErrorLog ([Logger]) VALUES (#logger)" />
<parameter>
<parameterName value="#logger" />
<dbType value="String" />
<size value="100" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%logger" />
</layout>
</parameter>
</appender>
</log4net>
Related
I have been using log4net to log to an Oracle database for the past few weeks and everything was working until I was told that Native Network Encryption had been turn on. This caused my logging to cease and I'm clueless on how to fix it. No errors are given, it just won't write to the DB. I am using the following logger.xml file:
<log4net>
<appender name="DebugAppender" type="log4net.Appender.DebugAppender">
<immediateFlush value="true" />
<layout type="log4net.Layout.SimpleLayout" />
</appender>
<appender name="AdoNetAppender_Oracle" type="log4net.Appender.AdoNetAppender">
<connectionType value="Oracle.ManagedDataAccess.Client.OracleConnection, Oracle.ManagedDataAccess, Version=4.121.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
<connectionStringName value="Payments" />
<commandText value="INSERT INTO CROWN.EOB_LOG (Datetime,Thread,Log_Level,Logger,Message) VALUES (:log_date, :thread, :log_level, :logger, :message)" />
<bufferSize value="1" />
<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>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="AdoNetAppender_Oracle" />
</root>
</log4net>
As I said this was working perfectly until NNE was turned on. The application I am using is a C# console app. Can anyone point me in the right direction?
I want to write to a log file and a database using log4net. However I only want to write to the database if the level is WARN.
I have tried Threshold, level and filter in my config file.
<log4net>
<root>
<appender-ref ref="ADONetAppender" />
<appender-ref ref="file" />
</root>
<appender name="ADONetAppender" type="log4net.Appender.ADONetAppender">
<filter type="log4net.Filter.LevelMatchFilter">
<levelToMatch value="WARN"/>
</filter>
<bufferSize value="100"/>
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<connectionString value="connString"/>
<commandText value="APP_Insert_File_Failure" />
<commandType value="StoredProcedure" />
<parameter>
<parameterName value="#FileName" />
<dbType value="String" />
<size value="255"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%property{FileName}" />
</layout>
</parameter>
<parameter>
<parameterName value="#FileFailure" />
<dbType value="String" />
<size value="255"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%property{FileFailure}" />
</layout>
</parameter>
</appender>
<appender name="file" type="log4net.Appender.RollingFileAppender">
<param name="File" value="C:\Temp" />
<appendToFile value="true" />
<rollingStyle value="Date" />
<datePattern value="yyyyMMdd" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %-5level %newline%message%newline%exception%newline" />
</layout>
</appender>
</log4net>
My C# code to run is
//Parameters for stored procedure
log4net.GlobalContext.Properties["FileName"] = Path.GetFileName(filename);
log4net.GlobalContext.Properties["FileFailure"] = "Testing 1 2 3;
log.Warn("Testing 1 2 3");
I use to populate the connString -
public static void SetUpDbConnection(string adoNetAppenderString, string newConnString)
{
log4net.Repository.ILoggerRepository repository = log4net.LogManager.GetRepository();
foreach (log4net.Appender.IAppender appender in repository.GetAppenders())
{
if (appender.Name.CompareTo(adoNetAppenderString) == 0 && appender is log4net.Appender.AdoNetAppender)
{
log4net.Appender.AdoNetAppender adoAppender = (log4net.Appender.AdoNetAppender)appender;
adoAppender.ConnectionString = System.IO.Path.Combine(adoAppender.ConnectionString, newConnString);
adoAppender.ActivateOptions();
}
}
}
It writes to the text file no problem, but nothing is appearing in the database.
I want it to write into the database when level = Warn
The problem was the connection string. I tried to change it dynamically, but that wan't working. I copied the the connection string straight into the config file and it worked.
Now I just have to figure out to be able to change the connection string dynamically.
Thanks anyway!
Found out what I was doing wrong when trying to change the connection string dynamically.
I changed -
adoAppender.ConnectionString = System.IO.Path.Combine(adoAppender.ConnectionString, newConnString);
to -
adoAppender.ConnectionString = newConnString;
In the SetUpDbConnection method.
I have been trying to log the error in my .Net website to the SQL database using Log4Net AdoNetAppender, but the error message are not getting logged in the database. Looks like the AdoNetAppender is not getting enabled or read. While debugging what I observed is that the Logger.Log shows all its properties values as false. i.e. IsErrorEnabled / IsDebugEnabled / IsFatalEnabled / IsInfoEnabled / IsWarnEnabled all as false.
Version of the log4net.dll I am using is 2.0.8.0
click here to view image of object properties
The logging.cs code is as below:
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
namespace Utility.Library
{
public class Logging
{
public static class Logger
{
public static ILog Log = LogManager.GetLogger(typeof(SharedMethods));
}
public static class LogException
{
private static StringBuilder sessionJobLogBuilder = new StringBuilder();
public static void LogError(string sMsg, Exception ex)
{
Logger.Log.Error(sMsg, ex);
sessionJobLogBuilder.AppendLine(sMsg + Environment.NewLine);
sessionJobLogBuilder.AppendLine(ex.ToString() + Environment.NewLine);
}
public static void LogInfo(string sMsg)
{
Logger.Log.Info(sMsg);
sessionJobLogBuilder.AppendLine(sMsg + Environment.NewLine);
}
}
}
}
And below is the app.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<log4net>
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
<bufferSize value="1" />
<connectionType value="System.Data.SqlClient.SqlConnection,
System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<connectionString value="data source=xxx\xxx;
initial catalog=xxx;integrated security=false;
persist security info=True;User ID=xxx;Password=xxx" />
<commandText value="EXECUTE [dbo].[WriteLogEntry] #App, #Module, #Ver, #Computer, #UserID, #Level, #Message, #Exception" />
<parameter>
<parameterName value="#App" />
<dbType value="String" />
<size value="30" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%App" />
</layout>
</parameter>
<parameter>
<parameterName value="#Module" />
<dbType value="String" />
<size value="200" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%Module" />
</layout>
</parameter>
<parameter>
<parameterName value="#Ver" />
<dbType value="String" />
<size value="20" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%Ver" />
</layout>
</parameter>
<parameter>
<parameterName value="#Computer" />
<dbType value="String" />
<size value="15" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%Computer" />
</layout>
</parameter>
<parameter>
<parameterName value="#UserID" />
<dbType value="String" />
<size value="30" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%UserID" />
</layout>
</parameter>
<parameter>
<parameterName value="#Level" />
<dbType value="Int32" />
<layout type="log4net.Layout.PatternLayout" />
</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="2000" />
<layout type="log4net.Layout.ExceptionLayout" />
</parameter>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="AdoNetAppender"/>
</root>
</log4net>
</configuration>
But the Logger.Log properties at all levels show as false.
From your comment I read you have a separate app.config file and the Logger class defined in a separate assembly.
An ASP.NET website only considers the web.config file.
Your app.config file doesn't get loaded, so the Log4net configuration doesn't get applied.
One way to solve this is to transform your app.config file into a separate Log4netconfiguration file and to load that explicitly.
Move the <log4net> ... </log4net> content from the app.config file to a separate file (by convention named Log4net.config) in the root of your website project.
The <log4net> element must be the root xml element in that file.
Remove the [assembly: log4net.Config.XmlConfigurator(Watch = true)] from your Logger project.
Add the following code to Application_Start in Global.asax of the website project to ensure that the log4net configuration gets loaded at website startup phase.
void Application_Start(object sender, EventArgs e)
{
ILoggerRepository repository = log4net.LogManager.GetRepository(Assembly.GetExecutingAssembly());
XmlConfigurator.Configure(repository, new FileInfo(Server.MapPath("log4net.config")));
// Remaining startup code.
}
I have the following log4net.config in the root of my website project (near web.config) with just a RollingFileAppender but the concept is the same.
<log4net>
<appender name="file" type="log4net.Appender.RollingFileAppender">
<param name="ImmediateFlush" value="true" />
<file value="Log.log" />
<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="ERROR" />
<appender-ref ref="file" />
</root>
</log4net>
With your AdoNetAppender setup in my Log4net.config the expected values for IsDebugEnabled, IsErrorEnabled, etc. get shown.
Summary:
Log4net's internal debug logging showed that the configuration file was not being loaded from the presumed location.
The combination of correcting this location (in the XmlConfigurator.Configure method call) and providing a configuration as shown above solved the problem.
I have multiple appenders in my log4net configuration, one for logging to a file, and the other using a stored procedure. I'm able to see the logging to a file, but the SQL data will show only after I click "Stop Site", see the image below:
So I've come to the conclusion that I may have to 'shutdown' the instance by doing the following: log4net.LogManager.GetLogger("SearchParamsLogger").Logger.Repository.Shutdown();
But in doing so, it seems to also shut down the other logger. How can I shut down only the ONE logger?
I have the following logger blocks:
<logger name="SearchParamsLogger">
<level value="DEBUG" />
<appender-ref ref="LogSearchParams" />
</logger>
<logger name="FileLogger">
<level value="DEBUG" />
<appender-ref ref="LogFile" />
</logger>
I have the following appenders in my .config:
<appender name="LogSearchParams" 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=MyServer\SQLEXPRESSPC;initial catalog=MyDatabase;integrated security=false;persist security info=True;User ID=DBUser;Password=MyPassword" />
<commandText value="InsertIManNrlLog" />
<commandType value="StoredProcedure" />
<parameter>
<parameterName value="#UserName"/>
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%property{uname}" />
</layout>
</parameter>
<parameter>
<parameterName value="#ObjectId" />
<dbType value="String" />
<size value="4000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message" />
</layout>
</parameter>
<parameter>
<parameterName value="#DeleteSpan" />
<dbType value="Int32" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%property{deleteSpan}" />
</layout>
</parameter>
<parameter>
<parameterName value="#LogLevel" />
<dbType value="String" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level" />
</layout>
</parameter>
</appender>
<appender name="LogFile" type="log4net.Appender.FileAppender">
<file value="application.log"/>
<appendToFile value="true"/>
<layout type="log4net.Layout.PatternLayout">
<header value="Logging Start
"/>
<footer value="Logging End
"/>
<conversionPattern value="%date | [%thread] %-5level %logger: %message%newline"/>
</layout>
</appender>
You can configure the number of messages the DBAppender will buffer before flushing them to the DB.
Your <bufferSize value="100" /> is the default example I found here, lower it and you should see the messages more often, you can even get immediate logging to the DB with the value 1 (or lower)
I have a webapp that I would like to use a different log4net config file when running under DEBUG mode compared to running under RELEASE mode.
I am using log4net version 2.0.3.
In my AssemblyInfo.cs class I have this code:
#if DEBUG
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4netDebug.xml", Watch = true)]
#else
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4netLive.xml", Watch = true)]
#endif
In my Global.asax.cs class I have this code:
log4net.Config.XmlConfigurator.Configure();
log = LogManager.GetLogger(typeof(GlobalApp));
(log is a public static member of GlobalApp.)
In my log4netDebug.xml file I have this code:
<?xml version="1.0" encoding="utf-8"?>
<!-- Configuration for logging using log4net-->
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net>
<!-- Show logging in the Visual Studio output window-->
<appender name="TraceAppender"
type="log4net.Appender.TraceAppender" >
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-6level - %message%newline" />
</layout>
</appender>
<appender
name="AdoNetAppender"
type="log4net.Appender.AdoNetAppender">
<threshold>INFO</threshold>
<bufferSize
value="1" />
<connectionType
value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<connectionString value="data source=BLAH;initial catalog=BLAH;integrated security=True;persist security info=True" />
<commandText value="INSERT INTO Logs ([Date],[Thread],[Source],[Level], [Logger],[Message],[Exception],[HostName]) VALUES (#log_date, #thread, 'LOG SOURCE',#log_level, #logger, #message, #exception, #hostname)" />
<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="#hostname" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%property{log4net:HostName}" />
</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="-1" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message" />
</layout>
</parameter>
<parameter>
<parameterName value="#exception" />
<dbType value="String" />
<size value="-1" />
<layout type="log4net.Layout.ExceptionLayout" />
</parameter>
</appender>
<root>
<level value="ALL" />
<!-- Show logging in the Visual Studio output window-->
<appender-ref ref="TraceAppender" />
<appender-ref ref="AdoNetAppender" />
</root>
</log4net>
</configuration>
I have tested this config script and it works if I place it in my web.config file.
The log4netDebug.xml file has the Copy always property set.
When I try to do something like this:
System.IO.FileInfo fi = new System.IO.FileInfo("Log4NetDebug.xml");
log4net.Config.XmlConfigurator.ConfigureAndWatch(fi);
This doesn't work either.
I have read several stackoverflow and other web pages that describe how to do this and I seem to be doing what they recommend doing but it still deson't seem to work.
Any ideas why?
If you look at the Constructor for the FileInfo class, you will see that it expects The fully qualified name of the new file, or the relative file name..
So when you do this System.IO.FileInfo fi = new System.IO.FileInfo("Log4NetDebug.xml"); you need to specify the full path to the file.
As this is in a web app, you probably want something like this:
var logFile = new FileInfo(Path.Combine(HttpRuntime.BinDirectory, "Log4NetDebug.xml"));