アップデート:
@edosoft問題は、LogEventInfoのデフォルトコンストラクターの使用にあると思います。ここでLogEventInfoのソースを見ると
https://github.com/NLog/NLog/blob/master/src/NLog/LogEventInfo.cs
デフォルトのコンストラクターを使用してもフィールドにデータが入力されないことがわかります.TimeStamp
。そのため、フィールドはおそらくデフォルトでDateTimeのデフォルト値になります。これは私が想定している値ですDateTime.MinValue
。他のコンストラクターの1つまたはCreateメソッドの1つを使用する必要があります。メッセージフィールドとレベルフィールドのみを設定しているので、次のいずれかをお勧めします。
var logEvent = new LogEventInfo(priority, "", message); //Second param is logger name.
または
var logEvent = LogEventInfo.Create(priority, "", message);
DateLayoutRenderer
(ここから)のNLogソースから、ロギングストリームの一部として書き込まれる日付値が次のように計算されていることがわかります。
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
取得していることです(NLogは、、、、などのメソッドを使用するたびにこれらの1つを作成します。自分でオブジェクトを作成し、メソッドを使用してログに記録することもできます)。TimeStamp
LogEventInfo
Logger.Trace
Logger.Debug
Logger.Info
LogEventInfo
Logger.Log
デフォルトでは、LogEventInfo
オブジェクトが作成されると、そのTimeStamp
フィールドは次のように設定されます(LogEventInfo
ここのソースから)(の使用に注意してください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
確認できます。
(更新-ある時点で、NLogは、いくつかのフレーバーを持つオブジェクトをCurrentTimeGetter
持つというより一般的なアプローチに変更されました(そのうちの1つは本質的にと同じです))。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の値と同じになります。今回取得されたので、最後の値を使用してください。取得した値。
このすべてのコードが機能している場合(そして、日付/時刻のログが他のほとんどの人にとって明らかに機能している場合)、問題の1つの考えられる説明は、Logger.Log
メッセージをログに記録するメソッドを使用していて、LogEventInfo
オブジェクトを自分で構築していることです。デフォルトでは、LogEventInfo
オブジェクトを新しく作成したばかりの場合、プロパティの自動設定は正常に機能TimeStamp
するはずです。、、および必要に応じて最後の値を再利用するロジックにEnvironment.Ticks
のみ依存します。DateTime.Now
DateTime.Now
オブジェクトを作成してからLogEventInfo
、そのTimeStamp
プロパティをに設定している可能性はありDateTime.MinValue
ますか?ログに記録されている日付はですのでお願いしますDateTime.MinValue
。
私が考えることができる他の唯一の説明はEnvironment.Ticks
、何らかの理由で-1を返す場合です。含まれている場合は、CurrentTimeGetter
常にlastDateTimeプライベートメンバー変数の初期値を返します。Environment.Ticks
-1が返されるシナリオは想像できません。