Создать строго типизированный уровень log4net из строки - PullRequest
15 голосов
/ 27 апреля 2011

Я заметил 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;
    }

Ответы [ 3 ]

16 голосов
/ 27 апреля 2011

Похоже, это цель класса LevelMap.

https://logging.apache.org/log4net/log4net-1.2.11/release/sdk/log4net.Core.LevelMap.html

РЕДАКТИРОВАТЬ: Вы можете получить LevelMap из свойства LevelMap из ILoggerRepository, если у вас есть доступ к одному.

4 голосов
/ 08 июля 2011

Вы можете использовать отражение, чтобы получить список уровней журнала и использовать этот список для заполнения 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]; 
            }
        }
    }
}
0 голосов
/ 27 апреля 2011

Ну, пока каждый уровень определен в классе уровня как:

 public static readonly Level Warn;

Я не вижу хорошего способа справиться с этим (вы можете использовать отражение для перечисления свойств, но я не думаю, что оно того стоит). Единственное улучшение вашего кода, которое я вижу, вместо жестко закодированных строковых значений, вместо этого использовать значения из Level.Name.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...