Log4net: Multiple configuration files but only one actually used - log4net

I am trying to refactor a little bit outdated code and can not find solution for log4net logs: I have multiple project each one of them defined it own log4net logger like this:
(using Common.Logging.Log4net.Universal and Common.Logging.Core and Common.Logging, log4net version 2.0.12.0)
app.config
...
...
<configSections>
<sectionGroup name="common">
<section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
</sectionGroup>
</configSections>
<common>
<logging>
<factoryAdapter type="Common.Logging.Log4Net.Universal.Log4NetFactoryAdapter, Common.Logging.Log4Net.Universal" />
</logging>
</common>
<appSettings>
<add key="log4net.Config" value="Current.Project.Unique.Name.log4net.config" />
<add key="log4net.Config.Watch" value="True" />
</appSettings>
...
...
and actual Current.Project.Unique.Name.log4net.config file:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net>
<appender name="CurrentProjectUniqueAppenderName" type="log4net.Appender.RollingFileAppender">
<file value="LogFolder\Current.Project.Unique.Name.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="1MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="CurrentProjectUniqueAppenderName" />
</root>
</log4net>
</configuration>
and in code I am trying to use this logger like this:
private static readonly ILog Logger = LogManager.GetCurrentClassLogger();
private void function1()
{
Logger.Debug("I am logging here");
}
so it look like everything OK and should work but actually what happens that only 'Startup project' actually reading (?) and using xxx.log4net.configuration file (it's own) and no other project is reading or using they <project.name>.log4net.configuration file.
Why is this ? How I can configure log4net so each project will use it own configuration file and only fallback to startup-project configuration in case it own is not defined ?

Related

Log4net doesn't log to Application Insights

I'm using log4net for my MVC application. The log4net.config file is independent from web.config. I added ApplicationInsights.Log4NetAppender to my UI project and moved the aiAppender from web.config to log4net.config. Somehow the application is able to log data into the Logs.txt, but it doesn't log to ApplicationInsights.
Please help me to figure out this issue.
Here is my log4net.config:
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender" >
<file value="App_Data/Logs/Logs.txt" />
<encoding value="utf-8" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10000KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5level %date [%-5.5thread] %-40.40logger - %message%newline" />
</layout>
</appender>
<appender name="aiAppender" type="Microsoft.ApplicationInsights.Log4NetAppender.ApplicationInsightsAppender, Microsoft.ApplicationInsights.Log4NetAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5level %date [%-5.5thread] %-40.40logger - %message%newline" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="RollingFileAppender" />
<appender-ref ref="aiAppender" />
</root>
</log4net>
The InstrucmentationKey for applicationinsights is reading from appsettings.
TelemetryConfiguration.Active.InstrumentationKey = WebConfigurationManager.AppSettings["InstrumentationKey"];
In AdaptiveSamplingTelemetryProcessor, I'm using adpative sampling.
<Add Type="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.AdaptiveSamplingTelemetryProcessor, Microsoft.AI.ServerTelemetryChannel">
<MaxTelemetryItemsPerSecond>5</MaxTelemetryItemsPerSecond>
<ExcludedTypes>Event</ExcludedTypes>
</Add>
I could see all dependencies and requests get logged on ApplicationInsights, but couldn't find any data from log4net.
If the problem is in log4net, you can best enable log4net internal debugging:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="log4net.Internal.Debug" value="true"/>
</appSettings>
</configuration>
And write it to file:
<configuration>
...
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add
name="textWriterTraceListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="C:\tmp\log4net.txt" />
</listeners>
</trace>
</system.diagnostics>
...
</configuration>
If there is any exception you will find it in the log file. It could also be that the AI logger uses buffering, or the application insights is buffering and not flushed when your application exits.
more on Log4net Troubleshooting
flush application insights when your ASP.NET Core application exits
This issue drove me nuts for hours.
You need to add an appender to log4net so it can write to application insights:
<appender name="aiAppender" type="Microsoft.ApplicationInsights.Log4NetAppender.ApplicationInsightsAppender, Microsoft.ApplicationInsights.Log4NetAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message%newline"/>
</layout>
</appender>
Next set the key or connection string in your startup so log4net can use it. The updated code for .NET 5 / 6 is:
services.AddApplicationInsightsTelemetry(new ApplicationInsightsServiceOptions
{
ConnectionString = Configuration["ApplicationInsights:ConnectionString"],
EnableActiveTelemetryConfigurationSetup = true
});
Full info here.

Log4Net not creating a log file

I am using log4net to log the error in my application.But the log file is not getting created.As far as I can see,the code is fine.
Web.config code
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<log4net>
<appender name="Console" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<!-- Pattern to output the caller's file name and line number -->
<conversionPattern value="%5level [%thread] (%file:%line) - %message%newline" />
</layout>
</appender>
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<file value="C:\Demo\example.log" />
<appendToFile value="true" />
<maximumFileSize value="100KB" />
<maxSizeRollBackups value="2" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level %thread %logger - %message%newline" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="Console" />
<appender-ref ref="RollingFile" />
</root>
</log4net>
In the AssemblyInfo.cs file,I have added the following code
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Web.config", Watch = true)]
In the class where I want to track the errors,I have added the following code
private static readonly ILog logger = LogManager.GetLogger(typeof(ProviderRepository));
I am using the logger as so in the catch block.
logger.Error(Ex.Message);
But I dont see the Log file.Am I doing something wrong here?
You should check if your apppool user has access to C:\Demo\, next you can enable log4net internal debugging which will tell you if there is any problem in your configuration or file access etc:
<configuration>
...
<appSettings>
<add key="log4net.Internal.Debug" value="true"/>
</appSettings>
...
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add
name="textWriterTraceListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="C:\tmp\log4net.txt" />
</listeners>
</trace>
</system.diagnostics>
</configuration>
Log4net FAQ
Thanks a lot for all your suggestions guys.I was able to figure this one out.I had write the below line of code in the Global.asax file
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
I was writing it earlier in the Assembly.info.cs file.

log4net - no log file produced

I have this as my config file:
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="c:\\logging\\EwsSearch.log" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="-1" />
<maximumFileSize value="100KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
</log4net>
<root>
<level value="ERROR" />
<appender-ref ref="RollingFileAppender" />
</root>
</configuration>
I then have in my C# code:
public class VsiEWSSearch
{
private static readonly ILog logger = LogManager.GetLogger(typeof(VsiEWSSearch));
public EWSResponse PdeProcessInquiry(int BusinessLineCode, int ClientCaseId, string callingApp)
{
XmlConfigurator.Configure(new System.IO.FileInfo("VSI.EWSSearch.config"));
logger.Error("This is an error");
No log file is produced even though I have adjusted permissions for the directory. What's wrong?
The root node has to be inside the log4net node. Depending on the type of configuration file you need to make some further adjustments:
If you have a standalone config file for log4net then you need to remove the configuration and configSections node. I also think that log4net is not going to find you configuration file unless you specify the full path (you can of course do that without hard-coding any path in your application).
If you are simply using app.config then you do not need further modifications, but you need to call the XmlConfigurator.Configure() method without any argument.
Note: You should call the XmlConfigurator.Configure() method only once in your application.

log4net with HTTPhandler

In my AssemblyInfo.cs I have:
[assembly: log4net.Config.XmlConfigurator(ConfigFile="ReverseProxy.config", Watch=true)]
In the bin directory where the handler dll is I have the file ReverseProxy.config with the contents:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"
requirePermission="false"/>
</configSections>
<log4net>
<appender name="LogFileAppender" type="log4net.Appender.FileAppender, log4net">
<file value="e:\temp\reverseProxy.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="5" />
<maximumFileSize value="1000KB" />
<encoding value="utf-8" />
<layout type="log4net.Layout.SimpleLayout" />
</appender>
<root>
<level value="ALL" />
<appender-ref ref="LogFileAppender" />
</root>
</log4net>
</configuration>
No logging file is written. I have been able to debug the handler and it hits the Log.Info(..) line but nothing is written.
I am wondering if the config file is actually being found.
The answer is that the config file needs to be in the website directory, not in the bin directory.

Why log4net is not logging messages

I have a console application for which I am trying to setup logging with log4net.
I have done all the basic steps for setting it up -
Added Configuration in App
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<appSettings>
<add key="LogFileRootFolderPath" value="C:\TestApplicationLogs\"/>
</appSettings>
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="TestApplication.log" />
<appendToFile value="true" />
<rollingStyle value="Composite" />
<maxSizeRollBackups value="14" />
<maximumFileSize value="15000KB" />
<datePattern value="yyyyMMdd" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="{%level}%date{MM/dd HH:mm:ss} - %message%newline"/>
</layout>
</appender>
<root>
<level value="All" />
<!-- You can use levels, in increasing order of verbosity: Off, Fatal, Error, Warn, Info, Debug, All -->
<appender-ref ref="RollingFileAppender" />
</root>
</log4net>
P.S. I have created a new folder 'TestApplicationLogs' in C:\
Added [assembly: log4net.Config.XmlConfigurator(Watch = true)] in AssemblyInfo.cs
In Program.cs
private static readonly log4net.ILog log = log4net.LogManager.GetLogger
(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
static void Main(string[] args)
{
log.Info("App Started");
}
Can anyone please guide what is missing?
I don't see where you define that C:\TestApplicationLogs as the directory where it should log to.
In the log4net config you have just specified the file name, so it will log to the directory where you execute your exe.

Resources