自定义目标不起作用

时间:2018-01-12 19:31:22

标签: nlog

我正在尝试实施针对this question发布的解决方案,但它无效。

我的目标是登录文件(正常工作)并使LogHandler方法触发(不工作)。

class Program
{
    private static Logger Logger;
    static void Main(string[] args)
    {
        Target.Register<CallbackTarget>("CallbackTarget"); // https://github.com/NLog/NLog/wiki/Register-your-custom-component
        LogManager.Configuration.AddTarget("CallbackTarget", new CallbackTarget(LogHandlerA, LogHandlerB));
        Logger = LogManager.GetCurrentClassLogger();
        Worker.DoNothing();
        Logger.Debug("Log msg from Program");
        Console.ReadLine();

    }

    public static void LogHandlerA(string msg)
    {
        Console.WriteLine("LogHandlerA " + msg);
    }

    public static void LogHandlerB(string msg)
    {
        Console.WriteLine("LogHandlerB " + msg);
    }
}


public class Worker
{
    private static Logger Logger;

    static Worker()
    {
        Logger = LogManager.GetCurrentClassLogger();
    }

    public static void DoNothing()
    {
        Logger.Debug("Log msg from DoNothing");  // should trigger callbacks
    }
}

[Target("CallbackTarget")]
public sealed class CallbackTarget : TargetWithLayout
{
    private readonly Action<String>[] _callbacks;

    public CallbackTarget(params Action<string>[] callbacks)
    {
        this._callbacks = callbacks;

    }

    protected override void Write(LogEventInfo logEvent)
    {
        base.Write(logEvent);

        foreach (var callback in _callbacks)
            callback(logEvent.FormattedMessage);
    }
}

编辑:添加nlog.config

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  <!--https://github.com/nlog/NLog/wiki/File-target#time-based-file-archival-->

  <variable name="methodName"
            value="${callsite:className=True:fileName=False:includeSourcePath=False:methodName=True:cleanNamesOfAnonymousDelegates=False:includeNamespace=False:skipFrames=0}" />

  <targets>
    <target name="file" xsi:type="File"
        layout="${longdate} [${level:uppercase=true}] [thread ${threadid}] [${methodName}]  ${message} "
        fileName="${basedir}/logs/logfile.txt"
        archiveFileName="${basedir}/archives/log.{#}.txt"
        archiveEvery="Day"
        archiveNumbering="Rolling"
        maxArchiveFiles="7"
        concurrentWrites="true"
        keepFileOpen="false"
        encoding="iso-8859-2" />
  </targets>

  <rules>
    <logger name="*" minlevel="Trace" writeTo="file" />
  </rules>

</nlog>

1 个答案:

答案 0 :(得分:0)

Nlog最近获得了一些新功能:

  • NLog版本。 4.5.8为methodCallTarget引入了lambda
  • NLog版本。 4.6.4引入了与Serilog.ForContext匹配的Logger.WithProperty。现有NLog.Fluent.LogBuilder的替代方法。
using System;
using System.Runtime.CompilerServices;
using NLog;
using NLog.Fluent;

namespace ConsoleExample
{
    static class Program
    {
        static void Main(string[] args)
        {
            var outputTemplate = "${longdate} ${level} ${logger}${newline}${message}${newline}in method ${event-properties:CallerMemberName} at ${event-properties:CallerFilePath}:${event-properties:CallerLineNumber}${NewLine}${exception:format=tostring}";
            Action<string> handler = LogHandler;

            // Setup NLog Config
            var nlogConfig = new NLog.Config.LoggingConfiguration();
            var customTarget = new NLog.Targets.MethodCallTarget("CustomTarget", (logEvent, parms) => CustomTargetLogger(logEvent, parms[0].ToString(), handler));
            customTarget.Parameters.Add(new NLog.Targets.MethodCallParameter(outputTemplate));
            nlogConfig.AddRule(NLog.LogLevel.Info, NLog.LogLevel.Fatal, customTarget);
            NLog.LogManager.Configuration = nlogConfig;

            // Start Logging
            var nlogLogger = NLog.LogManager.GetCurrentClassLogger();
            nlogLogger.Info().Message("Hello World").Write();   // NLog.Fluent.LogBuilder
            nlogLogger.Here().Info("Hello World");  // Requires NLog ver. 4.6.4
            Console.ReadLine();
        }

        public static void CustomTargetLogger(LogEventInfo logEvent, string outputTemplateResult, params Action<string>[] handlers)
        {
            foreach (Action<string> handler in handlers)
                handler(outputTemplateResult);
        }

        public static void LogHandler(string logMsg)
        {
            Console.WriteLine("LogHandler: " + logMsg);
        }

        public static NLog.Logger Here(this NLog.Logger logger,
           [CallerMemberName] string callerMemberName = "",
           [CallerFilePath] string callerFilePath = "",
           [CallerLineNumber] int callerLineNumber = 0)
        {
            return logger.WithProperty("CallerMemberName", callerMemberName)
                .WithProperty("CallerFilePath", callerFilePath)
                .WithProperty("CallerLineNumber", callerLineNumber);
        }

    }
}