.net8系列-05图文并茂手把手教你.NET Core 下使用 Log4Net 记录日志,配置日志组件log4net

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~

大功告成

结语

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

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

在这里插入图片描述

欢迎路过的小哥哥小姐姐们提出更好的意见哇~~
### 回答1: EfficientNet是一种由Google Research团队开发的高效卷积神经网络模型。它采用了多种技术来提高网络的效率,包括深度可分离卷积、自适应空间金字塔池化和网络缩放系数。 EfficientNet模型结构大体分为三部分: 1. 特征提取层:包含多个深度可分离卷积层和自适应空间金字塔池化层。这些层结合了深度可分离卷积的计算效率和金字塔池化的空间信息保留。 2. 中间层:包含多个普通卷积层和批归一化层。 3. 分类层:包含一个全连接层和一个softmax层。 EfficientNet还采用了网络缩放系数来控制模型的大小和复杂度。这个系数会影响网络中各层的卷积核数量和通道数,以及网络的总参数量。通过调整网络缩放系数,可以在保持网络性能的同时调整网络的大小和复杂度。 EfficientNet在ImageNet数据集上取得了很高的准确率,并且在多种应用中都表现出了优异的性能。 ### 回答2: EfficientNet是一种高效的神经网络模型结构,可以在保持准确性的基础上显著减少模型参数和计算复杂度。EfficientNet基于Convolutional Neural Networks(CNNs),通过优化网络层数、宽度和深度来提高模型效率。 EfficientNet的结构可以分为三个主要部分:宽度乘数(width multiplier)、深度乘数(depth multiplier)和分辨率乘数(resolution multiplier)。 首先,宽度乘数决定了每个层的通道数。宽度乘数小于1时,减少每层的通道数,可以减少计算复杂度,但可能会损失一些特征信息;宽度乘数大于1时,增加通道数,可以提高模型的表达能力,但也会增加计算复杂度。 其次,深度乘数决定了网络的层数。通过减少层数,可以减少网络的计算复杂度;增加层数则可以增加模型的能力。深度乘数与宽度乘数共同作用,可以在减少参数的情况下保持模型的准确性。 最后,分辨率乘数决定了输入图像的分辨率。较低的分辨率可以减少计算复杂度,而较高的分辨率可以提高模型的表达能力。分辨率乘数也可以与宽度乘数和深度乘数共同作用,以在影响模型效率的同时保持其准确性。 EfficientNet还有一个重要的部分是“Squeeze-and-Excitation”模块。这个模块通过学习每个通道的特征重要性,并对其进行加权,从而增强网络在特定任务上的性能。 总之,EfficientNet通过优化网络的层数、宽度和深度以及分辨率乘数来提高模型的效率,并通过“Squeeze-and-Excitation”模块进一步增强模型的性能。这使得EfficientNet在计算能力有限的设备上也能够高效地进行深度学习任务。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值