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 ?
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.
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.
I have the following file Log4net.config in my bin directory:
<?xml version="1.0" encoding="utf-8" ?>
<log4net xmlns="urn:log4net">
<appender name="FileAppender" type="log4net.Appender.FileAppender">
<param name="file" value="MyLogFile.log"/>
<param name="appendToFile" value="false"/>
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%date (%logger) [%5level] - %message" />
</layout>
</appender>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%date (%logger) [%5level] - %message" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="FileAppender" />
<appender-ref ref="ConsoleAppender"/>
</root>
<logger name="NHibernate" additivity="false">
<level value="WARN"/>
</logger>
</log4net>
And the following code in my AssemblyInfo.cs file:
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyTitle("My Project")]
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log4net.config", Watch = true)]
When I run the program, I get the following log4net debug output:
log4net: log4net assembly [log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821]. Loaded from [D:\Data\Projects\Active\Clients\MyProject\src\MyProject.Importer\bin\Debug\log4net.dll]. (.NET Runtime [4.0.30319.1] on Microsoft Windows NT 6.1.7600.0)
log4net: DefaultRepositorySelector: defaultRepositoryType [log4net.Repository.Hierarchy.Hierarchy]
log4net: DefaultRepositorySelector: Creating repository for assembly [MyCompany.Framework, Version=2.1.72.0, Culture=neutral, PublicKeyToken=null]
log4net: DefaultRepositorySelector: Assembly [MyCompany.Framework, Version=2.1.72.0, Culture=neutral, PublicKeyToken=null] Loaded From [D:\Data\Projects\Active\Clients\MyProject\src\MyProject.Importer\bin\Debug\MyCompany.Framework.dll]
log4net: DefaultRepositorySelector: Assembly [MyCompany.Framework, Version=2.1.72.0, Culture=neutral, PublicKeyToken=null] does not have a RepositoryAttribute specified.
log4net: DefaultRepositorySelector: Assembly [MyCompany.Framework, Version=2.1.72.0, Culture=neutral, PublicKeyToken=null] using repository [log4net-default-repository] and repository type [log4net.Repository.Hierarchy.Hierarchy]
log4net: DefaultRepositorySelector: Creating repository [log4net-default-repository] using type [log4net.Repository.Hierarchy.Hierarchy]
The thread 'vshost.RunParkingWindow' (0xd30) has exited with code 0 (0x0).
The thread '<No Name>' (0x15d0) has exited with code 0 (0x0).
log4net: Hierarchy: Shutdown called on Hierarchy [log4net-default-repository]
Log4net loads, but doesn't seem to be processing my config file. When I comment out the attribute in AssemblyInfo.cs and run the following code during my program initialization, it works as expected:
var log4netConfig = "Log4net.config";
var log4netInfo = new FileInfo(log4netConfig);
log4net.Config.XmlConfigurator.ConfigureAndWatch(log4netInfo);
What am I doing wrong? I want to load from AssemblyInfo.cs.
I also have trouble with this method of boostrapping log4net. The documentation says you have to make a call very early in your application startup
if you use configuration attributes you must invoke log4net to allow it to read the attributes. A simple call to LogManager.GetLogger will cause the attributes on the calling assembly to be read and processed. Therefore it is imperative to make a logging call as early as possible during the application start-up, and certainly before any external assemblies have been loaded and invoked.
Try placing a logger in the same class that starts your application (program.cs, app.xaml, whatever). For example
private static readonly ILog Log = LogManager.GetLogger(typeof(Program));
And for kicks, make any call to the log (even one that is filtered or evaluated out of the append process, it should force log4net to evaluate your repository/heirarchy).
static Program()
{
Log.Debug("Application loaded.");
}
finally i just find the simple solution, you may get help there
Global.asax in start function
protected void Application_Start()
{
log4net.Config.XmlConfigurator.Configure();
}
In any of the class where use logging at class level
add namespace
using log4net;
add this code line at class level
private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
use log function in any of the action call
log.Error("test error q111..");
configuration
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net " />
</configSection>
<log4net debug="true">
<!--AdoNet appender is use for write log file into sql server-->
<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=DESKTOP-NLH31FH; Initial Catalog=SmallBizDb;Integrated Security=true" providerName="System.Data.SqlClient" />
<commandText value="INSERT INTO [dbo].[Logs] ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (#logdate,#thread, #loglevel, #logger, #message, #exception)" />
<parameter>
<parameterName value="#logdate" />
<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="#loglevel" />
<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>
<!--Add appender which you want to use, You can add more then one appender . Like if you want save log both plain text or sql server ,Add both appender.-->
<root>
<level value="Debug" />
<!--<appender-ref ref="RollingLogFileAppender" />-->
<!--Enable this line if you want write log file into plain text file-->
<appender-ref ref="AdoNetAppender" />
<!--Enable this line if you want write log file into sql server-->
</root>
</log4net>
<appSettings>
<add key="log4net.Internal.Debug" value="true"/>
</appSettings>
</configuration>
it may help all and easy to use. thanks
I do keep log4net.Config.XmlConfigurator.Configure(new FileInfo(Server.MapPath("~/Web.config")));
in the Global.asax.cs inside of the Application_Start()... So I don't need to carry the command all over the places.
I fixed this by adding the RepositoryAttribute to the offending assembly's AssemblyInfo.cs file.
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: RepositoryAttribute("Your.Namespace.Here")]
I am using Web.Config sections to configure Logger and manually log events, Bootstrapping Logger from global.asax
static ILog logger = LogManager.GetLogger(<LoggerName>);
protected void Application_Start()
{
log4net.Config.XmlConfigurator.Configure();
}
Try bootstrapping it from global.asax
I was using log4Net with windows service. I tried all the possible options mentioned in the other answers.
For me, another instance of the service was left alive which I had to kill from the task manager. After this, the issue was resolved.
var log4NetPath = Server.MapPath("~/log4net.config");
FileInfo fileInfo = new FileInfo(log4NetPath);
XmlConfigurator.ConfigureAndWatch(fileInfo);
I didn't want to make the title too long but this question specifically refers to running an NServiceBus Generic Host as a Windows Service (thanks to TopShelf) configured to run as Local System (on a Vista machine)
In a previous question I explain why I decided to adapt the PubSub sample to run as a Windows Service so that I can easily stop and start the service to fully prove to myself that NServiceBus was doing what it was supposed to do.
For some reason I can't get Log4Net to log anything to disk, so this could well just be a Log4Net (newbie) configuration problem?
Below is my brute-force attempt to get some sort of tracing going - all I'm getting so far is files writen as follows:
C:\logs\<-GUID->log4net.log
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="MsmqTransportConfig" type="NServiceBus.Config.MsmqTransportConfig, NServiceBus.Core" />
<section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" />
<sectionGroup name="common">
<section name="logging" type="Common.Logging.ConfigurationSectionHandler, NServiceBus.Core"/>
</sectionGroup>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
</configSections>
<!-- in order to configure remote endpoints use the format: "queue#machine"
input queue must be on the same machine as the process feeding off of it.
error queue can (and often should) be on a different machine.
-->
<MsmqTransportConfig
InputQueue="worker2"
ErrorQueue="error"
NumberOfWorkerThreads="1"
MaxRetries="5"
/>
<UnicastBusConfig>
<MessageEndpointMappings>
<add Messages="Messages" Endpoint="messagebus" />
</MessageEndpointMappings>
</UnicastBusConfig>
<common>
<logging>
<factoryAdapter type="Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, NServiceBus.Core">
<arg key="configType" value="INLINE"/>
</factoryAdapter>
</logging>
</common>
<log4net debug="true">
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender,log4net">
<param name="File" value="c:\logs\Subscriber2.log" />
<param name="AppendToFile" value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="2" />
<maximumFileSize value="100KB" />
<staticLogFileName value="true" />
<datePattern value="yyyyMMdd" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
</appender>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionpattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
</appender>
<appender name="EventLogAppender" type="log4net.appender.eventlogappender">
<applicationname value="Subscriber2.EndPointConfig_v1.0.0.0" />
<layout type="log4net.layout.patternlayout">
<conversionpattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
</appender>
<appender name="TraceAppender" type="log4net.Appender.TraceAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="RollingLogFileAppender" />
<appender-ref ref="EventLogAppender" />
<appender-ref ref="ConsoleAppender" />
<appender-ref ref="TraceAppender" />
</root>
</log4net>
<appSettings>
<add key="log4net.Internal.Debug" value="true"/>
</appSettings>
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add
name="textWriterTraceListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="c:\logs\log4net.log" />
</listeners>
</trace>
</system.diagnostics>
</configuration>
NSB will not pick up log settings from config files as default. To do this implement IConfigureLogging in your endpoint config class.
More info here:
http://tech.groups.yahoo.com/group/nservicebus/message/3655
Hope this helps!
/Andreas
It looks as if your other two appenders are throwing exceptions while trying to log. I suspect the %property{NDC} in your patterns - remove them from the pattern and try again.
If your pattern contains %property{X} then you need to set a property with key "X" using code such as
ABC.Properties["X"] = /* some value */
where ABC is either a LoggingEvent instance or ThreadContext or GlobalContext.
I don't know if you've set properties with key "NDC", but I suspect not...