时间:2020年6月12日11:23:31
事件:重新修改了Log4Net的集成
原由:之前的集成只是将Log4net集成进了Asp.netCore 自带的Logger中使用,文件分类存储只能按照日志级别进行分类,不能按照需要如场景、模块等分类方式进行分类(可能有 我没找到)。故做此修改,可以自定义文件夹分类方式。
原理:使用LogManager获取多个分类的Ilog进行分别记录,各记录各的

安装包-NuGet

Microsoft.Extensions.Logging.Log4Net.AspNetCore

准备配置文件

保存为Log4net.config,属性设置为如果较新则复制

以下删除


  1. <?xml version="1.0" encoding="utf-8"?>
  2. <log4net>
  3. <!-- 将日志以回滚文件的形式写到文件中 -->
  4. <!-- 按日期切分日志文件,并将日期作为日志文件的名字 -->
  5. <!--Error-->
  6. <appender name="ErrorLog" type="log4net.Appender.RollingFileAppender">
  7. <file value="Log\\LogError\\"/>
  8. <appendToFile value="true" />
  9. <rollingStyle value="Date" />
  10. <!--日期的格式,每天换一个文件记录,如不设置则永远只记录一天的日志,需设置-->
  11. <datePattern value="yyyyMMdd&quot;.html&quot;" />
  12. <!--日志文件名是否为静态-->
  13. <StaticLogFileName value="false"/>
  14. <!--多线程时采用最小锁定-->
  15. <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
  16. <!--布局(向用户显示最后经过格式化的输出信息)-->
  17. <layout type="log4net.Layout.PatternLayout">
  18. <ConversionPattern value="&lt;HR COLOR=red&gt;%n【异常时间】:%d [%t] &lt;BR&gt;%n【异常级别】:%-5p &lt;BR&gt;%n%m &lt;BR&gt;%n &lt;HR Size=1&gt;" />
  19. </layout>
  20. <filter type="log4net.Filter.LevelRangeFilter">
  21. <levelMin value="ERROR" />
  22. <levelMax value="FATAL" />
  23. </filter>
  24. </appender>
  25. <!--Error-->
  26. <!--Info-->
  27. <appender name="InfoLog" type="log4net.Appender.RollingFileAppender">
  28. <!--定义文件存放位置-->
  29. <file value="Log\\LogInfo\\"/>
  30. <appendToFile value="true" />
  31. <rollingStyle value="Date" />
  32. <!--日志文件名是否为静态-->
  33. <StaticLogFileName value="false"/>
  34. <!--日期的格式,每天换一个文件记录,如不设置则永远只记录一天的日志,需设置-->
  35. <datePattern value="yyyyMMdd&quot;.html&quot;" />
  36. <!--多线程时采用最小锁定-->
  37. <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
  38. <!--布局(向用户显示最后经过格式化的输出信息)-->
  39. <layout type="log4net.Layout.PatternLayout">
  40. <conversionPattern value="&lt;HR COLOR=blue&gt;%n【日志时间】:%d [%t] &lt;BR&gt;%n【日志级别】:%-5p &lt;BR&gt;%n%m &lt;BR&gt;%n &lt;HR Size=1&gt;" />
  41. </layout>
  42. <filter type="log4net.Filter.LevelRangeFilter">
  43. <levelMin value="DEBUG" />
  44. <levelMax value="WARN" />
  45. </filter>
  46. </appender>
  47. <!--Info-->
  48. <root>
  49. <!-- 控制级别,由低到高:ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF -->
  50. <!-- 比如定义级别为INFO,则INFO级别向下的级别,比如DEBUG日志将不会被记录 -->
  51. <!-- 如果没有定义LEVEL的值,则缺省为DEBUG -->
  52. <level value="ALL" />
  53. <!-- 按日期切分日志文件,并将日期作为日志文件的名字 -->
  54. <appender-ref ref="ErrorLog" />
  55. <appender-ref ref="InfoLog" />
  56. </root>
  57. </log4net>

修改后

