У меня есть база данных, в которую я пытаюсь писать сообщения, и я хотел бы использовать макет $ {level}, но мне нужно преобразовать его в значение int для ссылки на мою собственную таблицу, в которой хранятся уровни ведения журнала. Возможно ли, чтобы уровень был приведен к моему перечислению в конфигурации? Есть другие идеи?
Значение настраиваемого уровня журнала NLog
Ответы (3)
Я не проверял это, но подозреваю, что вы сможете просто написать свой собственный модуль рендеринга макета (плагин), чтобы 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;
}
}
}
person
Viktor
schedule
18.07.2011
Попробуйте это решение:
[LayoutRenderer("levelInt")]
public class NlogLevelToIntLayoutRenderer : LayoutRenderer
{
protected override void Append(StringBuilder builder, LogEventInfo logEvent)
{
builder.Append(logEvent.Level.Ordinal);
}
}
person
YD1m
schedule
05.09.2014
Работает как шарм. Не забудьте
ConfigurationItemFactory.Default.LayoutRenderers.RegisterDefinition
перед использованием LayoutRenderer.
- person niaher; 10.09.2014
Вот протестированный модуль рендеринга макета, который регистрирует уровень журнала как целое число. То, как я получаю уровни журнала, вероятно, немного за бортом, но я проходил фазу 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;
}
}
}
person
wageoghe
schedule
18.07.2011
Не могу заставить упрощенную версию работать на меня, поскольку LogLevel - это класс, а не перечисление. Может это разница между v1.0 и v2.0, я до сих пор использую v1.0.
- person Viktor; 19.07.2011
@Viktor - Ты прав! Я слишком упростил без тестирования. Я забыл, что LogLevel - это класс, а не перечисление. Я удалю упрощение, чтобы никто не запутался.
- person wageoghe; 19.07.2011