NLog 动态切换日志文件名称

2023-07-13  乐帮网

.net nlog

NLog 动态日志文件名称切换解决方案:

1、一种方法是使用全局诊断上下文变量 - $(GDC):

在C#中设置值 GlobalDiagnosticsContext.Set("UserId_From_DB", "42");
然后在配置(nlog.config)中:

<target type="file" filename="Log_${gdc:item=UserId_From_DB}_${date:format=yyyy-MM-dd}.log" ..>

请避免在运行时修改 NLog 变量(请参阅下面的上一个答案)。它们应被视为只读,因为它们不是线程安全的。如果重新加载LoggingConfiguration,NLog变量也会受到影响。所以思路相同的可以使用NLog中自带的变量如下:
用C#设置值

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


在配置(nlog.config)中:

<target type="file" filename="Log_${var:UserId_From_DB}_${date:format=yyyy-MM-dd}.log" ..>

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

2、虽然以上的答案有效,但它存在并发问题。该变量是一个全局变量,最终可能会产生冲突。
有一个更好的解决方案。有一种方法可以将事件属性传递给NLog。
链接到相关的NLog文档。(https://github.com/NLog/NLog/wiki/EventProperties-Layout-Renderer
假设你想记录一条错误信息:

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文档中提到的 "Layout"值的字段中使用这个自定义属性。
布局中你可以使用 ${event-properties:item=MySpecialValue} 访问这个值。例如:

<target xsi:type="File" 
        name="file" 
        fileName="${basedir}/logs/${event-properties:item=MySpecialValue}/my_${event-properties:item=MySpecialValue}_file.log"
        layout="${event-properties:item=MySpecialValue} ${message}" />

根据以上的示例,您将得到一个名为SPECIAL的文件夹,其中有一个名为my_SPECIAL_file.log的日志文件。为了证明这一点,您可以以多种不同的方式使用这个自定义值。
我通常用它来做实体特定的日志(日志的文件名等于实体的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);
    }
}

这只是一个简单的示例。我在这里使用的很酷的功能是,我使用UserId值定义了日志的文件名(在Nlog.Config目标中),因此可以确保每个用户都被记录到他们自己唯一的日志文件中。
这样,当你想将日志记录到 "user log "布局中,你就可以确保用户ID是已知的。作为额外的功能,它还巧妙地将NLog依赖与您的调用代码分离开来。
这种方式不会有并发问题。

3、假设您的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; 

这种方式使用纯代码方式实现,来更改日志文件名称。

原文地址:[Solved] NLog dynamically change filename using | 9to5Answer

公众号二维码

关注我的微信公众号
在公众号里留言交流
投稿邮箱:1052839972@qq.com

庭院深深深几许?杨柳堆烟,帘幕无重数。
玉勒雕鞍游冶处,楼高不见章台路。
雨横风狂三月暮。门掩黄昏,无计留春住。
泪眼问花花不语,乱红飞过秋千去。

欧阳修

付款二维码

如果感觉对您有帮助
欢迎向作者提供捐赠
这将是创作的最大动力