C# NLog自定义日志级别值

C# NLog自定义日志级别值,c#,nlog,C#,Nlog,我有一个数据库,我正试图将消息写入其中,并希望使用${level}布局,但我需要将其转换为int值,以引用我自己存储日志记录级别的表。是否可以在配置中将级别强制转换为我的枚举?还有其他想法吗?我没有检查这个,但我怀疑您应该能够为NLog编写自己的布局渲染器(插件)来完成您想做的事情。NLog非常可插拔:) 布局渲染器外观的快速示例(未测试…): [LayoutRenderer(“intLevel”,使用LogEventInfo=true)] 公共级别:LayoutRenderer { 受保护的覆

我有一个数据库,我正试图将消息写入其中,并希望使用${level}布局,但我需要将其转换为int值,以引用我自己存储日志记录级别的表。是否可以在配置中将级别强制转换为我的枚举?还有其他想法吗?

我没有检查这个,但我怀疑您应该能够为NLog编写自己的布局渲染器(插件)来完成您想做的事情。NLog非常可插拔:)

布局渲染器外观的快速示例(未测试…):

[LayoutRenderer(“intLevel”,使用LogEventInfo=true)]
公共级别:LayoutRenderer
{
受保护的覆盖int GetEstimatedBufferSize(LogEventInfo logEvent)
{
返回1;
}
受保护的覆盖无效附加(StringBuilder生成器,LogEventInfo logEvent)
{
开关(logEvent.Level.LowercaseName)
{
案例“跟踪”:
builder.Append(0);
打破
案例“调试”:
附加(1);
打破
案例“信息”:
附加(2);
打破
案例“警告”:
附加(3);
打破
案例“错误”:
附加(4);
打破
"致命个案:
附加(5);
打破
违约:
附加(-1);
打破
}
}
}

这是一个经过测试的布局渲染器,它将日志级别记录为整数。我获取日志级别的方法可能有点过火,但我正在经历linq阶段;-)

使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用NLog;
使用NLog.LAYUTRENDERS;
命名空间MyNLogExtensions.NLog
{
[LayoutRenderer(“LogLevelOrdinal”)]
类LoglevelOrdinallYoutRenderer:LayoutRenderer
{
词典序数;
公共覆盖无效初始化()
{
base.Initialize();
序号=GetLogLevels()
.OrderBy(级别=>level)
.Select((级别,索引)=>new{level=level,Ordinal=index})
.ToDictionary(x=>x.Level,x=>x.Ordinal);
}
受保护的覆盖无效附加(StringBuilder生成器,LogEventInfo logEvent)
{
智力水平=0;
如果(!ordinals.TryGetValue(logEvent.Level,out Level))级别=99;
builder.Append(级别);
}
受保护的覆盖int GetEstimatedBufferSize(LogEventInfo logEvent)
{
返回1;
}
//
//LogLevel是一个静态类,每个不同的日志级别都有一个静态成员。
//LogLevel序号不公开(即,表示相对
//日志级别值的“重要性”)。
//LogLevel.GetHashCode的实现实际上返回序号,但它不返回序号
//依赖于实现细节似乎是正确的。
//最后,这个LayoutRenderer实际上只允许生成一个数值来表示
//特定日志级别值相对于其他lob级别的“位置”。因此,
//我们只需获取所有已知的日志级别值,对它们进行排序(它们是可排序的),然后分配
//根据日志级别值在结果排序列表中的位置拥有序号。
//
//这个helper函数将已知的日志级别值公开为IEnumerable,以便
//轻松使用LINQ构建字典以将日志级别映射到序号。
//
内部IEnumerable GetLogLevels()
{
收益率返回对数水平;
产生返回LogLevel.Debug;
收益率返回LogLevel.Info;
产量返回对数水平。警告;
收益率返回LogLevel.Error;
收益率返回对数水平。致命;
}
}
}
尝试以下解决方案:

[LayoutRenderer("levelInt")]
public class NlogLevelToIntLayoutRenderer : LayoutRenderer
{
    protected override void Append(StringBuilder builder, LogEventInfo logEvent)
    {
        builder.Append(logEvent.Level.Ordinal);
    }
}

我无法使用“简化”版本,因为LogLevel是类而不是枚举。也许这是v1.0和v2.0之间的区别,我仍然使用v1.0。@Viktor-你说得对!我在没有测试的情况下“简化”了太多。我忘记了LogLevel是一个类而不是一个枚举。我将删除“简化”以防止任何人感到困惑。它就像一个符咒。在使用LayoutRenderer之前,不要忘记
ConfigurationItemFactory.Default.LayoutRenders.RegisterDefinition
[LayoutRenderer("levelInt")]
public class NlogLevelToIntLayoutRenderer : LayoutRenderer
{
    protected override void Append(StringBuilder builder, LogEventInfo logEvent)
    {
        builder.Append(logEvent.Level.Ordinal);
    }
}