掘金 后端 ( ) • 2024-04-30 11:35

log4net是什么?

log4net是Apache软件基金会为.NET平台开发的一个日志记录库。它是Apache log4j框架的.NET移植版本,属于Apache Logging Services项目的一部分。

为什么使用log4net?

log4net设计用于帮助.NET应用程序的开发者控制日志信息的生成过程,使得日志信息可以根据配置被输出到多种目的地,包括控制台、文件系统、数据库、电子邮件、Windows事件日志等。

log4net有什么特点?

分级日志级别:支持DEBUG、INFO、WARN、ERROR、FATAL等多个日志级别,允许开发者精细控制输出哪些信息。 灵活的配置:强大的XML配置文件支持,可以在不修改代码的情况下调整日志行为。 多种输出目标:支持多种日志信息的目的地,易于扩展。 定制化布局:可以定制日志信息的格式,如添加时间戳、线程信息等。 性能优化:通过缓冲和异步写入等机制减少日志记录对应用程序性能的影响。

log4net怎么用?

安装log4net解决方案包

安装Microsoft.Extensions.Logging.Log4Net.解决方案包

编写配置文件

xiaojinWebApplication\xiaojinWebApplication\configFile\log4net.Config

<?xml version="1.0" encoding="utf-8"?>
<log4net>
	<!-- Define some output appenders -->
	<appender name="rollingAppender" type="log4net.Appender.RollingFileAppender">
		<file value="log4\log.txt" />
		<!--追加日志内容-->
		<appendToFile value="true" />

		<!--防止多线程时不能写Log,官方说线程非安全-->
		<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />

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

		<!--当备份文件时,为文件名加的后缀-->
		<datePattern value="yyyyMMdd.TXT" />

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

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

		<!--置为true,当前最新日志文件名永远为file节中的名字-->
		<staticLogFileName value="true" />

		<!--输出级别在INFO和ERROR之间的日志-->
		<filter type="log4net.Filter.LevelRangeFilter">
			<param name="LevelMin" value="ALL" />
			<param name="LevelMax" value="FATAL" />
		</filter>
		<layout type="log4net.Layout.PatternLayout">
			<conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/>
		</layout>
	</appender>

	<!--SqlServer形式-->
	<!--log4net日志配置:http://logging.apache.org/log4net/release/config-examples.html -->
	<appender name="AdoNetAppender_SqlServer" type="log4net.Appender.AdoNetAppender">
		<!--日志缓存写入条数 设置为0时只要有一条就立刻写到数据库-->
		<bufferSize value="0" />
		<connectionType value="System.Data.SqlClient.SqlConnection,System.Data.SqlClient, Version=4.6.1.3, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
		<connectionString value="Data Source=PC-202206030027;Initial Catalog=LogManager;Persist Security Info=True;User ID=sa;Password=sa123" />
		<commandText value="INSERT INTO Log4Net ([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>
	
	
	<root>

		<!--控制级别,由低到高: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF-->
		<!--OFF:0-->
		<!--FATAL:FATAL-->
		<!--ERROR: ERROR,FATAL-->
		<!--WARN: WARN,ERROR,FATAL-->
		<!--INFO: INFO,WARN,ERROR,FATAL-->
		<!--DEBUG: INFO,WARN,ERROR,FATAL-->
		<!--ALL: DEBUG,INFO,WARN,ERROR,FATAL--> 
		<priority value="ALL"/>
		
		<level value="INFO"/>
		<appender-ref ref="rollingAppender" />
		<appender-ref ref="AdoNetAppender_SqlServer" />
	</root>
</log4net>

暂时注释数据库日志,等到我们链接数据库后我们再进行使用

注释root里的AdoNetAppender_SqlServer

	<root>

		<!--控制级别,由低到高: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF-->
		<!--OFF:0-->
		<!--FATAL:FATAL-->
		<!--ERROR: ERROR,FATAL-->
		<!--WARN: WARN,ERROR,FATAL-->
		<!--INFO: INFO,WARN,ERROR,FATAL-->
		<!--DEBUG: INFO,WARN,ERROR,FATAL-->
		<!--ALL: DEBUG,INFO,WARN,ERROR,FATAL--> 
		<priority value="ALL"/>
		
		<level value="INFO"/>
		<appender-ref ref="rollingAppender" />
		<!-- <appender-ref ref="AdoNetAppender_SqlServer" /> -->
	</root>

配置NLog.Config

