我可以将自定义属性传递给NLOG并输出到文件吗?

Ed *_*dau 7 c# nlog

编辑4:"从"似乎是NLog中的保留字.改变它"FromID"工作.这是一种将变量传递给NLog并保持代码清洁的绝佳方式!谢谢迈克!

编辑3.我真的很喜欢这个想法:

实现了一个帮助类,正如迈克在下面建议的那样:

public class NLogHelper
{
    //
    // Class Properties
    //
    private Logger m_logger;
    private Dictionary<string, object> m_properties;


    //
    // Constructor
    //
    public NLogHelper(Logger logger)
    {
        m_logger = logger;
        m_properties = new Dictionary<string, object>();
    }

    //
    // Setting Logger properties per instancce
    //
    public void Set(string key, object value)
    {
        m_properties.Add(key, value);
    }

    //
    // Loggers
    //
    public void Debug(string format, params object[] args)
    {
        m_logger.Debug()
            .Message(format, args)
            .Properties(m_properties)
            .Write();
    }
Run Code Online (Sandbox Code Playgroud)

在我的主要代码中,我有:

    private NLogHelper m_logger;
    public void Start() 
    {
        m_logger = new NLogHelper(LogManager.GetCurrentClassLogger());
        m_logger.Set("From", "QRT123");  // Class setting.
        m_logger.Debug("Hello ");
    }
Run Code Online (Sandbox Code Playgroud)

并且配置文件中设置的目标如下:

<target xsi:type="File"
    name ="LogFile" fileName="C:\QRT\Logs\QRTLog-${shortdate}.log"
    layout ="${date}|${level}|${event-properties:item=From}|${message} "/>
Run Code Online (Sandbox Code Playgroud)

但输出有一个BLANK代替'from'属性???

所以我几乎就在那里......但它似乎没有用?

编辑2:我现在正在尝试创建自己的NLog调用版本:

private void Log_Debug (string Message) 
{
   LogEventInfo theEvent = new LogEventInfo(LogLevel.Debug, "What is this?", Message);
   theEvent.Properties["EmployeeID"] = m_employeeID;
   m_logger.Log(theEvent);
}
Run Code Online (Sandbox Code Playgroud)

问题是我必须格式化调用的字符串(但是一个巨大的性能交易)......但这似乎是一个黑客?

理想情况下,我会在自定义布局渲染器中声明属性,而不是在配置文件中设置这些属性,我的类的每个实例都将设置属性...类似于[ID = m_ID]整个类.这样,只要从该类调用NLog,就会设置ID属性,并且NLog的自定义布局渲染器可以使用此属性来输出它.我有意义吗?

我是NLog的新手,一直在寻找自定义渲染器.基本上,我的目标是让我的日志语句为: _logger.Debug ("My Name is {0}", "Ed", ID=87);

而且我希望我的渲染类似于: layout = ${ID} ${date} ${Level} ${Message}

而已.$ {ID}的默认值为0.罚款.但理想情况下,我希望每次调用都能够指定ID而无需每次我想记录时都有3行.

我见过自定义渲染器允许我自定义我输出的内容,但我不确定如何自定义我传递给它的属性

https://github.com/NLog/NLog/wiki/Extending%20NLog显示了我如何添加属性,但我不知道如何调用它们.

此外,https://github.com/NLog/NLog/wiki/Event-Context-Layout-Renderer显示了我如何设置自定义属性,但这涉及每次我想记录某事时创建一个LogEventInfo对象.

Nlog Custom layoutrenderer显示如何再次自定义输出...而不是如何自定义输入.

这适用于使用VS2013定位.NET 4.0的C#中的控制台应用程序

谢谢-Ed

Mik*_*son 23

事件属性(以前称为事件上下文)将是执行所需操作的内置方法.如果您使用的是NLog 3.2+,则可以使用流畅的api,这可能比创建LogEventInfo对象更具吸引力.您可以使用命名空间来访问此API NLog.Fluent.

然后您的布局将如下定义:

${event-properties:item=ID} ${date} ${Level} ${Message}
Run Code Online (Sandbox Code Playgroud)

然后使用流畅的api,记录如下:

_logger.Debug()
    .Message("My name is {0}", "Ed")
    .Property("ID", 87)
    .Write();
Run Code Online (Sandbox Code Playgroud)

除了如上所述设置每个事件的属性之外,唯一的另一个选择是使用MDCMDLS设置每个线程的属性.

NLog没有办法(我已经找到)设置per-logger属性.在内部,NLog Logger通过记录器名称缓存实例,但不保证Logger始终为给定的记录器名称返回相同的实例.因此,例如,如果您调用LogManager.GetCurrentClassLogger()类的构造函数,大多数情况下,您将为类的所有实例返回相同的Logger实例.在这种情况下,对于每个类的实例,您将无法在记录器上具有单独的值.

也许您可以创建一个可以在类中实例化的日志助手类.可以使用每个实例属性值初始化辅助类,以便在每条消息中记录.辅助类还将提供方便的方法来记录消息,如上所述,但只有一行代码.像这样的东西:

// Example of a class that needs to use logging
public class MyClass
{
    private LoggerHelper _logger;

    public MyClass(int id)
    {
        _logger = new LoggerHelper(LogManager.GetCurrentClassLogger());

        // Per-instance values
        _logger.Set("ID", id);
    }

    public void DoStuff()
    {
        _logger.Debug("My name is {0}", "Ed");
    }
}


// Example of a "stateful" logger
public class LoggerHelper
{
    private Logger _logger;
    private Dictionary<string, object> _properties;


    public LoggerHelper(Logger logger)
    {
        _logger = logger;
        _properties = new Dictionary<string, object>();
    }

    public void Set(string key, object value)
    {
        _properties.Add(key, value);
    }

    public void Debug(string format, params object[] args)
    {
        _logger.Debug()
            .Message(format, args)
            .Properties(_properties)
            .Write();
    }
}
Run Code Online (Sandbox Code Playgroud)

这将使用与上面相同的布局.


Rol*_*sen 5

NLog v4.5 支持使用消息模板进行结构化日志记录:

logger.Info("Logon by {user} from {ip_address}", "Kenny", "127.0.0.1");
Run Code Online (Sandbox Code Playgroud)

NLog v4.6.3 支持使用以下方式注入属性WithProperty

logger.WithProperty("user", "kenny").Info("User logon");
Run Code Online (Sandbox Code Playgroud)

NLog v5 引入了新的Fluent API

logger.ForInfoEvent().Property("user", "kenny").Message("User logon").Log();
Run Code Online (Sandbox Code Playgroud)

另请参阅https://github.com/NLog/NLog/wiki/How-to-use-structed-logging

另请参阅https://github.com/NLog/NLog.Extensions.Logging/wiki/NLog-properties-with-Microsoft-Extension-Logging

  • @KevinBui 这个想法不是使用字符串插值而是使用消息模板:https://messagetemplates.org/ (8认同)