开发者

Create a strongly typed log4net level from a string

开发者 https://www.devze.com 2023-03-01 14:18 出处:网络
I noticed log4net has a strongly typed Level class. Does anyone know if there\'s a way to create a Level object by parsing a log level string?

I noticed log4net has a strongly typed Level class. Does anyone know if there's a way to create a Level object by parsing a log level string?

For example:

I want to parse the error level string "ERROR" into the equivalent log4net.Core.Level.Error object, and likewise for other logging levels.

I wrote my own (naive) method to do this (see below), but I was hoping there was something internal to log4net that would do this for me.

Thanks!

    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":
               开发者_如何学Python 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");
        }
    }

Edit: Based on Dr. Wily's Apprentice's recommendation, here's what I came up with in the end using the 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;
    }


It looks like that is the purpose of the LevelMap class.

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

EDIT: You can get a LevelMap from the LevelMap property of an ILoggerRepository, if you have access to one.


You can use reflection to get the list of log levels and use this list to fill the 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]; 
            }
        }
    }
}


Well, as long as each level is defined in Level class as:

 public static readonly Level Warn;

I don't see a nice way to handle it (you could use reflection to enumerate properties, but i don't think it's worth). The only improvement to your code i see, instead of hard coded string values, use values from Level.Name instead.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号