32

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.

Philipp M
  • 1,827
  • 7
  • 27
  • 38
Chris
  • 26,212
  • 23
  • 116
  • 214

7 Answers7

42

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.");
}
Anthony Mastrean
  • 20,318
  • 20
  • 92
  • 173
  • 3
    As always, check the internal log4net debug output `` – Anthony Mastrean Jun 15 '11 at 14:44
  • For a web service application, where should this be? – oliverdejohnson Jun 16 '14 at 16:12
  • @oliverdejohnson Check http://logging.apache.org/log4net/release/faq.html for How do I enable log4net internal debugging? it shows how to set up the debug and a trace listener. – Jeff Martin Jun 19 '14 at 14:45
  • There's also the lesser known issue, that, for some reason I cannot comprehend, they decided that log4net's XmlConfiguratorAttribute should only work when using a Debug build. If you plan on doing a release build (which you most certainly will at some point), you have to use ConfigureAndWatch approach during application startup. – Tom Lint Nov 15 '18 at 14:51
  • @TomLint Just tested the use of the attribute using a release build and it's loading the configuration (2.0.6), but for some reason only locally. After I deployed the code to an Azure WebJob, its not working when it was built on release. Do you have a documentation source for this behavior? – martinoss Dec 23 '20 at 17:29
7

finally i just find the simple solution, you may get help there

  1. Global.asax in start function

     protected void Application_Start()
     {
       log4net.Config.XmlConfigurator.Configure();
     }
    
  2. 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);
  1. use log function in any of the action call

    log.Error("test error q111..");
    
  2. 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

adnan
  • 1,309
  • 1
  • 15
  • 22
4

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.

rkmorgan
  • 447
  • 4
  • 12
3

I fixed this by adding the RepositoryAttribute to the offending assembly's AssemblyInfo.cs file.

[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: RepositoryAttribute("Your.Namespace.Here")]
NightShovel
  • 2,614
  • 1
  • 25
  • 34
  • 1
    I tried above, and now log4net is not giving error for creating repository for assembly, but it still does not writing to log file. After creating repository, it just shutdown the assembly. any idea?? – meghana Apr 07 '17 at 13:29
0

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

Rahul Jujarey
  • 151
  • 1
  • 4
0

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.

tech-y
  • 1,451
  • 2
  • 12
  • 25
-1
var log4NetPath = Server.MapPath("~/log4net.config");

FileInfo fileInfo = new FileInfo(log4NetPath);

XmlConfigurator.ConfigureAndWatch(fileInfo);
jayson.centeno
  • 755
  • 10
  • 15
  • 2
    You need to add some prose here to explain what this code does. It has already being flagged and is showing up in the Low Quality Posts review queue, so it is otherwise at risk of being deleted. – sideshowbarker Oct 18 '15 at 04:31