Log4Net - Добавить время с регистрацией datetime - PullRequest
3 голосов
/ 10 апреля 2011

Я разработал веб-сайт 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

Есть идеи, как этого добиться?

Ответы [ 2 ]

5 голосов
/ 11 апреля 2011

Это может не ответить на ваш вопрос, потому что я не уверен, чего именно вы пытаетесь достичь.Возможно, если бы вы могли предоставить более подробную информацию о том, почему именно вы хотите это сделать, вы могли бы получить лучший ответ.

Если вы пытаетесь сопоставить несколько файлов журналов (или других источников), которые были созданы в разных регионах, это может помочь ...

Вы можете попробовать utctime PatternLayout в log4net, как описано здесь .

Это даст вам время регистрации в универсальном времени, которое может бытьВам легче соотнести.Если у вас есть контроль над источниками временных меток (например, веб-сайтом asp.net), то путем их нормализации к универсальному времени их будет проще сравнивать.

Если вы действительно хотите изменить время наВ другой регион или добавьте / вычтите произвольный промежуток времени из отметки времени, когда она регистрируется, вам, возможно, придется написать свой собственный PatternLayout или PatternLayoutConverter.Это может быть немного сложно, так как я думаю, что ни log4net DatePatternConverter, ни UtcDatePatternConverter не доступны для настройки (т. Е. Они объявлены internal, поэтому вы не можете их подклассить и добавить свое поведение).

Вымог бы написать свой собственный с нуля, используя реализацию log4net из репозитория кода log4net , но мне это кажется большой проблемой.

Еще одно замечание, возможно, было бы полезно войти в системуснова в отдельном столбце, используя один из этих пользовательских форматов даты : z, zz, zzz , K .

ОБНОВЛЕНИЕ: См. этот ответ для другой идеи, которая может помочь.Вопрос спрашивает, как записать имя пользователя с помощью 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);
  } 
}

Вы можете взглянуть на эту статью , чтобы узнать, какпреобразовать время UTC в произвольный часовой пояс.

0 голосов
/ 21 марта 2014

Если вам нужно просто «сместить» дату в ваш часовой пояс, вы можете написать свой собственный 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>
...