NLog使用NLog.config动态更改文件名

如何使用C#中的变量动态更改FileName? 我的想法是创建一个日志文件,如Log__${date:format=yyyy-MM-dd}.log 。 有任何想法吗?

另一种选择是使用全局诊断上下文 – $(GDC) :

在C#中设置值

 GlobalDiagnosticsContext.Set("UserId_From_DB","42"); 

在config(nlog.config)中:

  

请避免在运行时修改NLog变量(请参阅下面的上一个答案)。 它们应该被视为只读,因为它们不是线程安全的。 如果重新加载LoggingConfiguration,NLog变量也会受到影响。

NLog变量的上一个答案:

在C#中设置值

 LogManager.Configuration.Variables["UserId_From_DB"] = "42"; 

在config(nlog.config)中:

  

如果再次设置该值,则文件名将自动更改。

假设您的nlog.config文件中有一个名为mylogfile.log的日志文件

 FileTarget target = LogManager.Configuration.FindTargetByName("mylogfile.log") as FileTarget; String customlog = "Log_" + GetUserId(UserId_From_DB) + "_" + DateTime.Now.ToString("yyyy-MM-dd") + ".log"; target.FileName = customlog; 

虽然发布的答案有效,但它会遇到并发问题。 该变量是一个全局变量,您最终可能会遇到冲突。

有一个更好的解决方案。 有一种方法可以将事件属性传递给NLog。

链接到相关的NLog文档 。

假设您要记录错误消息:

 Logger myLog = LogManager.GetLogger(name); LogLevel level = LogLevel.Error; string message = "This is an error message!"; 

您将此信息转换为LogEventInfo对象:

 LogEventInfo logEvent = new LogEventInfo(level , myLog.Name, message); 

然后,您可以向此事件添加属性(可以自由选择字符串索引):

 logEvent.Properties["MySpecialValue"] = "SPECIAL"; 

然后你写日志:

 myLog.Log(logEvent); 

这里有趣的是,在NLog配置中, 您可以在Nlog文档引用的任何字段中将此自定义属性用作“布局”值

您可以在布局中使用${event-properties:item=MySpecialValue}来访问该属性。 例如:

  

在发布的示例之后,您将获得一个名为SPECIAL的文件夹,其中包含一个名为my_SPECIAL_file.log的日志文件,您可以在其中找到消息SPECIAL This is an error message! 。 只是为了certificate你可以用许多不同的方式和形状来使用这个自定义值。


我通常使用它来进行特定于实体的日志记录(其中日志的文件名等于实体的ID值),这与您在此处要执行的操作基本相同。

作为一个快速提示,我倾向于将NLog Logger包装在我自己的类中:

 public class UserLogger { private readonly Logger _log; private readonly User _user; public UserLogger(User u) { _user = u; _log = LogManager.GetCurrentClassLogger(); } public void Error(string message) { LogEventInfo logEvent = new LogEventInfo(LogLevel.Error, _log.Name, message); logEvent.Properties["UserId"] = _user.Id; _log.Log(logEvent); } } 

这只是一个简单的例子,可以帮助您入门。

这样,您可以强制在您想要登录“用户日志”目标时知道用户ID。 作为额外的奖励,它还巧妙地将NLog依赖项与您的调用代码分离。