<?xml version="1.0" encoding="utf-8"?>
<log4net>
  <!--在这里就可以任意配置自己的日志分类-->
  <!--错误日志类-->
  <logger name="LogError">
    <level value="ALL" />
    <appender-ref ref="LogErrorAppender" />
  </logger>
  <!--普通日志类 -->
  <logger name="LogNormal">
    <level value="ALL" />
    <appender-ref ref="LogNormalAppender" />
  </logger>
  <!--AOP日志类-->
  <logger name="LogAOP">
    <level value="ALL" />
    <appender-ref ref="LogAOPAppender" />
  </logger>
  <!-- 将日志以回滚文件的形式写到文件中 -->
  <!-- 按日期切分日志文件,并将日期作为日志文件的名字 -->
  <!--Error-->
  <appender name="LogErrorAppender" type="log4net.Appender.RollingFileAppender">
    <file value="Log\\LogError\\"/>
    <appendToFile value="true" />
    <rollingStyle value="Date" />
    <!--日期的格式,每天换一个文件记录,如不设置则永远只记录一天的日志,需设置-->
    <datePattern value="yyyyMMdd&quot;_Error.html&quot;" />
    <!--日志文件名是否为静态-->
    <StaticLogFileName value="false"/>
    <!--多线程时采用最小锁定-->
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    <!--布局(向用户显示最后经过格式化的输出信息)-->
    <layout type="log4net.Layout.PatternLayout">
      <ConversionPattern value="&lt;HR COLOR=red&gt;%n【异常时间】:%d [%t] &lt;BR&gt;%n【异常级别】:%-5p &lt;BR&gt;%n%m &lt;BR&gt;%n &lt;HR Size=1&gt;"  />
    </layout>
    <filter type="log4net.Filter.LevelRangeFilter">
      <levelMin value="ERROR" />
      <levelMax value="FATAL" />
    </filter>
  </appender>
  <!--Error-->

  <!--Info-->
  <appender name="LogNormalAppender" type="log4net.Appender.RollingFileAppender">
    <!--定义文件存放位置-->
    <file value="Log\\LogInfo\\"/>
    <appendToFile value="true" />
    <rollingStyle value="Date" />
    <!--日期的格式,每天换一个文件记录,如不设置则永远只记录一天的日志,需设置-->
    <datePattern value="yyyyMMdd&quot;_Info.html&quot;" />
    <!--日志文件名是否为静态-->
    <StaticLogFileName value="false"/>
    <!--多线程时采用最小锁定-->
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    <!--布局(向用户显示最后经过格式化的输出信息)-->
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="&lt;HR COLOR=blue&gt;%n【日志时间】:%d [%t] &lt;BR&gt;%n【日志级别】:%-5p &lt;BR&gt;%n%m &lt;BR&gt;%n &lt;HR Size=1&gt;"  />
    </layout>
    <filter type="log4net.Filter.LevelRangeFilter">
      <levelMin value="DEBUG" />
      <levelMax value="WARN" />
    </filter>
  </appender>

  <!--AOP-->
  <appender name="LogAOPAppender" type="log4net.Appender.RollingFileAppender">
    <!--定义文件存放位置-->
    <file value="Log\\LogAOP\\"/>
    <appendToFile value="true" />
    <rollingStyle value="Date" />
    <!--日期的格式,每天换一个文件记录,如不设置则永远只记录一天的日志,需设置-->
    <datePattern value="yyyyMMdd&quot;_AOP.html&quot;" />
    <!--日志文件名是否为静态-->
    <StaticLogFileName value="false"/>
    <!--多线程时采用最小锁定-->
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    <!--布局(向用户显示最后经过格式化的输出信息)-->
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="&lt;HR COLOR=blue&gt;%n【日志时间】:%d [%t] &lt;BR&gt;%n【日志级别】:%-5p &lt;BR&gt;%n%m &lt;BR&gt;%n &lt;HR Size=1&gt;"  />
    </layout>
    <filter type="log4net.Filter.LevelRangeFilter">
      <levelMin value="DEBUG" />
      <levelMax value="WARN" />
    </filter>
  </appender>
</log4net>

在Programer中注册Log4Net服务

.ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>()
                    .ConfigureLogging((hostingContext, builder) =>
                    {
                        //该方法需要引入Microsoft.Extensions.Logging名称空间
                        builder.AddFilter("System", LogLevel.Error); //过滤掉系统默认的一些日志
                        builder.AddFilter("Microsoft", LogLevel.Error);//过滤掉系统默认的一些日志

                        //添加Log4Net
                        var path = Path.Combine(Directory.GetCurrentDirectory(), "Log4net.config");
                        //不带参数:表示log4net.config的配置文件就在应用程序根目录下,也可以指定配置文件的路径
                        //需要添加nuget包:Microsoft.Extensions.Logging.Log4Net.AspNetCore
                        builder.AddLog4Net(path);
                    });
                });

