1

I am trying to create a Helper class for log4net which will log all my messages to the log files.

The solution consists of an MVC Web Application and 2 Windows services. I want to be able to use the same logger class for all three projects.

The Helper Class I am creating is in a Common Project.

This is what the class looks like:

public class TBLogger 
{
    private static ILog Logger;

    public ILog Log
    {
        get
        {
            if (Logger != null) return Logger;
            XmlConfigurator.Configure();

            var type = MethodBase.GetCurrentMethod().DeclaringType;
            Logger = LogManager.GetLogger(type);
            return Logger;
        }
    }

    public void LogMessage(MessageType messageType, string message)
    {
        switch (messageType)
        {
            case MessageType.Debug:
                Log.Debug(message);
                break;

            case MessageType.Information:
                Log.Info(message);
                break;

            case MessageType.Error:
                Log.Error(message);
                break;
        }
    }

    public void LogExceptionMessage(string message, Exception innerException, string stackTrace, int iStage)
    {
        var exceptionMessage = string.Format("iStage: [{0}] Exception: [{1}], Inner: [{2}], Stack Trace: [{3}]", iStage, message, innerException.Message, stackTrace);
        Log.Error(exceptionMessage);
    }
}

I have added the Log4net settings in the Assembly Class

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log4net.config", Watch = true)]

And the config files look like this: (web.config for MVC Application and App.config for Services)

<log4net file="Log4net.config" />

The Log4net.config is something like this:

<log4net>

  <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
    <file value="D:\MyPath\Logs\WebLogs\" />
    <datePattern value="dd-MMM-yyyy\\\\'GeneralLog.txt'" />
    <staticLogFileName value="false" />
    <appendToFile value="true" />
    <rollingStyle value="Composite" />
    <layout type="log4net.Layout.PatternLayout">
      <!--<conversionPattern value="%date{MM/dd/yy HH:mm} [%thread] %-5level - %message%newline" />-->
      <conversionPattern value="%date{MM/dd/yy HH:mm} %-5level - %message%newline" />
    </layout>

    <filter type="log4net.Filter.LevelRangeFilter">
      <levelMin value="INFO" />
      <levelMax value="INFO" />
    </filter>

  </appender>
  <root>
    <appender-ref ref="RollingLogFileAppender" />
  </root>
</log4net>

What I want to do is create an object of TBLogger and call the LogMessage functions from both windows services and the MVC Application.

var logger = new TBLogger();
logger.LogMessage(MessageType.Information, "This is Information");

But it doesn't seem to be working.

EDIT

The log4net debug file gives this information:

log4net: log4net assembly [log4net, Version=1.2.15.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a]. Loaded from [C:\Users\[]\AppData\Local\Temp\Temporary ASP.NET Files\vs\bc22238d\7aa91eba\assembly\dl3\c228fa05\4ec3fa68_5175d101\log4net.dll]. (.NET Runtime [4.0.30319.42000] on Microsoft Windows NT 10.0.10240.0)
log4net: defaultRepositoryType [log4net.Repository.Hierarchy.Hierarchy]
log4net: Creating repository for assembly [DotNetOpenAuth.Core, Version=4.3.0.0, Culture=neutral, PublicKeyToken=2780ccd10d57b246]
log4net: Assembly [DotNetOpenAuth.Core, Version=4.3.0.0, Culture=neutral, PublicKeyToken=2780ccd10d57b246] Loaded From [C:\Users\[]\AppData\Local\Temp\Temporary ASP.NET Files\vs\bc22238d\7aa91eba\assembly\dl3\a73bdbf7\3acfe046_5175d101\DotNetOpenAuth.Core.dll]
log4net: Assembly [DotNetOpenAuth.Core, Version=4.3.0.0, Culture=neutral, PublicKeyToken=2780ccd10d57b246] does not have a RepositoryAttribute specified.
log4net: Assembly [DotNetOpenAuth.Core, Version=4.3.0.0, Culture=neutral, PublicKeyToken=2780ccd10d57b246] using repository [log4net-default-repository] and repository type [log4net.Repository.Hierarchy.Hierarchy]
log4net: Creating repository [log4net-default-repository] using type [log4net.Repository.Hierarchy.Hierarchy]
log4net: Creating repository for assembly [Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]
log4net: Assembly [Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null] Loaded From [C:\Users\[]\AppData\Local\Temp\Temporary ASP.NET Files\vs\bc22238d\7aa91eba\assembly\dl3\e7a0face\f76e0d4c_cf79d101\Common.dll]
log4net: Assembly [Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null] does not have a RepositoryAttribute specified.
log4net: Assembly [Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null] using repository [log4net-default-repository] and repository type [log4net.Repository.Hierarchy.Hierarchy]
log4net: repository [log4net-default-repository] already exists, using repository type [log4net.Repository.Hierarchy.Hierarchy]
log4net: configuring repository [log4net-default-repository] using .config file section
log4net: Application config file is [C:..........\web.config]
log4net: Configuring Repository [log4net-default-repository]
log4net: Configuration update mode [Merge].
log4net: Hierarchy Threshold []
log4net: No appenders could be found for logger [Common.Constants.TBLogger] repository [log4net-default-repository]
log4net: Please initialize the log4net system properly.
log4net:     Current AppDomain context information: 
log4net:        BaseDirectory   : C:\.............\
log4net:        FriendlyName    : /LM/W3SVC/2/ROOT-1-131019801091897637
log4net:        DynamicDirectory: C:\Users\[]\AppData\Local\Temp\Temporary ASP.NET Files\vs\bc22238d\7aa91eba

