Log4Net-使用日志记录datetime添加时间

Log4Net-使用日志记录datetime添加时间,datetime,log4net,log4net-configuration,Datetime,Log4net,Log4net Configuration,我开发了一个asp.net网站,其中我使用log4net记录错误信息,格式为: "%-5p %d - %m%n" 它按当前计算机的日期时间记录日期时间。 例如: FATAL 2011-04-10 01:08:11,759 - message 但我想将datetime转换为另一个区域,或者用它添加额外的时间。例如,我想在前面的示例中添加3小时,并希望输出为: FATAL 2011-04-10 **04**:08:11,759 - message 关于如何实现这一点,你有什么想法吗?这可能无法

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

"%-5p %d - %m%n"
它按当前计算机的日期时间记录日期时间。 例如:

FATAL 2011-04-10 01:08:11,759 - message
但我想将datetime转换为另一个区域,或者用它添加额外的时间。例如,我想在前面的示例中添加3小时,并希望输出为:

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

关于如何实现这一点,你有什么想法吗?

这可能无法回答你的问题,因为我不确定你到底想实现什么。也许如果你能提供更多关于你为什么要这样做的细节,你可能会得到一个更好的答案

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

您可以尝试log4net的
utctime
patternayout,如前所述

这将获得通用时间中的日志时间,这可能更容易关联。如果您可以控制时间戳的来源(如您的asp.net网站),那么通过将它们规范化为通用时间,它们应该更易于比较

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

您可以使用log4net的log4net实现从零开始编写自己的代码,但这对我来说似乎是一个很大的麻烦

还有一点需要注意的是,也许使用以下选项之一在单独的列中再次记录时间会很有用:

更新: 请看另一个可能有用的想法。这个问题询问一种使用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.Set("user", new HttpContextUserNameProvider()); 
public class MyLocalTimeProvider 
{   
  public override string ToString()   
  {     
    DateTime myLocalTime = GetUtcTimeInMyTimeZone(DateTime.UtcNow);
    return myLocalTime;
  } 
}
MDC.Set("myLocalTime", new MyLocalTimeProvider()); 
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);
  } 
}
将对象存储在MDC/GlobalDiagnosticContext.Properties中,如下所示:

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.Set("user", new HttpContextUserNameProvider()); 
public class MyLocalTimeProvider 
{   
  public override string ToString()   
  {     
    DateTime myLocalTime = GetUtcTimeInMyTimeZone(DateTime.UtcNow);
    return myLocalTime;
  } 
}
MDC.Set("myLocalTime", new MyLocalTimeProvider()); 
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);
  } 
}
你可能会写一些类似的东西,在不同的时间返回。您可以使用这个时间来代替log4net提供的时间,也可以将这个“自定义”时间作为一个附加列。您的“自定义时间”对象可能如下所示:

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.Set("user", new HttpContextUserNameProvider()); 
public class MyLocalTimeProvider 
{   
  public override string ToString()   
  {     
    DateTime myLocalTime = GetUtcTimeInMyTimeZone(DateTime.UtcNow);
    return myLocalTime;
  } 
}
MDC.Set("myLocalTime", new MyLocalTimeProvider()); 
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);
  } 
}
然后你可以这样引用它:

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.Set("user", new HttpContextUserNameProvider()); 
public class MyLocalTimeProvider 
{   
  public override string ToString()   
  {     
    DateTime myLocalTime = GetUtcTimeInMyTimeZone(DateTime.UtcNow);
    return myLocalTime;
  } 
}
MDC.Set("myLocalTime", new MyLocalTimeProvider()); 
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);
  } 
}
我不确定您是否可以将格式应用于MDC/GlobalDiagnosticContext.Properties中的项目(我认为您可以),但您可以试试看

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

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.Set("user", new HttpContextUserNameProvider()); 
public class MyLocalTimeProvider 
{   
  public override string ToString()   
  {     
    DateTime myLocalTime = GetUtcTimeInMyTimeZone(DateTime.UtcNow);
    return myLocalTime;
  } 
}
MDC.Set("myLocalTime", new MyLocalTimeProvider()); 
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);
  } 
}
您可以查看如何将UTC时间转换为任意时区。

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

名称空间Olekstra
{
使用制度;
使用log4net.Appender;
使用log4net.Core;
公共类TimeShift ForwardingAppender:ForwardingAppender
{
私人时间跨度转移;
专用时间跨度目标补偿;
公共时移转发附件()
{
TargetOffset=TimeZoneInfo.Local.BaseUtcOffset;
}
公共时间跨度目标补偿
{
得到
{
返回目标偏移;
}
设置
{
targetOffset=值;
shift=targetOffset.Subtract(TimeZoneInfo.Local.BaseUtcOffset);
}
}
受保护的覆盖无效附加(LoggingEvent LoggingEvent)
{
var eventData=loggingEvent.GetLoggingEventData();
eventData.TimeStamp=eventData.TimeStamp.Add(shift);
追加(新日志事件(eventData));
}
受保护的覆盖无效附加(LoggingEvent[]loggingEvents)
{
对于(变量i=0;i
和in.config


06:00:00 

基本上,我的服务器位于另一个时区。如果我的网站不能正常工作,那么我必须检查它为什么不能工作?检查一下,1。我访问了我的站点2。写命中时间3。DL日志文件(由log4net生成)4。通过macthing time和class/function检查错误,所以每次我都将服务器日志记录时间转换为本地时间。这就是为什么我想用我的时区记录数据。@Byron-我更新了我的答案。也许会有帮助,也许不会。祝你好运