封装一个Loghelper封装类

为什么不用系统的ILogger?因为我用不习惯,且暴露方法太多,实际开发中没必要,容易产生不必要的麻烦。
封装位置根据自己的情况定义就可以

以下删除


定义两个类

  • ILogHelper

    public interface ILogHelper
      {
          public void LogErr(string throwMsg, Exception ex);
          public void LogErr(string errkey, string errmsg);
          public void LogInfo(string key, string msg);
          public void LogInfo(string msg);
      }
    
  • LogHelper ```csharp public class LogHelper : ILogHelper// {

      private readonly ILogger _logger;
    
      public LogHelper(ILogger<LogHelper> logger)
      {
          _logger = logger;
      }
    
      public  void LogErr(string throwMsg, Exception ex)
      {
    
              var errorMsg =
                  $"【抛出信息】:{throwMsg} \r\n<br/>【异常类型】:{ex.GetType().Name} \r\n<br/>【异常信息】:{ex.Message} \r\n<br/>【堆栈调用】:\r\n<br/>{ex.StackTrace}\r\n<br/>【堆栈调用】:\r\n<br/>{ex.ToString()}";
          _logger.LogError(errorMsg);
    
    }
    public void LogErr(string errkey, string errmsg)
    {
        _logger.LogError(errkey+":"+ errmsg);
    }
    public  void LogInfo(string key,string msg)
    {

        _logger.LogInformation(key + ":" + msg);


    }
    public  void LogInfo(string msg)
    {
        _logger.LogInformation(msg);

    }
}
*说明下 为什么加<br/> ,因为我Log4net.config 中文件名配置的是html
<a name="kcr1h"></a>
## 依赖注入LogHelpre
*我用的是AutoFact,AutoFact添加方式很简单 下一篇说一下 [点击跳转](https://www.yuque.com/yourng/neter/xbbplz)
```csharp
/// <summary>
/// 自定义容器服务注册
/// </summary>
/// <param name="builder"></param>
public void ConfigureContainer(ContainerBuilder builder)
{
    builder.RegisterType<LogHelper>().As<ILogHelper>().SingleInstance();
}

修改后

public static class Log4NetHelper
    {//log4net日志初始化 这里就读取多个配置节点

        private static readonly ILog _logError = LogManager.GetLogger(Assembly.GetCallingAssembly(), "LogError");
        private static readonly ILog _logNormal = LogManager.GetLogger(Assembly.GetCallingAssembly(), "LogNormal");
        private static readonly ILog _logAOP = LogManager.GetLogger(Assembly.GetCallingAssembly(), "LogAOP");

        public static void LogErrException(string info, Exception ex)
        {
            if (_logError.IsErrorEnabled)
            {
                _logError.Error(info, ex);
            }
        }
        public static void LogErr(string message)
        {
            if (_logError.IsErrorEnabled)
            {
                _logError.Error(message);
            }
        }

        public static void LogNormal(string info)
        {
            if (_logNormal.IsInfoEnabled)
            {
                _logNormal.Info(info);
            }
        }

        public static void LogAOP(string key, string info)
        {
            if (_logAOP.IsInfoEnabled)
            {
                _logAOP.Info($"{key}:{info}");
            }
        }
        public static void LogAOP(string info)
        {
            if (_logAOP.IsInfoEnabled)
            {
                _logAOP.Info(info);
            }
        }
    }

Controller中测试

以下删除


private readonly ILogger<WeatherForecastController> _logger;
private readonly ILogHelper _logHelper;

public WeatherForecastController(ILogger<WeatherForecastController> logger, ILogHelper logHelper)
{
    _logger = logger;//这是默认的
    _logHelper = logHelper;//这是我们封装的 我们用这个
}

#region 日志测试
_logHelper.LogErr("测试异常", new Exception("哈哈哈"));
_logHelper.LogInfo("测试信息");
#endregion

修改后

直接使用即可
Log4NetHelper.LogNormal(“Cc”);
Log4NetHelper.LogAOP(“Cc”);
Log4NetHelper.LogErr(“Cc”,new Exception(“丁亥戊”));
image.png