NLog自定义日志级别
本文关键字:日志 自定义 NLog | 更新日期: 2023-09-27 18:02:22
我有一个数据库,我试图写我的消息,并希望使用${level}布局,但我需要将其转换为int值,以参考我自己的表,存储日志级别。是否有可能在配置中将级别转换为我的enum ?还有其他想法吗?
我没有检查过这个,但我怀疑你应该能够为NLog编写自己的布局渲染器(插件)来做你想做的事情。NLog是非常可插拔的:)
一个布局渲染器的快速示例(未测试…):
[LayoutRenderer("intLevel", UsingLogEventInfo = true)]
public class IntLevel : LayoutRenderer
{
protected override int GetEstimatedBufferSize(LogEventInfo logEvent)
{
return 1;
}
protected override void Append(StringBuilder builder, LogEventInfo logEvent)
{
switch(logEvent.Level.LowercaseName)
{
case "trace":
builder.Append(0);
break;
case "debug":
builder.Append(1);
break;
case "info":
builder.Append(2);
break;
case "warn":
builder.Append(3);
break;
case "error":
builder.Append(4);
break;
case "fatal":
builder.Append(5);
break;
default:
builder.Append(-1);
break;
}
}
}
试试这个解决方案:
[LayoutRenderer("levelInt")]
public class NlogLevelToIntLayoutRenderer : LayoutRenderer
{
protected override void Append(StringBuilder builder, LogEventInfo logEvent)
{
builder.Append(logEvent.Level.Ordinal);
}
}
这是一个经过测试的布局渲染器,它将日志级别记录为整数。我获得日志级别的方式可能有点过火,但我正在经历一个linq阶段;-)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NLog;
using NLog.LayoutRenderers;
namespace MyNLogExtensions.NLog
{
[LayoutRenderer("LogLevelOrdinal")]
class LogLevelOrdinalLayoutRenderer : LayoutRenderer
{
IDictionary<LogLevel, int> ordinals;
public override void Initialize()
{
base.Initialize();
ordinals = GetLogLevels()
.OrderBy(level => level)
.Select((level, index) => new { Level = level, Ordinal = index })
.ToDictionary( x => x.Level, x => x.Ordinal);
}
protected override void Append(StringBuilder builder, LogEventInfo logEvent)
{
int level = 0;
if (!ordinals.TryGetValue(logEvent.Level, out level)) level = 99;
builder.Append(level);
}
protected override int GetEstimatedBufferSize(LogEventInfo logEvent)
{
return 1;
}
//
// LogLevel is a static class with a static member for each of the different log levels.
// The LogLevel ordinal is not exposed publically (i.e. an ordinal indicating the relative
// "importance" of a LogLevel value).
// The implementation of LogLevel.GetHashCode actually does return the ordinal, but it doesn't
// seem right to rely on that implementation detail.
// In the end, this LayoutRenderer is really just to allow for producing a numeric value to represent
// a particular log level value's "position" relative to the other lob levels. As such,
// We can just get all of the known log level values, order them (they are sortable), and assign our
// own ordinal based on the position of the log level value in the resulting sorted list.
//
// This helper function exposes the known log level values as IEnumerable<LogLevel> so that we can
// easily use LINQ to build a dictionary to map LogLevel to ordinal.
//
internal IEnumerable<LogLevel> GetLogLevels()
{
yield return LogLevel.Trace;
yield return LogLevel.Debug;
yield return LogLevel.Info;
yield return LogLevel.Warn;
yield return LogLevel.Error;
yield return LogLevel.Fatal;
}
}
}