업데이트 :이 문제가 LogEventInfo의 기본 생성자의 사용이라고 생각 @edosoft
. 여기
https://github.com/NLog/NLog/blob/master/src/NLog/LogEventInfo.cs
기본 생성자를 사용하면 .TimeStamp
필드를 채울하지 않는 것을 볼 수 있습니다, 그래서 필드가 아마 내가 가정 날짜 시간에 대한 기본 값으로 기본 설정됩니다 LogEventInfo의 소스를 보면 DateTime.MinValue
입니다. 다른 생성자 중 하나 또는 Create 메서드 중 하나를 사용해야합니다. 당신은 단지 메시지와 레벨 필드를 설정하고 있기 때문에, 나도 제안 :
var logEvent = new LogEventInfo(priority, "", message); //Second param is logger name.
또는 (here에서) DateLayoutRenderer
에 대한 NLog 소스에서
var logEvent = LogEventInfo.Create(priority, "", message);
우리가 날짜 값이 취득하는 것을 볼 수 있습니다 로깅 스트림의 일부는 다음과 같이 계산으로 작성 :
protected override void Append(StringBuilder builder, LogEventInfo logEvent)
{
var ts = logEvent.TimeStamp;
if (this.UniversalTime)
{
ts = ts.ToUniversalTime();
}
builder.Append(ts.ToString(this.Format, this.Culture));
}
여기에서 일어나고있는 것은 DateLayoutRenderer
이 getti 때문이다 LogEventInfo
개체의 TimeStamp
값 (NLog는 Logger.Trace
, Logger.Debug
, Logger.Info
등의 메서드를 사용할 때마다이 중 하나를 만듭니다. 직접 LogEventInfo
개체를 만들고 Logger.Log
메서드를 사용하여 로그에 기록 할 수도 있습니다. LogEventInfo
객체가 생성 될 때 기본적으로
가, 그 TimeStamp
필드 (LogEventInfo
here의 소스에서) 다음과 같이 설정 (CurrentTimeGetter.Now
의 사용에주의) :
public LogEventInfo(LogLevel level, string loggerName, IFormatProvider formatProvider, [Localizable(false)] string message, object[] parameters, Exception exception)
{
this.TimeStamp = CurrentTimeGetter.Now;
this.Level = level;
this.LoggerName = loggerName;
this.Message = message;
this.Parameters = parameters;
this.FormatProvider = formatProvider;
this.Exception = exception;
this.SequenceID = Interlocked.Increment(ref globalSequenceId);
if (NeedToPreformatMessage(parameters))
{
this.CalcFormattedMessage();
}
}
가 TimeStamp
필드가 설정되어 LogEventInfo
생성자는 TimeSource.Current.Now
속성을 사용하며 그 구현은 here으로 볼 수 있습니다.
(UPDATE은 - 어떤 시점에서 NLog 본질적) CurrentTimeGetter
와 동일 여러 향미를 갖는 TimeSource
오브젝트 (중 하나 CachedTimeSource
를 갖는 더 일반적인 접근법을 사용 CurrentTimeGetter
변경).
링크를 탐색의 문제를 저장하려면, 여기 CachedTimeSource
의 소스입니다 :
public abstract class CachedTimeSource : TimeSource
{
private int lastTicks = -1;
private DateTime lastTime = DateTime.MinValue;
/// <summary>
/// Gets raw uncached time from derived time source.
/// </summary>
protected abstract DateTime FreshTime { get; }
/// <summary>
/// Gets current time cached for one system tick (15.6 milliseconds).
/// </summary>
public override DateTime Time
{
get
{
int tickCount = Environment.TickCount;
if (tickCount == lastTicks)
return lastTime;
else
{
DateTime time = FreshTime;
lastTicks = tickCount;
lastTime = time;
return time;
}
}
}
}
이 클래스의 목적은 상대적으로 비용이 많이 드는 작업에 대한 액세스를 제한하기 위해 상대적으로 저렴한 작업 (
Environment.Ticks
)를 사용하는 것입니다
(DateTime.Now
). Ticks 값이 통화 간 (기록 된 메시지에서 다음 메시지로) 변경되지 않으면 DateTime.Now
의 값은 이번에 검색 한 DateTime.Now의 값과 같으므로 이번에는 마지막으로 검색된 값.
이 코드를 모두 사용하면 (대부분의 사람들에게 날짜/시간 로깅이 작동하는 것처럼 보임) 문제의 한 가지 가능한 설명은 Logger.Log
메서드를 사용하여 메시지를 로깅하고 LogEventInfo
개체를 직접. 기본적으로 LogEventInfo
개체를 새로 추가 한 경우 TimeStamp
속성의 자동 설정이 정상적으로 작동합니다. 적절한 경우 Environment.Ticks
, DateTime.Now
및 마지막 DateTime.Now
값을 재사용하는 논리에만 종속됩니다. 개체를 만든 다음 TimeStamp
속성을 DateTime.MinValue
으로 설정할 수 있습니까? 기록되는 날짜가 DateTime.MinValue
이기 때문에 묻습니다.
내가 생각할 수있는 유일한 설명은 Environment.Ticks
이 어떤 이유로 -1을 반환하는 경우입니다. 그렇다면 CurrentTimeGetter
은 항상 lastDateTime 전용 멤버 변수의 초기 값을 반환합니다. Environment.Ticks
이 -1을 반환하는 시나리오를 상상할 수 없습니다.
Log 메서드와 LogEventInfo 클래스를 사용하여 메시지를 작성할 수 있습니까? – wageoghe
@wageoghe 나는 그렇게 기대한다. 그러나 나는 atm과 코드를 갖고 있지 않다. 내가 살펴 보자 마자 바로 업데이 트됩니다 – edosoft
LogEventInfo에 대한 기본 생성자를 사용하는 것이 문제라고 생각합니다. 내 대답에 대한 자세한 내용을 추가했습니다. – wageoghe