【问题标题】:Enterprise Library Logging Block Rolling Flat File Not Writing to File企业库日志记录块滚动平面文件未写入文件
【发布时间】:2016-05-17 10:37:42
【问题描述】:

我正在使用 ASP.NET MVC 5 为 Web 堆栈和 WebApi 2.2 为后端服务堆栈实现一个多层 Web 解决方案。这些将在部署时位于不同的服务器上,但在本地运行在两个不同的进程中以进行开发 - Windows 7 和 IIS 7.5。我正在尝试使用 Enterprise Library 6 Logging Application Block 在两个进程中实现滚动平面文件跟踪侦听器。我有一个公共项目,其中包含我的 Log 类,该类将保留它自己的单例实例 - 对 Logger 的所有访问都将是:

public sealed class Log : ILog
{
    private static readonly Log m_log;

    static Log()
    {
        var factory = new LogWriterFactory();
        Logger.SetLogWriter(factory.Create());

        m_log = new Log();
    }

    private Log() // no one else can create
    { }

    public static ILog Instance { get { return m_log; } }

    public bool IsLoggingEnabled()
    {
        return Logger.IsLoggingEnabled();
    }

    public void Critical(object caller, string method, string message)
    {
        if (Logger.IsLoggingEnabled())
            Write(caller, method, message, TraceEventType.Critical);
    }

    public void Error(object caller, string method, string message)
    {
        if (Logger.IsLoggingEnabled())
            Write(caller, method, message, TraceEventType.Error);
    }

    public void Warning(object caller, string method, string message)
    {
        if (Logger.IsLoggingEnabled())
            Write(caller, method, message, TraceEventType.Warning);
    }

    public void Information(object caller, string method, string message)
    {
        if (Logger.IsLoggingEnabled())
            Write(caller, method, message, TraceEventType.Information);
    }

    private void Write(object caller, string method, string message, TraceEventType severity = TraceEventType.Information)
    {
        var entry = new LogEntry();
        entry.Severity = severity;

        if (Logger.ShouldLog(entry))
        {
            entry.TimeStamp = DateTime.Now;
            entry.Message = message;

            entry.ExtendedProperties.Add("Type", caller.GetType().Name);
            entry.ExtendedProperties.Add("Method", method);

            ...

            Logger.Write(entry);
        }
    }
}

这是两个进程完全相同的配置,除了写入的文件名(MVC 写入 Web.log 和 WebApi 写入 WebApi.log):

<loggingConfiguration name="loggingConfiguration" tracingEnabled="true" defaultCategory="General" logWarningsWhenNoCategoriesMatch="true">
<logFilters>
  <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Filters.LogEnabledFilter, Microsoft.Practices.EnterpriseLibrary.Logging"
      enabled="true" name="Logging Enabled Filter" />
</logFilters>
<listeners>
  <add name="Rolling Flat File Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.RollingFlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging"
    listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.RollingFlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging"
    fileName="C:\Logs\WebApi.log"
    footer="" formatter="Text Formatter" header=""
    rollFileExistsBehavior="Increment" rollInterval="Midnight"
    timeStampPattern="yyyy-MM-DD" maxArchivedFiles="7"
    traceOutputOptions="LogicalOperationStack, DateTime, Timestamp, ProcessId, ThreadId, Callstack"
    filter="All" />
</listeners>
<formatters>
  <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging"
    template="Timestamp:{timestamp} Severity:{severity} Message:{message} Machine:{machine} ProcessId:{processId} ThreadId:{win32ThreadId}{dictionary( {key}:{value})}"
    name="Text Formatter" />
</formatters>
<categorySources>
  <add switchValue="All" name="General" autoFlush="true">
    <listeners>
      <add name="Rolling Flat File Trace Listener" />
    </listeners>
  </add>
</categorySources>
<specialSources>
  <allEvents switchValue="All" name="All Events">
    <listeners>
      <add name="Rolling Flat File Trace Listener" />
    </listeners>
  </allEvents>
  <notProcessed switchValue="All" name="Unprocessed Category">
    <listeners>
      <add name="Rolling Flat File Trace Listener" />
    </listeners>
  </notProcessed>
  <errors switchValue="All" name="Logging Errors &amp; Warnings">
    <listeners>
      <add name="Rolling Flat File Trace Listener" />
    </listeners>
  </errors>
</specialSources>

WebApi 堆栈使用 Unity 为所有控制器依赖项执行 DI。我的单例实例被正确解析并注入到我的所有控制器都派生的 ApiController 基类中。我有一个动作过滤器试图在 onActionExecutingAsync 和 onActionExecutedAsync 事件中写入日志。

问题出在:WebApi 进程没有将条目写入 WebApi.log 文件。该过程创建文件;它只是没有在那里写任何东西。我很确定我一开始就在那里写了一些东西,但我就是不能让它在那里记录任何东西。我已经通过调试器,IsLoggingEnabled() 返回 true,并且调用 Logger.Write 方法。我尝试在前端撤消对 Logging Block 的所有引用,认为在同一台机器上的多个进程中运行该块存在问题。不用找了。前端 MVC 进程创建并记录到 Web.log 文件就好了(同样,相同的配置)。有人对我缺少什么有任何线索吗?提前致谢。

【问题讨论】:

  • 配置看起来不错。尝试将此行更改为:entry.ExtendedProperties.Add("Method", method ?? String.Empty);
  • 感谢您这么快看。我试过你说的没有用。我仍然只是原型设计,所以我知道我总是在传递一个有效的字符串。不过,我明白你的意思——一旦界面出现并且其他开发人员开始使用它。一旦你这么说,我就更担心“调用者”参数。我正在传递“这个”,但同样,谁知道其他人会做什么。 FWIW - 我还想确认上述 timeStampPattern 问题:“DD”无效,我已将其更改为“dd” - 但这仍然无助于我的空日志文件问题。 :( 我会按照你的建议尝试示例解决方案。
  • 仅供参考,我建议的原因是,如果在异常中传递 null ExtendedProperty 值,则会引发(并吞下)并且不会记录该消息。
  • 你就是男人!你完全正确!我检查了我正在设置的其他 ExtendedProperties(上面的 Write 方法中的“...”)(当然是在我之前的回复之后),其中一个为空。我按照你的建议做了并放了一个?? string.Empty 在它之后,它神奇地记录到文件中!谢谢你。如何标记为答案?

标签: c# asp.net-mvc logging asp.net-web-api enterprise-library


【解决方案1】:

日志应用程序块中有一个known issue,如果ExtendedProperty 值为空,则LogEntry 条目将失败并且不会被记录。

如果为任何 ExtendedProperty 值传入 null,请尝试更改您的代码以写入一个空字符串。例如:

entry.ExtendedProperties.Add("Method", method ?? String.Empty);

这应该避免遇到问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-27
    • 1970-01-01
    • 2011-09-26
    • 1970-01-01
    • 2010-12-30
    • 2011-10-13
    • 1970-01-01
    • 2013-08-01
    相关资源
    最近更新 更多