How save in two distinct files using NLog?
我在MVC中有一个Web应用程序,该应用程序使用NLog和Quartz运行某些作业。
我需要将作业的日志保存在另一个文件中,但是由于我只有一个LogManager到应用程序,因此我无法找到一种方法来执行此操作。
试图使用其他目标,但没有成功。
有谁知道该怎么做?
以下是我今天使用的内容:
1 2 3 4 | var config = new NLog.Config.LoggingConfiguration(); var logfile = new NLog.Targets.FileTarget("logfile") { FileName = ArquivoLog, Name="logfile", CreateDirs = true, Layout = FormatoLog, ArchiveEvery = NLog.Targets.FileArchivePeriod.Day, ArchiveNumbering = NLog.Targets.ArchiveNumberingMode.DateAndSequence, MaxArchiveFiles = 31, WriteFooterOnArchivingOnly = true, KeepFileOpen = true, OpenFileCacheTimeout = 30 }; config.AddRule(LogLevel.Trace, LogLevel.Fatal, logfile); NLog.LogManager.Configuration = config; |
要通过NLog.config文件执行此操作,请参阅Andrew Tarasenko的答案。
如果要在代码中进行操作,是否尝试过以下方法?
1 2 3 4 5 6 7 8 9 | var config = new NLog.Config.LoggingConfiguration(); var logfile = new NLog.Targets.FileTarget("logfile1") { FileName = ArquivoLog, Name="logfile1", CreateDirs = true, Layout = FormatoLog, ArchiveEvery = NLog.Targets.FileArchivePeriod.Day, ArchiveNumbering = NLog.Targets.ArchiveNumberingMode.DateAndSequence, MaxArchiveFiles = 31, WriteFooterOnArchivingOnly = true, KeepFileOpen = true, OpenFileCacheTimeout = 30 }; var logfile2 = new NLog.Targets.FileTarget("logfile2") { FileName = ArquivoLog, /* Name="NotReallyNeeded as it is already passed in constructor" */, CreateDirs = true, Layout = FormatoLog, ArchiveEvery = NLog.Targets.FileArchivePeriod.Day, ArchiveNumbering = NLog.Targets.ArchiveNumberingMode.DateAndSequence, MaxArchiveFiles = 31, WriteFooterOnArchivingOnly = true, KeepFileOpen = true, OpenFileCacheTimeout = 30 }; config.AddRule(LogLevel.Trace, LogLevel.Fatal, logfile1,"Job1"); config.AddRule(LogLevel.Trace, LogLevel.Fatal, logfile2,"Job2"); NLog.LogManager.Configuration = config; |
然后在工作中,您应该创建一个这样的记录器
1 2 | var loggerInJob1 = NLog.LogManager.GetLogger("Job1"); var loggerInJob2 = NLog.LogManager.GetLogger("Job2"); |
有关我添加的loggerNamePattern属性,请参阅NLog文档。
这样,每个作业的日志将保存到其他日志文件中。
我个人将采用NLog.config方式。这样一来,无需重新编译代码即可轻松添加新目标(用于新作业)。
但是不知道您的解决方案是否有可能。
如果事先不知道作业数,并且每个作业要求一个日志文件,则可以在每个作业开始时以编程方式更新NLog配置。
在作业开始时,创建一个新的NLog目标。
1 2 3 4 5 6 7 | var target = new NLog.Targets.FileTarget() { FileName = $"Arquivo{jobNumber}.Log", Name = $"logfile{jobNumber}", Layout ="${logger} ${longdate} ${level} ${message}", //add settings are required }; |
然后获取现有的NLog配置,添加目标并为目标添加规则。
1 2 3 | var config = NLog.LogManager.Configuration; config.AddTarget(target); config.AddRuleForAllLevels(target, loggerName); |
最后调用
1 | NLog.LogManager.ReconfigExistingLoggers(); |
这些作业很可能是并发的,因此需要一种锁定机制。
即使存在Nlog.config文件,上面的代码也会追加到现有配置中。
这里是完整样本。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | using NLog; using System.Threading; using System.Threading.Tasks; using NLog.Config; namespace ConsoleApplication2 { class Program { private static readonly object LoggerSynchronization = new object(); static void Main(string[] args) { //create some jobs int numberOfJobs = 5; for (int i = 0; i < numberOfJobs; i++) { var jobNumber = i; Task.Run(() => RunJob(jobNumber)); } Thread.Sleep(1000); //wait till done } private static void RunJob(int jobNumber) { var logger = SetupLog(jobNumber); logger.Info($"Running job {jobNumber}."); //do stuff here ... } private static Logger SetupLog(int jobNumber) { var loggerName = $"Job{jobNumber}"; //create a custom target per job var target = new NLog.Targets.FileTarget() { FileName = $"Arquivo{jobNumber}.Log", Name = $"logfile{jobNumber}", Layout ="${logger} ${longdate} ${level} ${message}", }; //add the target to the configuration lock (LoggerSynchronization) //avoid concurrency issues between the jobs { //check if configuration exists if (NLog.LogManager.Configuration == null) { NLog.LogManager.Configuration = new LoggingConfiguration(); } var config = NLog.LogManager.Configuration; config.AddTarget(target); config.AddRuleForAllLevels(target, loggerName); NLog.LogManager.ReconfigExistingLoggers(); } return NLog.LogManager.GetLogger(loggerName); } } } |
并采样NLog.config
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?xml version="1.0" encoding="utf-8" ?> <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true" throwExceptions="false"> <targets> <target name="console" xsi:type="ColoredConsole" layout="${logger} ${longdate} ${level} ${message}" /> </targets> <rules> <logger name="*" writeTo="console" minlevel="Info" /> </rules> </nlog> |
样本输出