美文网首页
Log4Net 日志组件通用代码

Log4Net 日志组件通用代码

作者: 任前程 | 来源:发表于2018-05-09 20:38 被阅读165次
    matese-fields-233175-unsplash.jpg | center | 827x550

    [toc]

    概述

    C# 领域最知名的日志组件非 Log4Net 莫属。一直以来都是现用现查手册,虽然浪费不了多少时间,但是这种习惯终归不好。于是,搜集了一份封装比较完善的代码,具体实现了:可零配置,动态指定文件名和文件路径,按日期和大小自动分割文件。

    代码详情

    1. 创建配置文件类

    初始化Logger时首先读取配置项中的同名Appender,如果存在使用配置参数,如果不存在则使用默认配置。

    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace TestProject.Log4net
    {
        public class ReadParamAppender : log4net.Appender.AppenderSkeleton
        {
            private string _file;
            public string File
            {
                get { return this._file; }
                set { _file = value; }
            }
    
            private int _maxSizeRollBackups;
            public int MaxSizeRollBackups
            {
                get { return this._maxSizeRollBackups; }
                set { _maxSizeRollBackups = value; }
            }
    
            private bool _appendToFile = true;
            public bool AppendToFile
            {
                get { return this._appendToFile; }
                set { _appendToFile = value; }
            }
    
            private string _maximumFileSize;
            public string MaximumFileSize
            {
                get { return this._maximumFileSize; }
                set { _maximumFileSize = value; }
            }
    
            private string _layoutPattern;
            public string LayoutPattern
            {
                get { return this._layoutPattern; }
                set { _layoutPattern = value; }
            }
    
            private string _datePattern;
            public string DatePattern
            {
                get { return this._datePattern; }
                set { _datePattern = value; }
            }
    
            private string _level;
            public string Level
            {
                get { return this._level; }
                set { _level = value; }
            }
    
            protected override void Append(log4net.Core.LoggingEvent loggingEvent)
            {
            }
        }
    }
    
    

    2. 动态创建Logger工厂类

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Collections.Concurrent;
    using System.Configuration;
    
    using log4net;
    using log4net.Appender;
    using log4net.Core;
    using log4net.Layout;
    using log4net.Repository;
    using log4net.Repository.Hierarchy;
    
    [assembly: log4net.Config.XmlConfigurator(Watch = true)]
    namespace TestProject.Log4net
    {
        public static class CustomRollingFileLogger
        {
            private static readonly ConcurrentDictionary<string, ILog> loggerContainer = new ConcurrentDictionary<string, ILog>();
    
            private static readonly Dictionary<string, ReadParamAppender> appenderContainer = new Dictionary<string, ReadParamAppender>();
            private static object lockObj = new object();
    
            //默认配置
            private const int MAX_SIZE_ROLL_BACKUPS = 20;
            private const string LAYOUT_PATTERN = "%d [%t] %-5p %c  - %m%n";
            private const string DATE_PATTERN = "-yyyyMMdd\".txt\"";
            private const string MAXIMUM_FILE_SIZE = "256MB";
            private const string LEVEL = "debug";
    
            //读取配置文件并缓存
            static CustomRollingFileLogger()
            {
                IAppender[] appenders = LogManager.GetRepository().GetAppenders();
                for (int i = 0; i < appenders.Length; i++)
                {
                    if (appenders[i] is ReadParamAppender)
                    {
                        ReadParamAppender appender = (ReadParamAppender)appenders[i];
                        if (appender.MaxSizeRollBackups == 0)
                        {
                            appender.MaxSizeRollBackups = MAX_SIZE_ROLL_BACKUPS;
                        }
                        if (appender.Layout != null && appender.Layout is log4net.Layout.PatternLayout)
                        {
                            appender.LayoutPattern = ((log4net.Layout.PatternLayout)appender.Layout).ConversionPattern;
                        }
                        if (string.IsNullOrEmpty(appender.LayoutPattern))
                        {
                            appender.LayoutPattern = LAYOUT_PATTERN;
                        }
                        if (string.IsNullOrEmpty(appender.DatePattern))
                        {
                            appender.DatePattern = DATE_PATTERN;
                        }
                        if (string.IsNullOrEmpty(appender.MaximumFileSize))
                        {
                            appender.MaximumFileSize = MAXIMUM_FILE_SIZE;
                        }
                        if (string.IsNullOrEmpty(appender.Level))
                        {
                            appender.Level = LEVEL;
                        }
                        lock(lockObj)
                        {
                            appenderContainer[appenders[i].Name] = appender;
                        }
                    }
                }
            }
    
            public static ILog GetCustomLogger(string loggerName, string category = null, bool additivity = false)
            {
                return loggerContainer.GetOrAdd(loggerName, delegate(string name)
                {
                    RollingFileAppender newAppender = null;
                    ReadParamAppender appender = null;
                    if (appenderContainer.ContainsKey(loggerName))
                    {
                        appender = appenderContainer[loggerName];
                        newAppender = GetNewFileApender(loggerName, string.IsNullOrEmpty(appender.File) ? GetFile(category, loggerName) : appender.File, appender.MaxSizeRollBackups,
                            appender.AppendToFile, true, appender.MaximumFileSize, RollingFileAppender.RollingMode.Composite, appender.DatePattern, appender.LayoutPattern);
                    }
                    else
                    {
                        newAppender = GetNewFileApender(loggerName, GetFile(category, loggerName), MAX_SIZE_ROLL_BACKUPS, true, true, MAXIMUM_FILE_SIZE, RollingFileAppender.RollingMode.Composite, 
                            DATE_PATTERN, LAYOUT_PATTERN);
                    }
                    log4net.Repository.Hierarchy.Hierarchy repository = (log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository();
                    Logger logger = repository.LoggerFactory.CreateLogger(repository, loggerName);
                    logger.Hierarchy = repository;
                    logger.Parent = repository.Root;
                    logger.Level = GetLoggerLevel(appender == null ? LEVEL : appender.Level);
                    logger.Additivity = additivity;
                    logger.AddAppender(newAppender);
                    logger.Repository.Configured = true;
                    return new LogImpl(logger);
                });
            }
    
            //如果没有指定文件路径则在运行路径下建立 Log\{loggerName}.txt
            private static string GetFile(string category, string loggerName)
            {
                if (string.IsNullOrEmpty(category))
                {
                    return string.Format(@"Log\{0}.txt", loggerName);
                }
                else
                {
                    return string.Format(@"Log\{0}\{1}.txt", category, loggerName);
                }
            }
    
            private static Level GetLoggerLevel(string level)
            {
                if (!string.IsNullOrEmpty(level))
                {
                    switch (level.ToLower().Trim())
                    {
                        case "debug":
                            return Level.Debug;
    
                        case "info":
                            return Level.Info;
    
                        case "warn":
                            return Level.Warn;
    
                        case "error":
                            return Level.Error;
    
                        case "fatal":
                            return Level.Fatal;
                    }
                }
                return Level.Debug;
            }
    
            private static RollingFileAppender GetNewFileApender(string appenderName, string file, int maxSizeRollBackups, bool appendToFile = true, bool staticLogFileName = false, string maximumFileSize = "5MB", RollingFileAppender.RollingMode rollingMode = RollingFileAppender.RollingMode.Composite, string datePattern = "yyyyMMdd\".txt\"", string layoutPattern = "%d [%t] %-5p %c  - %m%n")
            {
                RollingFileAppender appender = new RollingFileAppender
                {
                    LockingModel = new FileAppender.MinimalLock(),
                    Name = appenderName,
                    File = file,
                    AppendToFile = appendToFile,
                    MaxSizeRollBackups = maxSizeRollBackups,
                    MaximumFileSize = maximumFileSize,
                    StaticLogFileName = staticLogFileName,
                    RollingStyle = rollingMode,
                    DatePattern = datePattern
                };
                PatternLayout layout = new PatternLayout(layoutPattern);
                appender.Layout = layout;
                layout.ActivateOptions();
                appender.ActivateOptions();
                return appender;
            }
        }
    }
    
    

    使用方法

    1. 零配置使用

    Log logger = CustomRollingFileLogger.GetCustomLogger("pay", "10001");  
    logger.Debug("debug message");  
    

    将在运行目录下生成 Log\10001\pay.txt

    按日期分割日志文件,如果文件超过256M,也进行分割。

    <a name="nvctaf"></a>2. 使用配置文件

    修改App.config/Web.config,添加或修改项:

    <configSections>
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
      </configSections>
      <log4net>
        <appender name="pay" type="Rainstorm.Log4net.ReadParamAppender">
          <param name="file" value="D:\\log\\pay.txt"/> <!--文件路径 -->
          <param name="appendToFile" value="true"/> <!--如果同名文件已存在,是否在文件中追加日志 -->
          <param name="maxSizeRollBackups" value="100"/> <!--在发生文件分割时,最多保留的历史文件个数 -->
          <param name="maximumFileSize" value="2MB"/> <!--设置按文件大小分割的阈值 -->
          <param name="datePattern" value="yyyyMMdd'.txt'"/> <!--按日期分割时文件重命名规则 -->
          <param name="level" value="debug"/> <!--logger输出等级 -->
          <layout type="log4net.Layout.PatternLayout"> <!--日志输出格式 -->
            <conversionPattern value="%d - %m%n"/> <!--文件路径 -->
          </layout>
        </appender>
        <root>
          <level value="INFO"/>
          <appender-ref ref="pay"/>
        </root>
      </log4net>
    

    调用方式:

    ILog logger = CustomRollingFileLogger.GetCustomLogger("pay");
    logger.Debug("debug message");
    

    相关链接

    1. 参考文章:基于log4net的支持动态文件名、按日期和大小自动分割文件的日志组件
    2. 参考文章: C#使用Log4Net來紀錄應用程式的日誌


    本文为原创文章,转载请注明出处!欢迎关注任前程博客 https://renqiancheng.com/,第一时间看后续精彩文章。

    相关文章

      网友评论

          本文标题:Log4Net 日志组件通用代码

          本文链接:https://www.haomeiwen.com/subject/raworftx.html