Home

How to set up log4net?

Hi ~

How can I set up log4net to work? Is it possible to do it programmatically? I don't want to change the config file each time I run lprun.exe. If this can be done, can you show me how, please?

Thanks.

Comments

  • What problem do you get when using log4net in LINQPad?
  • I'm not getting any errors, but I'm not getting any output either. So, I'm sure that I'm doing something wrong or missing a step. This is what I did in my program:
    LogHelper Class
    #region LogHelper class
    class LogHelper
    {
    public static log4net.ILog GetLogger(string fileName = @c:\temp\test.log) =>
    log4net.LogManager.GetLogger(fileName);
    }
    #endregion
    Setting up the global Log variable
    public static readonly ILog Log = LogHelper.GetLogger();
    Writing something to Log
    Log.Info("Startup Application");
    Nothing happens. Any idea what I'm missing? Or what I should be doing?
  • When I run your code, the following displays False:
    Log.IsInfoEnabled.Dump();
    
    I'm guessing log4net needs configuring to enable logging. I don't how whether this is done in the app.config; if it is, you can specify a configuration file on a global or per-query basis (Query -> app.config).
  • No. I haven't done anything in the app.config. Can I create a config file to be used specifically by a program? I don't want every program to use that config file. Basically, where would I create the app.config file? And how do I access it programmatically?
  • Go to the Query Menu and choose App.Config or press Ctrl+Shift+O
  • Ok. I've created a Linqpad.config file in my c:\temp. In that config file, I set up the logger write to c:\temp\ as well. However, nothing gets created. What else do I need to do?
  • Have you tried that same config file with a Visual Studio project? And can you post the content of your config file?
  • edited August 2017
    Yup. It works on VS 2017. I created a console application. Here's the content of my Linpad.config file:
    
    <configuration>
      <configSections>
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
      </configSections>
      <log4net>
        <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
          <param name="File" value="c:\temp\testlog_"/>
          <param name="RollingStyle" value="Date"/>
          <param name="DatePattern" value="yyMMdd'.log'" />
          <param name="StaticLogFileName" value="false"/>
          <appendToFile value="true" />
          <maximumFileSize value="2MB" />
          <maxSizeRollBackups value="5" />
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%date{MM/dd/yyyy HH:mm:ss} %logger [%thread] (Line :%line) %level - %message%newline"/>
          </layout>
        </appender>
        <appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
          <file value="..\Logs\CurrentLog" />
          <appendToFile value="true" />
    
          <rollingStyle value="Size" />
          <maxSizeRollBackups value="5" />
          <maximumFileSize value="2MB" />
          <staticLogFileName value="true" />
          <!-- Alternatively, roll on date -->
          <!-- <rollingStyle value="Date" /> -->
          <!-- <datePattern value="yyyyMMdd" /> -->
          <filter type="log4net.Filter.LevelRangeFilter">
            <acceptOnMatch value="true" />
            <levelMin value="INFO" />
            <levelMax value="FATAL" />
          </filter>
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%-5level %date [%thread] %-22.22c{1} - %m%n" />
          </layout>
        </appender>
    
        <appender name="LogFileAppender" type="log4net.Appender.FileAppender">
          <file value="log-file.txt" />
          <!-- Example using environment variables in params -->
          <!-- <file value="${TMP}\log-file.txt" /> -->
          <appendToFile value="true" />
          <layout type="log4net.Layout.PatternLayout">
            <header value="[Your Header text here]" />
            <footer value="[Your Footer text here]" />
            <conversionPattern value="%date [%thread] %-5level %logger [%ndc] 
                     <%property{auth}> - %message%newline" />
          </layout>
          <!-- Alternate layout using XML            
        <layout type="log4net.Layout.XMLLayout" /> -->
        </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" >
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%date [%thread] %-5level %logger
                             [%property{NDC}] - %message%newline" />
          </layout>
        </appender>
    
        <!-- Set the default logging level and add the active appenders -->
        <root>
          <level value="DEBUG" />
          <appender-ref ref="RollingFileAppender" />
          <!--<appender-ref ref="LogFileAppender" />
        <appender-ref ref="ConsoleAppender" />
        <appender-ref ref="RollingFileAppender" />-->
        </root>
    
        <!-- Specify the level for specific categories (“namespace.class”)-->
        <logger name="ConsoleApp.LoggingExample">
          <level value="ERROR" />
          <appender-ref ref="EventLogAppender" />
        </logger>
      </log4net>
    </configuration>
    Not sure if this is important, but this is what I did in VS:
    * In the Properties for Linqpad.config, I changed the Build Action to "Content" and Copy to Output Directory to "Copy always".
    * I created a LinqPadHelper class with the following code
    public static log4net.ILog GetLogger([CallerFilePath] string fileName = "")
    {
    return log4net.LogManager.GetLogger(fileName);
    }
    * Then I added this code to my AssemblyInfo.cs
    [assembly: XmlConfigurator(ConfigFile = "Linqpad.config", Watch = true)]
    * Finally, this is what my Program.cs looks like
    Log.Info("Startup Application");
    Log.Info("Application Completed");
  • Any ideas on what I'm missing?
  • Your sample doesn't work for me in VS. One of the problems I think is your GetLogger method. The parameter to this method should be the name of the logger, not the filename.

    I've created a simple test query that uses log4net in LINQPad here:

    http://share.linqpad.net/ouuq7q.linq

    Note that I'm calling XmlConfigurator.Configure - I believe you need to do this to get log4net to read the application configuration file.

    Also note the app.config config (press F4 and click the app.config tab). I've included the config here with the query, but if you prefer, you can save it to a file and point LINQPad to that file instead, so you can re-use it more easily between queries. You could also put it in default LINQPad.config file.

    Hope this helps!
  • edited August 2017
    Yes, that really helped. Thank you. One other issue, other than closing out of the program, how can I release the log file that gets created?
  • See this:
    https://stackoverflow.com/a/1999446/46223

    You can also press Shift+F5 to terminate the underlying process and release the lock in LINQPad.
Sign In or Register to comment.