2015-09-29 39 views
3

编辑4:“来自”似乎是NLog中的保留字。改变它“FromID”的工作。这是一个很好的方式将变量传递给NLog,并且仍然保持您的代码清洁!感谢MIKE!可以将自定义属性传递给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(); 
    } 

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

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

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

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

但是输出在'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); 
} 

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

理想情况下,我会在自定义布局渲染器中声明属性,而不是在配置文件中设置这些属性,我的类的每个实例都将具有属性集合......类似于整个类的[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显示了如何自定义输出..再次...不是如何自定义输入。

这是针对.NET 4的C#中的控制台应用程序。0使用VS2013

感谢 -Ed

回答

18

事件属性(以前被称为事件上下文)将内置的方式做你想做的。如果您使用的是NLog 3.2+,则可以使用流畅的api,这可能比创建LogEventInfo对象更有吸引力。您可以通过使用命名空间NLog.Fluent来访问此api。

您的布局会那么这样的定义:

${event-properties:item=ID} ${date} ${Level} ${Message} 

然后用流利的API,日志是这样的:

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

除上述设置每个事件属性,唯一的选择将使用MDCMDLS来设置每个线程的属性。

NLog没有找到设置每个记录器属性的方法(我发现)。在内部,NLog通过记录器名称对Logger个实例进行高速缓存,但不能保证对于给定的记录器名称总是会返回Logger的同一个实例。因此,例如,如果在类的构造函数中调用LogManager.GetCurrentClassLogger(),大多数时间您将为您的类的所有实例取回相同的Logger实例。在这种情况下,您的记录器上不会有单独的值,即每个班级的实例。

也许你可以创建一个日志助手类,你可以在你的类中实例化。可以使用每个实例属性值来初始化助手类,以使用每条消息进行记录。该helper类还提供了便利的方法来记录消息,如上所示,但只需一行代码。像这样:

// 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(); 
    } 
} 

这将工作在与上述相同的布局。

+0

谢谢!我会尝试实施帮助程序,以便让我的代码可读。你认为这会影响性能吗?由于所有对辅助类的调用? –

+0

嗨迈克:我实施了你的建议,但它似乎并没有工作?我期待新房地产在现场空白。我在“编辑3”中提供了我的代码。我确定我正确地拼写了这个属性......“不确定这里发生了什么。没有编译发布等 –

+0

得到它的工作。 “From”似乎是一个保留字。我将它改为FromID,它工作! –

-2

这是propably没有做到这一点的最佳方式,甚至不是线程安全的,但一个快速和肮脏的解决方案:你可以使用环境变量:

Environment.SetEnvironmentVariable("NLogOptionID", "87"); 
logger.Debug("My Name id Ed"); 
Environment.SetEnvironmentVariable("NLogOptionID", null); 

在你的布局,您可以使用环境变量。

${environment:variable=NLogOptionID} 
+0

哇。有趣。我喜欢这个想法,因为我可以设置一次Env变量。现在,我正在使用一个LogEventInfo(我编辑了上面的问题来添加这个)......但是这非常混乱......我确实需要线程安全,但... –

0

使用MDLC布局呈现器

MappedDiagnosticsLogicalContext.Set( “属性名”, “的PropertyValue”); MappedDiagnosticsLogicalContext.Set(“PropertyName2”, “AnotherPropertyValue”);

在你n日志配置:

$ {MDLC:项目=属性名} $ {MDLC:项目= PropertyName2}

https://github.com/NLog/NLog/wiki/MDLC-Layout-Renderer

相关问题