9

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

4

3 回答 3

15

另一种选择是使用全局诊断上下文 - $(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" ..>

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

于 2016-09-24T23:40:59.227 回答
13

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

有更好的解决方案可用。有一种方法可以将事件属性传递给 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}在布局中使用来访问该属性。例如:

<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,您可以在其中找到消息SPECIAL This is an error message!。只是为了证明您可以以多种不同的方式和形状使用此自定义值。


我通常使用它来进行特定于实体的日志记录(其中日志的文件名等于实体的 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 目标中),因此可以确保每个用户都被记录到他们自己唯一的日志文件中。

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

于 2018-10-10T07:10:03.113 回答
1

假设您的 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; 
于 2016-05-19T15:35:46.140 回答