【问题标题】:Custom target not working自定义目标不起作用
【发布时间】:2019-10-20 04:39:36
【问题描述】:

我正在尝试实施为响应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>

【问题讨论】:

  • 你读过吗-> github.com/NLog/NLog/wiki/Combine-XML-config-with-C%23-config(见方法ExtendNLogConfig添加目标)
  • @RolfKristensen 感谢您提供信息。我 99% 肯定我会因为多种原因而迁移到 Serilog,其中之一就是这个。 See here.
  • ForContext 看起来会产生分配开销,但如果性能不是问题,那么它看起来不错。

标签: nlog


【解决方案1】:

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);
        }

    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-23
    相关资源
    最近更新 更多