3

で提供されているクラスの代わりにインターフェイスNLog.Interfaceを使用できるように使い始めました(主に単体テスト用ILoggerLoggerNLog

を使用する${stacktrace}と、次のようになります。

... => LoginViewModel.LogIn => LoggerAdapter.Info

LoggerAdapter.Infoその部分を削除したいと思います(クラスを 内にNLog.Interfaceラップするために含まれています)。LoggerLoggerAdapter

どうすればそれができますか?

4

2 に答える 2

4

一部のスタック フレームをスキップするカスタム LayoutRenderer を作成できます。

[LayoutRenderer("stacktrace")]
public class CustomStackTraseLayoutRenderer : StackTraceLayoutRenderer
{
   [DefaultValue(0)]
   public int SkipFrames { get; set; } // configurable

   protected override void Append(StringBuilder builder, LogEventInfo logEvent)
   {
       int startingFrame = logEvent.UserStackFrameNumber + TopFrames - 1;
       if (startingFrame >= logEvent.StackTrace.FrameCount)
           startingFrame = logEvent.StackTrace.FrameCount - 1;

        bool first = true;
        int endingFrame = logEvent.UserStackFrameNumber + SkipFrames;
        for (int i = startingFrame; i >= endingFrame; --i)
        {
            StackFrame f = logEvent.StackTrace.GetFrame(i);

            switch (Format)
            {
                case StackTraceFormat.Raw:
                    builder.Append(f.ToString());
                    break;
                case StackTraceFormat.Flat:
                    if (!first)
                        builder.Append(this.Separator);
                    var type = f.GetMethod().DeclaringType;
                    builder.Append(type == null ? "<no type>" : type.Name);
                    builder.Append(".");
                    builder.Append(f.GetMethod().Name);
                    first = false;
                    break;
                case StackTraceFormat.DetailedFlat:
                    if (!first)
                        builder.Append(this.Separator);
                    builder.Append("[" + f.GetMethod() + "]");
                    first = false;
                    break;
            }
        }
    }
}

カスタム レイアウト レンダラーの追加:

<extensions>
  <add prefix="custom" assembly="YourAssemblyName"/>
</extensions>
<targets>
  <target xsi:type="ColoredConsole" name="c"
          layout="${time} ${custom.stacktrace:skipframes=1} ${level} ${message}">
  </target>
</targets>
于 2013-09-25T15:04:35.913 に答える
2

呼び出しサイト情報が保持されるように NLog Logger をラップする正しい方法の簡単な例については、SO でこの回答を参照してください。

特定の NLog ロガー名の一致に関する問題

これは、NLog Logger のラッピングに関する別の質問です。実際、質問はNLog Loggerのラップに関するものではありませんが、私の回答は別の回答のNLog Loggerラッパーの実装の問題を指摘しています。

MEFでNLogを使用する最良の方法は何ですか?

重要なのは、NLog メソッドの観点からラッパーのロギング メソッドを実装し、ラッパーのを最初のパラメーターとしてLogger.Log渡すことです。type

時間を節約するために、NLog Logger ラッパー コードのわずかに短縮されたバージョンをここに投稿しました。

  class NLogLogger : ILogger
  {
    private NLog.Logger logger;

    public NLogLogger(Type t)
    {
      logger = NLog.LogManager.GetLogger(t.FullName);
    }

    //Trace, Warn, Error, Fatal eliminated for brevity

    public bool IsInfoEnabled
    {
      get { return logger.IsInfoEnabled; }
    }

    public bool IsDebugEnabled
    {
      get { return logger.IsDebugEnabled; }
    }

    public void Info(string format, params object [] args)
    {
      if (logger.IsInfoEnabled)
      {
        Write(LogLevel.Info, format, args);
      }
    }

    public void Debug(string format, params object [] args)
    {
      if (logger.IsDebugEnabled)
      {
        Write(LogLevel.Debug, format, args);
      }
    }

    private void Write(LogLevel level, string format, params object [] args)
    {
      LogEventInfo le = new LogEventInfo(level, logger.Name, null, format, args);
      logger.Log(typeof(NLogLogger), le);
    }
  }

次のようにラッパーを使用します。

class MyClass
{
  private static readonly logger = new NLogLogger(typeof(MyClass));

  public void DoSomething()
  {
    logger.Info("Hello from DoSomething");
  }
}

または、ロガーをクラスに挿入することもできます。

于 2013-09-25T14:36:52.330 に答える