xiaojinWebApplication\xiaojinWebApplication\configFile\NLog.Config

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
      autoReload="true"
      throwExceptions="false"
      internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log">

	<!-- optional, add some variables
  https://github.com/nlog/NLog/wiki/Configuration-file#variables
  -->
	<variable name="myvar" value="myvalue"/>

	<!--
  See https://github.com/nlog/nlog/wiki/Configuration-file
  for information on customizing logging rules and outputs.
   -->
	<targets>
		<!--
    add your targets here
    See https://github.com/nlog/NLog/wiki/Targets for possible targets.
    See https://github.com/nlog/NLog/wiki/Layout-Renderers for the possible layout renderers.
    -->
		<target name="AllDatabase" xsi:type="Database"
			  dbProvider="System.Data.SqlClient.SqlConnection, System.Data.SqlClient"
			  connectionString="Data Source=PC-202206030027;Initial Catalog=LogManager;Persist Security Info=True;User ID=sa;Password=sa123"
			  commandText="insert into dbo.NLog (Application, Logged, Level, Message,Logger, CallSite, Exception) values (@Application, @Logged, @Level, @Message,@Logger, @Callsite, @Exception);">
			<parameter name="@application" layout="AspNetCoreNlog" />
			<parameter name="@logged" layout="${date}" />
			<parameter name="@level" layout="${level}" />
			<parameter name="@message" layout="${message}" />
			<parameter name="@logger" layout="${logger}" />
			<parameter name="@callSite" layout="${callsite:filename=true}" />
			<parameter name="@exception" layout="${exception:tostring}" />
		</target>

		<target xsi:type="File" name="allfile" fileName="NLog\nlog-all-${shortdate}.log"
				layout="${longdate}|${logger}|${uppercase:${level}}|${message} ${exception}" />
		<!--同样是将文件写入日志中,写入的内容有所差别,差别在layout属性中体现。写入日志的数量有差别,差别在路由逻辑中体现-->
		<target xsi:type="File" name="ownFile-web" fileName="NLog\nlog-my-${shortdate}.log"
				 layout="${longdate}|${logger}|${uppercase:${level}}|${message} ${exception}" />
		<target xsi:type="Null" name="blackhole" />
		<!--
    Write events to a file with the date in the filename.
    <target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log"
            layout="${longdate} ${uppercase:${level}} ${message}" />
    -->
	</targets>

	<rules>
		<logger name="*" minlevel="Trace" writeTo="AllDatabase" />
		<!-- add your logging rules here -->
		<!--路由顺序会对日志打印产生影响。路由匹配逻辑为顺序匹配。-->
		<!--All logs, including from Microsoft-->
		<logger name="*" minlevel="Trace" writeTo="allfile" />
		<!--Skip Microsoft logs and so log only own logs-->
		<!--以Microsoft打头的日志将进入此路由,由于此路由没有writeTo属性,所有会被忽略-->
		<!--且此路由设置了final,所以当此路由被匹配到时。不会再匹配此路由下面的路由。未匹配到此路由时才会继续匹配下一个路由-->
		<logger name="Microsoft.*" minlevel="Trace"  final="true" />
		<!--上方已经过滤了所有Microsoft.*的日志,所以此处的日志只会打印除Microsoft.*外的日志-->
		<logger name="*" minlevel="Trace" writeTo="ownFile-web" />
		<!--
    Write all events with minimal level of Debug (So Debug, Info, Warn, Error and Fatal, but not Trace)  to "f"
    <logger name="*" minlevel="Debug" writeTo="f" />
    -->
	</rules>
</nlog>

设置编译属性

右键两个配置文件,改为始终编译

配置日志生效逻辑

在Program.cs文件中注册

// log4net---start
builder.Logging.AddLog4Net("configFile/log4net.Config");
// log4net---end

日志使用:构造函数注入

在测试接口文件中添加如下代码(我这个已经有了哦)

 private readonly ILogger<CommonInfoController> _logger;

 public CommonInfoController(ILogger<CommonInfoController> logger)
 {
     _logger = logger;
 }

添加日志测试代码

 public CommonInfoController(ILogger<CommonInfoController> logger)
 {
     _logger = logger;
     _logger.LogInformation(" LogInformation; this is CommonInfoController 构造函数~");
     _logger.LogError("LogError: this is CommonInfoController 构造函数~");
     _logger.LogWarning("LogWarning: this is CommonInfoController 构造函数~");
     _logger.LogDebug("LogDebug:this is CommonInfoController 构造函数~");
 }

