zoukankan      html  css  js  c++  java
  • asp.net core 集成 log4net 日志框架

    asp.net core 集成 log4net 日志框架

    Intro

    在 asp.net core 中有些日志我们可能想输出到数据库或文件或elasticsearch等,如果不自己去实现一个 LoggerProvider 的话就需要借助第三方日志框架实现了,而一些第三方框架的实现大多比较完善和成熟,不失为一个好办法。

    自己写了一个 log4net 的扩展 WeihanLi.Common.Logging.Log4Net,提供了在 .net core 中使用 log4net 的扩展

    安装 nuget 包

    通过 nuget 安装 WeihanLi.Common.Logging.Log4Net

    使用

    基本使用

    ILoggerFactory loggerFactory = new LoggerFactory();
    loggerFactory.AddLog4Net(); // loggerFactory.AddLog4Net(log4netConfigFilePath);
    

    你可以在 asp.net core 应用里你的 Startup 文件中使用下面代码进行配置

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
            {
                loggerFactory.AddLog4Net(); // loggerFactory.AddLog4Net(log4netConfigFilePath);
    
                // ...
            }
    

    默认使用当前目录下的 log4net.config 文件作为 log4net 的配置文件,如果不是需要自己设置 log4net 配置文件的路径。

    log4net 配置参考 示例配置

    源码解析

    项目源码

    Log4NetLoggerProvider

    • 实现记录日志的 ILogger
        internal class Log4NetLogger : ILogger
        {
            private readonly ILog _logger;
    
            public Log4NetLogger(string name) => _logger = LogManager.GetLogger(ApplicationHelper.ApplicationName, name);
    
            public IDisposable BeginScope<TState>(TState state) => NullScope.Instance;
    
            public bool IsEnabled(LogLevel logLevel)
            {
                switch (logLevel)
                {
                    case LogLevel.Critical:
                        return _logger.IsFatalEnabled;
    
                    case LogLevel.Debug:
                    case LogLevel.Trace:
                        return _logger.IsDebugEnabled;
    
                    case LogLevel.Error:
                        return _logger.IsErrorEnabled;
    
                    case LogLevel.Information:
                        return _logger.IsInfoEnabled;
    
                    case LogLevel.Warning:
                        return _logger.IsWarnEnabled;
    
                    case LogLevel.None:
                        return false;
    
                    default:
                        throw new ArgumentOutOfRangeException(nameof(logLevel));
                }
            }
    
            public void Log<TState>(LogLevel logLevel, EventId eventId, TState state,
                Exception exception, Func<TState, Exception, string> formatter)
            {
                if (!IsEnabled(logLevel))
                {
                    return;
                }
    
                if (formatter == null)
                {
                    throw new ArgumentNullException(nameof(formatter));
                }
    
                var message = formatter(state, exception);
    
                if (!(string.IsNullOrEmpty(message) && exception == null))
                {
                    switch (logLevel)
                    {
                        case LogLevel.Critical:
                            _logger.Fatal(message, exception);
                            break;
    
                        case LogLevel.Debug:
                        case LogLevel.Trace:
                            _logger.Debug(message, exception);
                            break;
    
                        case LogLevel.Error:
                            _logger.Error(message, exception);
                            break;
    
                        case LogLevel.Information:
                            _logger.Info(message, exception);
                            break;
    
                        case LogLevel.Warning:
                            _logger.Warn(message, exception);
                            break;
    
                        default:
                            _logger.Warn($"Encountered unknown log level {logLevel}, writing out as Info.");
                            _logger.Info(message, exception);
                            break;
                    }
                }
            }
        }
    
    • 实现提供 logger 的 ILoggerProvider
        [ProviderAlias("log4net")]
        internal class Log4NetLoggerProvider : ILoggerProvider
        {
            private readonly ConcurrentDictionary<string, Log4NetLogger> _loggers =
                new ConcurrentDictionary<string, Log4NetLogger>(StringComparer.Ordinal);
    
            public Log4NetLoggerProvider(string confFilePath)
            {
                if (null == LogManager.GetAllRepositories()?.FirstOrDefault(_ => _.Name == ApplicationHelper.ApplicationName))
                {
                    XmlConfigurator.ConfigureAndWatch(LogManager.CreateRepository(ApplicationHelper.ApplicationName), new FileInfo(confFilePath));
                }
            }
    
            public void Dispose() => _loggers.Clear();
    
            public ILogger CreateLogger(string categoryName) => _loggers.GetOrAdd(categoryName, loggerName => new Log4NetLogger(loggerName));
        }
    
    • 添加 ILoggerFactory 扩展
        public static class Log4NetLoggerFactoryExtensions
        {
            public static ILoggerFactory AddLog4Net(this ILoggerFactory factory)
            {
                factory.AddProvider(new Log4NetLoggerProvider(ApplicationHelper.MapPath("log4net.config")));
    
                return factory;
            }
    
            public static ILoggerFactory AddLog4Net(this ILoggerFactory factory, string configFile)
            {
                factory.AddProvider(new Log4NetLoggerProvider(configFile));
    
                return factory;
            }
        }
    

    Memo

    如果有什么问题或建议,欢迎指出

  • 相关阅读:
    高性能JS载入脚本并执行
    JavaScriptDOM高级程序设计myLogger.js
    (旧文重贴)看看这两段代码有什么不同?
    (旧文重贴)原来进行Authorization:basic的时候,后面的credentials就是
    (旧文重贴)终于把ServerAppUnaviable的问题搞定了。
    (旧文重贴)花了一个小时时间,给项目组作了一个汉字到拼音的转换
    (旧文重贴)昨晚和谢晓讨论了一下多组件服务器验证的问题
    大家好!我是浪潮通软的鞠强,初来贵地,请多多指教!
    (旧文重贴)vs.net的asp.net程序无法在winserver2003上打开,终于搞定了,郁闷ing。。。
    (旧文重贴)SQLDMO好像只能在打有sp3的sql2000上用?
  • 原文地址:https://www.cnblogs.com/weihanli/p/10454728.html
Copyright © 2011-2022 走看看