.Net Core 学习——log4net的使用

一、简介

       Log4net 是 Apache 下一个开放源码的项目,它是Log4j 的一个克隆版。我们可以控制日志信息的输出目的地。Log4net中定义了多种日志信息输出模式。 

       在做项目的时候令我最头疼的是在程序发布到正式环境之后出现了问题,我们不能调试而且问题很难重新,于是我们需要大量的日志数据来精确的跟踪程序的运行状况。 

       Log4net就可以帮我来解决这一个难题,对于日志的输出我们不需要人为的去干涉,它可以根据需要将日志输出到控制台,文本文件,windows 日志事件查看器中,包括数据库,邮件等等位置,以便我们快速跟踪程序bug。 

二、简单使用

工具:VS2019,win10,web api

1、从NuGet下载log4

2、在Startup.cs增加

//log4net日志
public static ILoggerRepository repository { get; set; }

public Startup(IConfiguration configuration)
{
    Configuration = configuration;
    //
    repository = LogManager.CreateRepository("AprilLog");
    XmlConfigurator.Configure(repository, new FileInfo("Config/log4net.config"));
    BasicConfigurator.Configure(repository);
}

3、在项目中添加配置文件:log4net.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <!-- This section contains the log4net configuration settings -->
  <log4net>
    <!-- Setup the root category, add the appenders and set the default level -->
    <root>
      <!-- 日志等级 -->
      <level value="ALL" />
      <appender-ref ref="RollingLogFileAppender" />
    </root>

    <!-- Define some output appenders -->
    <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
      <!--日志文件路径,会自动创建-->
      <file value="demoLogs/" />

      <!--追加日志内容-->
      <appendToFile value="true" />

      <!--防止多线程时不能写Log,官方说线程非安全-->
      <!--很关键的一句,让日志文件不被占用-->
      <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />

      <!--可以为:Once|Size|Date|Composite-->
      <!--Composite为Size和Date的组合-->
      <rollingStyle value="Composite" />

      <!--当备份文件时,为文件名加的后缀,这里可以作为每一天的日志分别存储不同的文件-->
      <datePattern value="yyyyMMdd'.log'" />
      <StaticLogFileName value="false"/>

      <!--日志最大个数,都是最新的-->
      <!--rollingStyle节点为Size时,只能有value个日志-->
      <!--rollingStyle节点为Composite时,每天有value个日志-->
      <maxSizeRollBackups value="10" />

      <!--可用的单位:KB|MB|GB-->
      <maximumFileSize value="10MB" />

      <!--输出级别在INFO和ERROR之间的日志-->
      <filter type="log4net.Filter.LevelRangeFilter">
        <param name="LevelMin" value="DEBUG" />
        <param name="LevelMax" value="FATAL" />
      </filter>

      <layout type="log4net.Layout.PatternLayout">
          <!--日志输出格式:时间  日志类型  日志内容-->
          <conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/>
      </layout>
    </appender>
  </log4net>
</configuration>

4、在需要使用日志的控制台添加:

private ILog log = LogManager.GetLogger(Startup.repository.Name, typeof(StudentController));

三、Log4Net 结构

Log4net 主要分为5个核心主键: Logger、Appender、Filter、Layout、Object Render 

1、Logger

       Logger主要用于记录日志的分类和控制日志的级别。它可以以多种格式输出日志信息,同时它也可以控制日志的输出级别。上面的简单例子我们看似做了日志输出,但是没有输出任何日志结果,因为我们在日志级别上做了限制。 

2、Appender

       这里我们简单称之为 附着器。意思就是说日志的输出必须依赖于它,更确切的说以文本形式输出,还是控制台格式输出都必须要依靠它来控制。Log4net定义了多种附着器:

        (1) AdoNetAppender 将日志记录到数据库中。可以采用SQL和存储过程两种方式 

        (2) AnsiColorTerminalAppender 在ANSI 窗口终端写下高亮度的日志事件 

        (3) AspNetTraceAppender 能用asp.net中Trace的方式查看记录的日志

        (4) BufferingForwardingAppender 在输出到子Appenders之前先缓存日志事件 

        (5) ConsoleAppender 将日志输出到控制台 

        (6) EventLogAppender 将日志写到Windows Event Log 

        (7) FileAppender 将日志写到文件中 

        (8) MemoryAppender 将日志存到内存缓冲区 

        (9) NetSendAppender 将日志输出到Windows Messenger service.这些日志信息将在用户终端的对话框中显示 

        (10) RemoteSyslogAppender 通过UDP网络协议将日志写到Remote syslog service

        (11) RemotingAppender 通过.NET Remoting将日志写到远程接收端 

        (12) RollingFileAppender 将日志以回滚文件的形式写到文件中 

        (13) SmtpAppender 将日志写到邮件中 

        (14) TraceAppender 将日志写到.NET trace 系统 

        (15) UdpAppender 将日志connectionless UDP datagrams的形式送到远程宿主或以UdpClient的形式广播 

3、Filter

       Appender 是将日志以缺省值的方式输出,意思就是按照默认值的方式输出。而Filter 意思就是过滤器,使用Filter 可以将日志以不同格式来输出 

