3

次の形式のlog4netを使用してエラー情報をログに記録するasp.netWebサイトを開発しました。

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

現在のマシンの日時ごとに日時をログに記録します。例えば:

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

しかし、日時を別の地域に変換するか、それに時間を追加したいと思います。たとえば、前の例で3時間を追加し、次のように出力したいとします。

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

これを達成する方法について何かアイデアはありますか?

4

2 に答える 2

5

あなたが何を達成しようとしているのか正確にはわからないので、これはあなたの質問に答えないかもしれません。たぶん、あなたがこれをしたい理由についてより多くの詳細を提供することができれば、あなたはより良い答えを得るかもしれません。

異なるリージョンで生成された複数のログファイル(または他のソース)を相互に関連付けようとしている場合は、役立つ可能性があります...

ここでutctime説明するように、 log4netのPatternLayoutを試すことができます。

これにより、ログ時間がユニバーサル時間で取得され、相関が容易になる場合があります。タイムスタンプのソース(asp.net Webサイトなど)を制御できる場合は、それらをユニバーサル時間に正規化することで、比較しやすくなります。

本当に時間を別のリージョンに変更したり、ログに記録されたタイムスタンプから任意の期間を追加/減算したりする場合は、独自のカスタムPatternLayoutまたはPatternLayoutConverterを作成する必要があります。log4net DatePatternConverterもUtcDatePatternConverterもカスタマイズに使用できないと思うので、これは少し注意が必要かもしれません(つまり、これらは宣言されinternalているため、サブクラス化して動作を追加することはできません)。

log4netコードリポジトリからのlog4netの実装を使用して、最初から独自に作成することもできますが、それは私には多くの問題のように思えます。

もう1つ注意してください。これらのカスタム日付形式指定子のいずれかを使用して、別の列に時間を再度記録すると便利な場合があります:z、zz、zzzK

更新:役立つ可能性のある別のアイデアについては、この回答を 参照してください。質問は、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時刻を任意のタイムゾーンに変換する方法については、この記事を参照してください。

于 2011-04-11T18:53:13.340 に答える
0

日付をタイムゾーンに「シフト」するだけでよい場合は、独自の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>
于 2014-03-21T07:56:40.857 に答える