【问题标题】:Log4Net - Add time with logging datetimeLog4Net - 使用记录日期时间添加时间
【发布时间】:2011-08-02 10:41:46
【问题描述】:

我开发了一个 asp.net 网站,我使用 log4net 记录错误信息,格式为:

"%-5p %d - %m%n"

它按当前机器的日期时间记录日期时间。 例如:

FATAL 2011-04-10 01:08:11,759 - message

但我想将日期时间转换为另一个区域或添加额外的时间。例如,我想在前面的示例中添加 3 小时,并希望输出为:

FATAL 2011-04-10 **04**:08:11,759 - message

知道如何实现这一目标吗?

【问题讨论】:

    标签: datetime log4net log4net-configuration


    【解决方案1】:

    这可能无法回答您的问题,因为我不确定您要达到的目标。也许如果你能提供更多关于你为什么要这样做的详细信息,你可能会得到更好的答案。

    如果您尝试关联在不同区域生成的多个日志文件(或其他来源),它可能会有所帮助...

    您可以按照here 的描述尝试 log4net 的 utctime PatternLayout。

    这将使您的日志时间采用通用时间,这可能更容易让您关联起来。如果您可以控制时间戳的来源(例如您的 asp.net 网站),那么通过将它们标准化为通用时间,它们应该更容易比较。

    如果您确实想将时间更改为不同的区域或在记录的时间戳中添加/减去任意时间跨度,您可能必须编写自己的自定义 PatternLayout 或 PatternLayoutConverter。这可能有点棘手,因为我认为 log4net DatePatternConverter 和 UtcDatePatternConverter 都不能用于自定义(即它们被声明为internal,因此您不能对它们进行子类化并添加您的行为)。

    您可以使用来自 log4net code repository 的 log4net 实现从头开始编写自己的代码,但这对我来说似乎很麻烦。

    请注意,使用Custom Date format specifiersz, zz, zzzK 之一在单独的列中再次记录时间可能会很有用。

    更新: 请参阅this answer 了解可能有帮助的另一个想法。该问题要求一种使用 log4net 捕获用户名的方法。最终,对他来说最好的解决方案是编写一个非常小的类来返回他需要的信息(用户名)。类的实例可以存储在 MDC(或 GlobalDiagnosticContext)中并在配置中引用。当 log4net 从 MDC(即对象)获取值时,它会调用 ToString 并记录结果。这种方法比编写一个全新的 PatternLayoutConverter 要容易得多,但灵活性稍差一些。

    答案的底部是一些示例代码,如下所示:

    public class HttpContextUserNameProvider 
    {   
      public override string ToString()   
      {     
        HttpContext context = HttpContext.Current;       
        if (context != null && 
            context.User != null && 
            context.User.Identity.IsAuthenticated)
        {
          return context.Identity.Name;     
        }     
        return "";   
      } 
    }
    

    您可以像这样将对象存储在 MDC/GlobalDiagnosticContext.Properties 中:

    MDC.Set("user", new HttpContextUserNameProvider()); 
    

    你可能会写一些类似的东西来返回不同的时间。您可以使用此时间而不是 log4net 提供的时间,或者您可以将此“自定义”时间作为附加列。您的“自定义时间”对象可能如下所示:

    public class MyLocalTimeProvider 
    {   
      public override string ToString()   
      {     
        DateTime myLocalTime = GetUtcTimeInMyTimeZone(DateTime.UtcNow);
        return myLocalTime;
      } 
    }
    

    然后你可以这样引用它:

    MDC.Set("myLocalTime", new MyLocalTimeProvider()); 
    

    我不确定您是否可以将格式应用于 MDC/GlobalDiagnosticContext.Properties 中的项目(我认为您可以),但您可以试试看。

    您始终可以使用硬编码格式或向对象添加格式属性,如下所示:

    public class MyLocalTimeProvider 
    {   
      public MyLocalTimeProvider(string format)
      {
        Format = format;
      }
    
      public MyLocalTimeProvider()
        : this ("G")
      {
      }
    
      public string Format { get; set; }
      public override string ToString()   
      {     
        DateTime myLocalTime = GetUtcTimeInMyTimeZone(DateTime.UtcNow);
        return myLocalTime.ToString(Format);
      } 
    }
    

    您可以查看this article,了解如何将 UTC 时间转换为任意时区。

    【讨论】:

    • 基本上,我的服务器在另一个时区。如果我的网站不能正常工作,那么我必须检查它为什么不能正常工作?要检查它, 1. 我点击了我的网站 2. 写入点击时间 3. DL 日志文件(由 log4net 生成) 4. 通过 macthing 时间和类/函数检查错误所以,每次我将服务器日志记录时间转换为本地时间。这就是我想使用我的时区记录数据的原因。
    • @Byron - 我更新了我的答案。也许会有所帮助,也许不会。祝你好运!
    【解决方案2】:

    如果您只需要将日期“转移”到您的时区,您可以编写自己的 ForwardingAppender,这将更改记录事件的 DateTime:

    namespace Olekstra
    {
        using System;
    
        using log4net.Appender;
        using log4net.Core;
    
        public class TimeShiftForwardingAppender : ForwardingAppender
        {
            private TimeSpan shift;
    
            private TimeSpan targetOffset;
    
            public TimeShiftForwardingAppender()
            {
                TargetOffset = TimeZoneInfo.Local.BaseUtcOffset;
            }
    
            public TimeSpan TargetOffset
            {
                get
                {
                    return targetOffset;
                }
    
                set
                {
                    targetOffset = value;
                    shift = targetOffset.Subtract(TimeZoneInfo.Local.BaseUtcOffset);
                }
            }
    
            protected override void Append(LoggingEvent loggingEvent)
            {
                var eventData = loggingEvent.GetLoggingEventData();
                eventData.TimeStamp = eventData.TimeStamp.Add(shift);
                base.Append(new LoggingEvent(eventData));
            }
    
            protected override void Append(LoggingEvent[] loggingEvents)
            {
                for (var i = 0; i < loggingEvents.Length; i++)
                {
                    var eventData = loggingEvents[i].GetLoggingEventData();
                    eventData.TimeStamp = eventData.TimeStamp.Add(shift);
                    loggingEvents[i] = new LoggingEvent(eventData);
                }
                base.Append(loggingEvents);
            }
        }
    }
    

    在 .config 中

    <log4net>
      <appender name="FileAppender" type="log4net.Appender.RollingFileAppender">
           <!-- Your real appender here -->
      </appender>
      <appender name="TimeShiftAppender" type="Olekstra.TimeShiftForwardingAppender">
        <targetOffset>06:00:00</targetOffset> <!-- your desired (local) UTC offset value -->
        <appender-ref ref="FileAppender" /> <!-- real appender(s) -->
      </appender>
      <root>
        <level value="DEBUG" />
        <appender-ref ref="TimeShiftAppender" />
      </root>
    </log4net>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-21
      • 2014-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-21
      • 2018-02-07
      相关资源
      最近更新 更多