4、Layout

      这个用于控制日志输出显示格式 

5、Object Render

      用于按照用户自定义标准来输出日志 


Log4net 的日志对象管理器——LogManager

       LogManager是用于来管理所有的Logger对象的,GetLogger() 可以用来查找已经存在的Logger对象,如果对象不存在它会自动创建一个Logger对象,并且管理它 。

四、更多配置

<log4net>
    
    <!--记录日志到数据库-->
    <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
      <bufferSize value="100" />
      <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
      <connectionString value="data source=GAS-HECHEN;initial catalog=dsc141051_db;integrated security=false;persist security info=True;User ID=sa;Password=000000" />
      <commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)" />
      <parameter>
        <parameterName value="@log_date" />
        <dbType value="DateTime" />
        <layout type="log4net.Layout.RawTimeStampLayout" />
      </parameter>
      <parameter>
        <parameterName value="@thread" />
        <dbType value="String" />
        <size value="255" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%thread" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@log_level" />
        <dbType value="String" />
        <size value="50" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%level" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@logger" />
        <dbType value="String" />
        <size value="255" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%logger" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@message" />
        <dbType value="String" />
        <size value="4000" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%message" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@exception" />
        <dbType value="String" />
        <size value="2000" />
        <layout type="log4net.Layout.ExceptionLayout" />
      </parameter>
    </appender>
    
    <!--输入日志到控制台-->
    <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="[时间]:%d%n[级别]:%p%n[内容]:%m%n%n"></conversionPattern>
      </layout>
    </appender>

    <appender name="FileAppender" type="log4net.Appender.FileAppender">
      <param name="file" value="D:\a.log"></param>
      <param name="appendToFile" value="true"></param>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="[时间]:%d%n[级别]:%p%n[内容]:%m%n%n"></conversionPattern>
      </layout>
    </appender>
    
    <root>
      <level value="INFO"></level>
      <appender-ref ref="FileAppender"></appender-ref>
      <appender-ref ref="ConsoleAppender"></appender-ref>
    </root>
    <logger name="MyLogger">
      <level value="INFO"></level>
      <appender-ref ref="FileAppender"></appender-ref>
      <appender-ref ref="ConsoleAppender"></appender-ref>
    </logger>
</log4net>

配置文件定义了三种不同的Appender,分别是ADO.NET 记录到数据,ConsoleAppender 从控制台输出, FileAppender 日志信息文件输出。更多详情查看:https://www.cnblogs.com/qingyuan/archive/2011/05/13/2045616.html

五、日志帮助类

首先创建一个仓储类

public class Log4NetRepository
{
    public static ILoggerRepository loggerRepository { get; set; }
}

 

    /// <summary>
    /// log4net帮助类
    /// AdoNetAppender仅支持到.net framework4.5,不支持在.net core项目中持久化日志到数据库
    /// </summary>
    public class LogHelper
    {
        // 异常 // 注意:logger name不要写错
        private static readonly ILog logerror = LogManager.GetLogger(Log4NetRepository.loggerRepository.Name, "errLog");
        // 记录
        private static readonly ILog loginfo = LogManager.GetLogger(Log4NetRepository.loggerRepository.Name, "infoLog");

        public static void Error(string throwMsg, Exception ex)
        {
            string errorMsg = string.Format("【异常描述】:{0} <br>【异常类型】:{1} <br>【异常信息】:{2} <br>【堆栈调用】:{3}", 
                new object[] {
                    throwMsg,
                    ex.GetType().Name,
                    ex.Message,
                    ex.StackTrace });
            errorMsg = errorMsg.Replace("\r\n", "<br>");
            logerror.Error(errorMsg);
        }

        public static void Info(string message)
        {
            loginfo.Info(string.Format("【日志信息】:{0}",message));
        }

    }

 

 startup引用log4netlog4net.Configlog4net.Repository。在startup的构造函数中这么配置:

 

public static ILoggerRepository repository { get; set; }

public Startup(IConfiguration configuration)
{
    Configuration = configuration;
    // log4net 仓储
    repository = LogManager.CreateRepository("CoreLogRepository");
    XmlConfigurator.Configure(repository, new FileInfo("config/log4net.config"));
    Log4NetRepository.loggerRepository = repository;
}

 

之前写好了全局异常捕获,现在可以加上这么一句。

public class ApiExceptionFilter:ExceptionFilterAttribute
    {
        private IHostingEnvironment _env;
        public ApiExceptionFilter(IHostingEnvironment env)
        {
            _env = env;
        }

        public override void OnException(ExceptionContext context)
        {
            if (context.ExceptionHandled)
            {
                return;
            }
            LogHelper.Error(exMsg, context.Exception); // 日志记录
            var exMsg = context.Exception.Message;
            ApiResp resp = new ApiResp(ApiRespCode.E999999,exMsg);
            // 开发环境显示异常信息
            if(_env.IsDevelopment())
            {
                resp.Message = exMsg;
            }
            context.Result = new JsonResult(resp);
            context.ExceptionHandled = true;
        }
    }

当发生异常时,会自动在项目目录创建Log\LogError\目录,并写入日志文件。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值