Ответ 1
Похоже, что это цель класса LevelMap
.
https://logging.apache.org/log4net/log4net-1.2.11/release/sdk/log4net.Core.LevelMap.html
EDIT: вы можете получить LevelMap
из свойство LevelMap ILoggerRepository
, если у вас есть доступ к одному.
Я заметил log4net имеет строго типизированный класс уровня. Кто-нибудь знает, есть ли способ создать объект уровня путем разбора строки уровня журнала?
Например:
Я хочу проанализировать строку уровня ошибки "ОШИБКА" в эквивалентный объект log4net.Core.Level.Error, а также для других уровней ведения журнала.
Я написал свой собственный (наивный) метод для этого (см. ниже), но я надеялся, что внутри log4net будет что-то внутреннее, что сделало бы это для меня.
Спасибо!
public static Level ParseLevel(string level)
{
switch (level.ToUpperInvariant())
{
case "ALERT":
return log4net.Core.Level.Alert;
case "ALL":
return log4net.Core.Level.All;
case "CRITICAL":
return log4net.Core.Level.Critical;
case "DEBUG":
return log4net.Core.Level.Debug;
case "EMERGENCY":
return log4net.Core.Level.Emergency;
case "ERROR":
return log4net.Core.Level.Error;
case "FATAL":
return log4net.Core.Level.Fatal;
case "FINE":
return log4net.Core.Level.Fine;
case "FINER":
return log4net.Core.Level.Finer;
case "FINEST":
return log4net.Core.Level.Finest;
case "INFO":
return log4net.Core.Level.Info;
case "NOTICE":
return log4net.Core.Level.Notice;
case "OFF":
return log4net.Core.Level.Off;
case "SEVERE":
return log4net.Core.Level.Severe;
case "TRACE":
return log4net.Core.Level.Trace;
case "VERBOSE":
return log4net.Core.Level.Verbose;
case "WARN":
return log4net.Core.Level.Warn;
default:
throw new Exception("Invalid logging level specified");
}
}
Редактирование: Основываясь на рекомендации доктора Уайли Ученика, вот что я придумал в конце, используя LevelMap:
using System;
using System.Linq;
public static Level ParseLevel(string level)
{
var loggerRepository = LoggerManager.GetAllRepositories().FirstOrDefault();
if (loggerRepository == null)
{
throw new Exception("No logging repositories defined");
}
var stronglyTypedLevel = loggerRepository.LevelMap[level];
if (stronglyTypedLevel == null)
{
throw new Exception("Invalid logging level specified");
}
return stronglyTypedLevel;
}
Похоже, что это цель класса LevelMap
.
https://logging.apache.org/log4net/log4net-1.2.11/release/sdk/log4net.Core.LevelMap.html
EDIT: вы можете получить LevelMap
из свойство LevelMap ILoggerRepository
, если у вас есть доступ к одному.
Вы можете использовать отражение, чтобы получить список уровней журнала и использовать этот список, чтобы заполнить LevelMap.
using System.Reflection;
using log4net.Core;
namespace MyUtils
{
/// <summary>
/// for getting the log level that belongs to a string
/// </summary>
public static class LogLevelMap
{
static LevelMap levelMap = new LevelMap();
static LogLevelMap()
{
foreach (FieldInfo fieldInfo in typeof(Level).GetFields(BindingFlags.Public | BindingFlags.Static))
{
if (fieldInfo.FieldType == typeof(Level))
{
levelMap.Add((Level)fieldInfo.GetValue(null));
}
}
}
public static Level GetLogLevel(string logLevel)
{
if (string.IsNullOrWhiteSpace(logLevel))
{
return null;
}
else
{
return levelMap[logLevel];
}
}
}
}
Хорошо, если каждый уровень определен в классе уровня как:
public static readonly Level Warn;
Я не вижу приятного способа справиться с этим (вы можете использовать отражение для перечисления свойств, но я не думаю, что это стоит). Единственное улучшение вашего кода, которое я вижу, вместо строчных строчных значений, вместо этого использовать значения от Level.Name.