【问题标题】:NLog: Write to two different targets based on logger name and grouping Quartz logsNLog:根据记录器名称和 Quartz 日志分组写入两个不同的目标
【发布时间】:2020-04-28 07:52:40
【问题描述】:

我有一个 ASP.NET 4.7 Web 项目,其中实现了 Quartz.NET 调度程序。 我读过 Quartz.NET 正在使用 Common.Logging 抽象,但我不知道它的真正含义......

为了避免 Quartz 消息向我的默认应用程序日志发送垃圾邮件,我以编程方式配置了 NLog 设置,方式如下:

        var config = new NLog.Config.LoggingConfiguration();
        var logfile = new NLog.Targets.FileTarget("logfile")
        {
            FileName = "${basedir}/Logs/${logger}_${shortdate}.log",
            Layout = "${longdate}|${level:uppercase=true}|${aspnet-request-ip}|${aspnet-request-url}|${callsite}|${message}|${exception:format=tostring}"
        };
        var logfileQ = new NLog.Targets.FileTarget("logfile")
        {
            FileName = "${basedir}/Logs/Quartz_${shortdate}.log",
            Layout = "${longdate}|${level:uppercase=true}||${message}"
        };

        config.AddTarget(logfile);
        config.AddTarget(logfileQ);

        config.AddRule(LogLevel.Error, LogLevel.Fatal, logfileQ, "Quartz*", true);
        config.AddRule(LogLevel.Trace, LogLevel.Fatal, logfile, "*");

        // Apply config           
        NLog.LogManager.Configuration = config;
        NLog.LogManager.ReconfigExistingLoggers();

然后我使用以下代码添加我的应用程序日志:

public class MyApiController : ApiController
{
    private static NLog.Logger logger = NLog.LogManager.GetLogger("Application");

    [HttpPost]
    [Authorize]
    public IHttpActionResult Post(DataModel.MyModel m)
    {
        logger.Warn("Unable to add point {0}: localization missing", m.Name);
    }
}

所以 NLog 正确地创建了一个“application_yyyy-MM-dd.log”文件以及一个只有错误和致命消息级别的“Quartz_yyyy-MM-dd.log”文件。

问题在于它还为 Quartz 创建了以下三个包含所有级别的文件:

  1. Quartz.Core.JobRunShell_2020-04-28.log
  2. Quartz.Core.QuartzSchedulerThread_2020-04-28.log
  3. Quartz.Simpl.SimpleJobFactory_2020-04-28.log

似乎第一个规则的 final=true 被忽略了。

哪种方式是正确的配置方式?我应该在 Quartz 中禁用某些东西吗?

【问题讨论】:

    标签: asp.net nlog quartz.net


    【解决方案1】:

    我终于明白了。

    添加的规则必须被视为过滤器,不匹配过滤器的进入下一个规则。

    最后一个就像“把之前没有匹配到的东西都拿走……”

    我的规则中的主要问题是第一个仅匹配级别 Error 和 Fatal,但 Quartz 消息的所有其他级别都进入写入日志文件的下一个规则。

    因此规则应该是这样的:

    config.AddRule(LogLevel.Trace, LogLevel.Fatal, logfileQ, "Quartz*", true);
    config.AddRule(LogLevel.Trace, LogLevel.Fatal, logfile, "*");
    

    这样,来自 Quartz 的任何级别的所有消息都将写入quartz_日志文件中。

    为了避免记录 Quartz 的跟踪或信息级别,我应该添加第三条规则来抓取它们并放在“全部抓取”规则之前:

    config.AddRule(LogLevel.Warn, LogLevel.Fatal, logfileQ, "Quartz*", true);
    config.AddRule(LogLevel.Trace, LogLevel.Info, noLogging, "Quartz*", true);
    config.AddRule(LogLevel.Trace, LogLevel.Fatal, logfile, "*");
    

    noLogging 是一个不写任何地方或只写到控制台的目标

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-16
      • 1970-01-01
      • 1970-01-01
      • 2014-12-24
      相关资源
      最近更新 更多