Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

log4net traceappender only logs messages with level 'verbose' when using Windows Azure DiagnosticsMonitor

I have an azure worker role which I have configured to use a log4net Trace Appender which writes to WindowsAzure.Diagnostics. This is done by making the following calls in the RoleEntryPoint of the worker role.

using System;
using Microsoft.WindowsAzure.Diagnostics;
using log4net.Config;

namespace XXX
{
    public class WorkerRole : RoleEntryPoint
    {
        public override bool OnStart()
        {
            var config = DiagnosticMonitor.GetDefaultInitialConfiguration();

            config.Logs.ScheduledTransferLogLevelFilter = LogLevel.Warning;
            config.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(5);

            config.WindowsEventLog.DataSources.Add("System!*");
            config.WindowsEventLog.DataSources.Add("Application!*");
            config.WindowsEventLog.ScheduledTransferLogLevelFilter = LogLevel.Error;
            config.WindowsEventLog.ScheduledTransferPeriod = TimeSpan.FromMinutes(5);

            DiagnosticMonitor.Start("Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString", config);

        XmlConfigurator.Configure();
        }
    }
}

The App.config file is configured in the following manner:

<log4net>
    <appender name="TraceAppender" type="log4net.Appender.TraceAppender">
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%logger - %message" />
        </layout>
    </appender>
    <root>
        <level value="ALL" />
        <appender-ref ref="TraceAppender" />
    </root>
</log4net>

<system.diagnostics>
    <trace>
        <listeners>
            <add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=1.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="AzureDiagnostics">
                <filter type="" />
            </add>
        </listeners>
    </trace>
</system.diagnostics>

The result of this is that all messages (even errors) are logged in table storage as "verbose" level.

How to fix this?

like image 522
Rune Vejen Petersen Avatar asked Aug 03 '12 20:08

Rune Vejen Petersen


People also ask

How do I set up log4net logging levels?

You can specify in your log4net config which log4net logging levels you want to log. This is really valuable if you want to specify only certain levels to be logged to a specific log appender or to reduce logging in production. This allows you to log more or less data without changing your code.

How do I Send Diagnostic tracing logs to Azure monitor?

For Python applications, send diagnostic tracing logs using AzureLogHandler in OpenCensus Python for Azure Monitor. You can then explore and search them.

What is log4net?

Log4net is a logging utility for .NET applications. It’s based on log4j, which is for Java applications. Log4net is highly configurable, so you can use it in many scenarios. You can use it across many different types of apps and write to more than a dozen log destinations, from file to network.

Can I make my own custom log4net Appenders?

You Can Make Your Own Custom log4net Appenders If you want to do something that the standard appenders do not support, you can search online for one or write your own. One example could be an appender for writing to Azure Storage. Once upon a time, we wrote one to send our logs to Azure Table storage to centralize them.


1 Answers

A couple of blog posts deal with this issue: (here and here)

  • It turns out that the log4net TraceAppender converts all log messages to Trace.Write messages and that the DiagnosticMonitorTraceListener converts all Trace.Write messages to verbose.

The answer in my case was to use Pete McEvoy's solution and extend the TraceAppender in the following manner:

using System.Diagnostics;
using log4net.Appender;
using log4net.Core;
namespace XXX.Logging
{
    public class AzureTraceAppender : TraceAppender
    {
        protected override void Append(LoggingEvent loggingEvent)
        {
            var level = loggingEvent.Level;
            var message = RenderLoggingEvent(loggingEvent);

            if (level >= Level.Error)
              Trace.TraceError(message);
            else if (level >= Level.Warn)
              Trace.TraceWarning(message);
            else if (level >= Level.Info)
              Trace.TraceInformation(message);
            else
              Trace.WriteLine(message);
            if (ImmediateFlush)
              Trace.Flush();
        }
    }
}

This extension was then implemented in my App.config:

<log4net>
    <appender name="AzureTraceAppender" type="XXX.Logging.AzureTraceAppender">
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%logger - %message" />
        </layout>
    </appender>
    <root>
        <level value="ALL" />
        <appender-ref ref="AzureTraceAppender" />
    </root>
</log4net>
like image 138
Rune Vejen Petersen Avatar answered Oct 06 '22 00:10

Rune Vejen Petersen