C# log4net traceappender仅记录级别为';冗长';使用Windows Azure DiagnosticsMonitor时

C# log4net traceappender仅记录级别为';冗长';使用Windows Azure DiagnosticsMonitor时,c#,azure,log4net,azure-diagnostics,C#,Azure,Log4net,Azure Diagnostics,我有一个azure worker角色,我已将其配置为使用写入WindowsAzure.Diagnostics的log4net跟踪附件。这是通过在worker角色的RoleEntryPoint中进行以下调用来完成的 using System; using Microsoft.WindowsAzure.Diagnostics; using log4net.Config; namespace XXX { public class WorkerRole : RoleEntryPoint

我有一个azure worker角色,我已将其配置为使用写入WindowsAzure.Diagnostics的log4net跟踪附件。这是通过在worker角色的RoleEntryPoint中进行以下调用来完成的

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();
        }
    }
}
App.config文件的配置方式如下:

<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>
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();
        }
    }
}

其结果是所有消息(甚至错误)都以“详细”级别记录在表存储中


如何解决这个问题?

一些博客文章讨论了这个问题:(和)

  • 事实证明log4net TraceAppender会转换所有日志消息 要跟踪。写入消息,DiagnosticMonitorTraceListener会将所有跟踪。写入消息转换为详细信息。
在我的案例中,答案是使用Pete McEvoy的解决方案并以以下方式扩展TraceAppender:

<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>
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();
        }
    }
}
然后在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>


非常有用。但是,我没有通过
Trace.Write()
从log4net获取调试级消息。我将代码调整为
else if(level>=level.Debug)
,现在我在流日志和表存储中看到了调试级别的消息。是的,这非常有用。一条评论:一个简单的Trace.Write(..)不会显示在Azure流日志中,所以最后一个else分支什么也不做。我们必须将log4net消息的5个级别显式地投影到3个级别的跟踪。我有
Microsoft.WindowsAzure.Diagnostics 2.5.0.0
,但仍然存在相同的问题。您的答案解决了这个问题。正如@g.pickardou指出的,Trace.Write()不会显示在azure流日志中。但是,Trace.WriteLine()在详细级别显示为日志记录。5个log4net级别到4个azure级别要比3个azure级别容易得多levels@g.pickardou&josh:TraceAppender代码已更新。谢谢你指出。这已经过时了。例如,你确定吗?人们似乎仍然在使用Microsoft.WindowsAzure.Diagnostics 2.5.0.0hmmm时遇到此问题:/n我不确定。