[英]How to conditionally render an attribute with NLog and structured logging?
我繼承了使用 NLog 進行日志記錄的 ASP.NET 應用程序。 記錄的屬性之一是命名模塊,它被硬編碼為“核心”。 這根本沒有用,因為應用程序的所有部分(例如健康檢查、各種業務上下文)都推送相同的值。
在某些情況下,我嘗試使用結構化日志記錄來覆蓋此值(我現在無法重構整個日志記錄)。
public static void LogInfoWithModule<T>(this ILogger<T> logger, string message, string module)
{
var escapedMessage = message.Replace("{", "{{");
escapedMessage = escapedMessage.Replace("}", "}}");
logger.Log(LogLevel.Information, "[{module}] " + escapedMessage, module);
}
logger.LogInfoWithModule($"Health check response = {response}", Constants.LoggingModules.Health);
<target name="logJson" xsi:type="File">
<layout xsi:type="JsonLayout" includeAllProperties="true">
<attribute name="module" layout="${when:when='${event-properties:item=module}'=='':Core" />
</layout>
</target>
我得到想要的,那就是所有現有的調用都不會提供模塊,它們會像以前一樣工作。 通過LogInfoWithModule
傳遞的任何日志記錄都將覆蓋默認值。
但是,我發現這個解決方案非常混亂,因為:
簡單的方法,但會影響性能(注意${mdlc:item=module}
區分大小寫)
public static void LogInfoWithModule<T>(this ILogger<T> logger, string message, string module)
{
using (logger.BeginScope(new [] { new KeyValuePair<string,object>("module", module) }))
{
logger.Log(LogLevel.Information, message);
}
}
注入屬性的高級方法(注意${event-properties:module}
區分大小寫):
public static void LogInfoWithModule<T>(this ILogger<T> logger, string message, string module)
{
logger.Log(LogLevel.Information, default(EventId), new ModuleLogEvent(message, module), default(Exception), ModuleLogEvent.Formatter);
}
class ModuleLogEvent : IReadOnlyList<KeyValuePair<string, object>>
{
public static Func<ModuleLogEvent, Exception, string> Formatter { get; } = (l, ex) => l.Message;
public string Message { get; }
public string Module { get; }
public MyLogEvent(string message, string module)
{
Message = message;
Module = module;
}
public override string ToString() => Message;
// IReadOnlyList-interface
public int Count => 1;
public KeyValuePair<string, object> this[int index] => new KeyValuePair<string,object>("module", Module);
public IEnumerator<KeyValuePair<string, object>> GetEnumerator() => yield return new KeyValuePair<string,object>("module", Module);
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
請注意上述示例代碼中可能包含拼寫錯誤和編譯錯誤。
或者你可能會在這里找到快樂: https://github.com/viktor-nikolaev/XeonApps.Extensions.Logging.WithProperty :
public static class LoggingExtensions
{
public static NLog.Logger WithModule(this NLog.Logger logger, object propertyValue) =>
logger.WithProperty("module", propertyValue);
public static ILogger WithModule(this ILogger logger, object propertyValue) =>
logger.WithProperty("module", propertyValue);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.