配置NLog的布局以显示所有事件上下文条目

时间:2015-02-22 16:09:48

标签: c# nlog

我目前正在开发webapi2应用程序,并且在使用NLog进行日志的阶段。

在我的应用程序中,我以这种方式使用LogEventInfo.Properties字典以键值方式登录:

thisController.LogParams.Add("ControllerName",controllerName);
thisController.LogParams.Add("ActionName", actionName);
thisController.LogParams.Add("TotalTime", actionWatch.ElapsedMilliseconds);
LogEventInfo logEvent = new LogEventInfo() 
       { 
           Message = string.IsNullOrEmpty(thisController.LogMessage)? "Finished Successfuly":thisController.LogMessage,
           Level = LogLevel.Info,
           TimeStamp = DateTime.Now
       };
logEvent.Properties.Merge(thisController.LogParams);
logger.Log(logEvent);

一切正常,但我似乎找不到渲染布局的方法,因此它打印了LogEventInfo.Properties字典中的所有键值条目。

假设我的目标是一个文件,那么我必须明确提到密钥名称, 有没有办法让它显示字典的所有内容? 这就是今天我这样做的地方,我只能记录我所知道的条目:

<target name="f1" 
  xsi:type="File" 
  fileName="${basedir}\logs\log.txt" 
  maxArchiveFiles="60" 
  archiveNumbering="Date" 
  archiveDateFormat="yyyyMMdd" 
  archiveEvery="Day" 
  layout="${longdate} : ${callsite:className=true:methodName=true} : ${event-context:item=ControllerName} : ${event-context:item=ActionName} : ${event-context:item=TotalTime} : ${message}" />

2 个答案:

答案 0 :(得分:4)

没有可以一次呈现所有属性的内置支持。如果您查看event-context layout renderer中的代码,那么它只会根据项目(即属性名称)添加单个属性值。

您可以创建可以从LogEventInfo打印所有属性的自定义布局渲染器。而不是基于项目获取属性值只需将它们全部添加到字符串构建器,它将打印到目标。

using System;
using System.Globalization;
using System.Text;
using NLog.Config;
namespace CustomLayoutRenderer
{
    /// <summary>
    /// Log event context data.
    /// </summary>
    [LayoutRenderer("event-context-all")]
    public class EventContextLayoutRenderer : LayoutRenderer
    {
        /// <summary>
        /// Renders the specified log event context item and appends it to the specified <see cref="StringBuilder" />.
        /// </summary>
        /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
        /// <param name="logEvent">Logging event.</param>
        protected override void Append(StringBuilder builder, LogEventInfo logEvent)
        {
            foreach (var item in logEvent.Properties)
            {
                // item is a keyvalue pair object you can custom format the key value as needed.
                builder.Append(Convert.ToString(item.Value, CultureInfo.InvariantCulture));
            }

        }
    }
}

您可以在Nlog配置文件中使用<extension>标记注册此自定义布局渲染器。

<nlog> 
  <extensions> 
    <!-- Add the assembly name which contains the custom layout renderer -->
    <add assembly="MyAssembly"/> 
  </extensions> 
  <targets> 
    <target name="f1" type="file"  layout="${longdate} ${event-context-all}" 
            fileName="${basedir}/logs/logfile.log" />
  </targets> 
</nlog>

这将打印所有属性values only,而不需要项目名称。

答案 1 :(得分:2)

NLog中有一个内置的布局渲染器用于此目的 - $ {all-event-properties}。默认情况下,它以键值样式发出所有事件上下文属性,以逗号分隔。

查看文档以获取更多详细信息 https://github.com/NLog/NLog/wiki/All-Event-Properties-Layout-Renderer