EDIT 2: It works for the MVC Application when I add these lines to the Global.asax.cs

var l4net = Server.MapPath("~/Log4net.config");
log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(l4net));
Dawood Awan
  • 7,051
  • 10
  • 56
  • 119
  • Turn on [log4net debug logging](http://stackoverflow.com/a/756241/107625). – Uwe Keim Mar 09 '16 at 06:44
  • 1
    @UweKeim I've posted the log4net debug file information in the Question – Dawood Awan Mar 09 '16 at 06:58
  • I can only assume that your initial config file declaration made log4net look in the wrong path. If it doesn't find a config file, it doesn't do any logging. You could just add your log4net config to your web.config. – Dirk Trilsbeek Mar 09 '16 at 07:19
  • @DirkTrilsbeek you are right when I add the Log4net settings in the Web.config or App.config file it works. – Dawood Awan Mar 09 '16 at 07:31

2 Answers2

1

as I suspected in a comment, the problem is with log4net being unable to locate the config file. This is probably due to the fact the application is a web app, the root directory of your site is not the application base directory. So just specifying "log4net.config" as the config file name wouldn't work.

Log4net supports configuration within your web.config. You can configure your logger there without having to locate the root directory of your site first.

Little caveat here: changing web.config will usually restart your web application. So if you just reconfigure some logging detail, your web app will restart. A dedicated log4net config file used with ConfigureAndWatch would enable you to get around this, change logging configuration without restarting the application. But as you already noticed, you'd have to configure log4net in code because you'd have to find the site directory first. I don't know if this is an issue in your case, but I wanted to point it out.

Dirk Trilsbeek
  • 5,873
  • 2
  • 25
  • 23
-2

Please try Nlog Plugins it's better than Log4Net and it will support in multiple plate form. when your application goes in sleep mode than wake up Log4Net is not working i face some time issue so many time that's why i switch to nLog. It will helpful to you. Please checkout below code this is working perfectly in my Project.

    /// <summary>
    /// Log Class For nLog
    /// </summary>
    internal static class Log
    {
        public static Logger Instance { get; private set; }
        static Log()
        {
            LogManager.ReconfigExistingLoggers();

            Instance = LogManager.GetCurrentClassLogger();
        }
    }


    /// <summary>
    /// custom Logger Class gor Logger
    /// </summary>
    public static class Loggers
    {
        /// <summary>
        /// Static Mathod For Info Message
        /// </summary>
        /// <param name="Message"></param>
        public static void Info(string Message)
        {
            Log.Instance.Info(Message);
        }
        /// <summary>
        /// Static Method For Error Logger
        /// </summary>
        /// <param name="Ex"></param>
        public static void Error(Exception Ex)
        {
            Log.Instance.Error(Ex);
        }

        /// <summary>
        /// Static Method For Debug
        /// </summary>
        /// <param name="Message"></param>
        public static void Debug(string Message)
        {
            Log.Instance.Debug(Message);
        }
    }

Compare Config File

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
      autoReload="true"
      throwExceptions="false"
      internalLogLevel="Trace" internalLogFile="${basedir:dir=Logs}\nlog-internal.log" >


  <!-- optional, add some variabeles
  https://github.com/nlog/NLog/wiki/Configuration-file#variables
  -->
  <variable name="myvar" value="myvalue"/>

  <!-- 
  See https://github.com/nlog/nlog/wiki/Configuration-file 
  for information on customizing logging rules and outputs.
   -->

  <variable name="appName" value="ATR.MOBILE.Web" />
  <targets>
    <target xsi:type="File"
               name="default"
               layout="${longdate} - ${level:uppercase=true}:${message}${onexception:${newline}EXCEPTION\: ${exception:format=ToString}}"
               fileName="${basedir:dir=Logs}\Debug.log"
               keepFileOpen="false"
               archiveFileName="
            ${basedir:dir=Logs}\Debug_${shortdate}.{##}.log"
               archiveNumbering="Sequence"
               archiveEvery="Day"
               maxArchiveFiles="30"
            />

    <target xsi:type="EventLog"
            name="eventlog"
            source="${appName}"
            layout="${message}${newline}${exception:format=ToString}"/>
    <!-- 
    add your targets here 
    See https://github.com/nlog/NLog/wiki/Targets for possible targets.
    See https://github.com/nlog/NLog/wiki/Layout-Renderers for the possible layout renderers.
    -->

    <!--
    Writing events to the a file with the date in the filename. 
    <target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log"
            layout="${longdate} ${uppercase:${level}} ${message}" />
    -->
  </targets>

  <rules>
    <!-- add your logging rules here -->

    <!--
    Write all events with minimal level of Debug (So Debug, Info, Warn, Error and Fatal, but not Trace)  to "f"
    <logger name="*" minlevel="Debug" writeTo="f" />
    -->
    <logger name="*" writeTo="default" minlevel="Info" />
    <logger name="*" writeTo="eventlog" minlevel="Error" />
  </rules>
</nlog>

Example:

Loggers.Info("Your comment.");
Loggers.Error(ex);
Nirav Patel
  • 520
  • 1
  • 5
  • 18