如何通过NLog实现每次应用启动生成唯一命名的日志文件?
搞定NLog单日志文件带启动时间戳的问题
核心思路
要实现整个应用只用一个带启动时间戳的日志文件,关键是让NLog在应用刚启动时生成唯一的时间戳文件名,然后所有日志实例都往这个文件写,别每个类都单独建文件目标。
方法1:配置文件+全局变量(推荐)
- 先在应用启动入口(比如
Main方法开头)生成启动时间戳,存到NLog的全局变量里:
// 按需求格式生成启动时间:日+月+年_时+分 var startupTime = DateTime.Now.ToString("ddMMyyyy_HHmm"); // 把时间戳塞到NLog全局变量,后面配置文件能直接引用 NLog.GlobalDiagnosticsContext.Set("StartupTime", startupTime);
- 修改
nlog.config配置文件,指定文件目标用这个全局变量命名:
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <targets> <!-- 仅创建一个文件目标,所有日志都写入这里 --> <target name="singleLogFile" xsi:type="File" fileName="MyLog_${gdc:item=StartupTime}.log" layout="${longdate} ${level} ${message}" /> </targets> <rules> <!-- 所有命名空间的日志都路由到这个目标 --> <logger name="*" minlevel="Trace" writeTo="singleLogFile" /> </rules> </nlog>
- 各个类中获取Logger实例时,直接使用默认配置即可,无需单独指定文件名:
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
这样不管在多少个类里创建Logger实例,都会写入同一个带启动时间戳的文件,不会生成多个日志文件。
方法2:纯代码配置
要是不想用配置文件,直接在启动时用代码创建全局日志目标:
// 生成启动时间戳 var startupTime = DateTime.Now.ToString("ddMMyyyy_HHmm"); var logFileName = $"MyLog_{startupTime}.log"; // 创建全局的文件日志目标 var fileTarget = new FileTarget("singleLogFile") { FileName = logFileName, Layout = "${longdate} ${level} ${message}" }; // 把目标加到NLog配置中,设置所有级别日志都写入该目标 var logConfig = new LoggingConfiguration(); logConfig.AddRule(LogLevel.Trace, LogLevel.Fatal, fileTarget); LogManager.Configuration = logConfig; // 后续任意类中使用Logger,都会写入同一个文件 var logger = LogManager.GetCurrentClassLogger(); logger.Info("应用启动");
关键注意点
- 别用
${date}这类动态日期变量作为文件名,否则NLog会按日志写入时间分割文件,我们需要的是应用启动那一刻的固定时间戳。 - 确保只创建一个文件目标,所有Logger实例共享这个目标,这是避免生成多个日志文件的核心。
内容的提问来源于stack exchange,提问作者Tali
相关产品推荐
相关产品推荐