第二种用法

   private readonly ILogger<CommonInfoController> _logger; // 方案一
  private readonly ILoggerFactory _ILoggerFactory; // 方案二
  public CommonInfoController(ILogger<CommonInfoController> logger, ILoggerFactory iLoggerFactory)
  {
      _logger = logger;
      _logger.LogInformation("方案一 LogInformation; this is CommonInfoController 构造函数~");
      _logger.LogError("方案一LogError: this is CommonInfoController 构造函数~");
      _logger.LogWarning("方案一LogWarning: this is CommonInfoController 构造函数~");
      _logger.LogDebug("方案一LogDebug:this is CommonInfoController 构造函数~");

      _ILoggerFactory = iLoggerFactory; // 方案二
      ILogger<CommonInfoController> _loger2 = _ILoggerFactory.CreateLogger<CommonInfoController>();
      _loger2.LogInformation("方案二LogInformation; this is CommonInfoController 构造函数~");
      _loger2.LogError("方案二LogError: this is CommonInfoController 构造函数~");
      _loger2.LogWarning("方案二LogWarning: this is CommonInfoController 构造函数~");
      _loger2.LogDebug("方案二LogDebug:this is CommonInfoController 构造函数~");
  }


接口中记录日志

/// <summary>
/// 测试接口01
/// </summary>
/// <returns></returns>
[HttpGet(Name = "getCommonInfo")]
public CommonInfo getCommonInfo()
{
    _logger.LogInformation("测试接口01~");
    _logger.LogError("测试接口01~");
    _logger.LogWarning("测试接口01~");
    _logger.LogDebug("测试接口01~");

    return new CommonInfo
    {
        Date = DateOnly.FromDateTime(DateTime.Now),
        Text = "getCommonInfo"
    };
}

启动项目

调用接口

查看日志

根据我们的配置项,日志在这个地方存储:"\xiaojinWebApplication\bin\Debug\net8.0\log4\log.txt"

2024-04-30 01:29:51,143 [1] INFO  Microsoft.Hosting.Lifetime - Now listening on: http://localhost:5064
2024-04-30 01:29:51,153 [1] INFO  Microsoft.Hosting.Lifetime - Application started. Press Ctrl+C to shut down.
2024-04-30 01:29:51,154 [1] INFO  Microsoft.Hosting.Lifetime - Hosting environment: Development
2024-04-30 01:29:51,155 [1] INFO  Microsoft.Hosting.Lifetime - Content root path: C:\Users\testDemo\net-demo\xiaojinWebApplication\xiaojinWebApplication
2024-04-30 01:30:17,271 [7] INFO  xiaojinWebApplication.Controllers.CommonInfoController - 方案一 LogInformation; this is CommonInfoController 构造函数~
2024-04-30 01:30:17,279 [7] ERROR xiaojinWebApplication.Controllers.CommonInfoController - 方案一LogError: this is CommonInfoController 构造函数~
2024-04-30 01:30:17,281 [7] WARN  xiaojinWebApplication.Controllers.CommonInfoController - 方案一LogWarning: this is CommonInfoController 构造函数~
2024-04-30 01:30:17,282 [7] INFO  xiaojinWebApplication.Controllers.CommonInfoController - 方案二LogInformation; this is CommonInfoController 构造函数~
2024-04-30 01:30:17,285 [7] ERROR xiaojinWebApplication.Controllers.CommonInfoController - 方案二LogError: this is CommonInfoController 构造函数~
2024-04-30 01:30:17,287 [7] WARN  xiaojinWebApplication.Controllers.CommonInfoController - 方案二LogWarning: this is CommonInfoController 构造函数~
2024-04-30 01:30:17,289 [7] INFO  xiaojinWebApplication.Controllers.CommonInfoController - 测试接口01~
2024-04-30 01:30:17,290 [7] ERROR xiaojinWebApplication.Controllers.CommonInfoController - 测试接口01~
2024-04-30 01:30:17,291 [7] WARN  xiaojinWebApplication.Controllers.CommonInfoController - 测试接口01~

大功告成

结语

  • 今天就写到这里啦~
  • 小伙伴们,( ̄ω ̄( ̄ω ̄〃 ( ̄ω ̄〃)ゝ我们明天再见啦~~
  • 大家要天天开心哦

欢迎大家指出文章需要改正之处~
学无止境,合作共赢

在这里插入图片描述

欢迎路过的小哥哥小姐姐们提出更好的意见哇~~