.NET 6.0 中接入 Log4net 和 NLog

一、接入Log4net

1.按日期和大小混合分割日志

nuget包安装

复制代码
log4net
Microsoft.Extensions.Logging.Log4Net.AspNetCore

配置文件

配置文件内容为

<?xml version="1.0" encoding="utf-8"?>

<log4net>

<!-- Define some output appenders -->

<appender name="rollingAppender" type="log4net.Appender.RollingFileAppender">

<!-- value="logs/log.log"-->

<file value="logs/" />

<!--追加日志内容-->

<appendToFile value="true" />

<!--防止多线程时不能写Log,官方说线程非安全-->

<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />

<!--可以为:Once|Size|Date|Composite-->

<!--Composite为Size和Date的组合-->

<rollingStyle value="Composite" />

<!--当备份文件时,为文件名加的后缀-->

<datePattern value="yyyyMMdd/"log.log"" />

<!--日志最大个数,都是最新的-->

<!--rollingStyle节点为Size时,只能有value个日志-->

<!--rollingStyle节点为Composite时,每天有value个日志-->

<maxSizeRollBackups value="20" />

<!--可用的单位:KB|MB|GB-->

<maximumFileSize value="3MB" />

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

<staticLogFileName value="false" />

<!--输出级别在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>

<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"/>

<!--使用上面配置的那个规则,ref指定上面的规则名称-->

<appender-ref ref="rollingAppender" />

</root>

</log4net>

程序引入,Program.cs文件增加

builder.Logging.AddLog4Net("Configs/log4net.Config");

//Nuget引入:

//1.Log4Net

//2.Microsoft.Extensions.Logging.Log4Net.AspNetCore

builder.Services.AddControllersWithViews();

程序使用

public class HomeController : Controller

{

private readonly ILogger<HomeController> _logger;

public HomeController(ILogger<HomeController> logger)

{

_logger = logger;

}

public IActionResult Index()

{

_logger.LogInformation($"{this.GetType()},info,接口访问");

_logger.LogError($"{this.GetType()},error,接口访问错误");

return View();

}

}

效果:

2.日志分级独立文件夹显示

上面全部等级的日志信息都显示在同一个文件夹,如果想找error信息,如果日志量大并不好查找,所以把error的独立出来。

增加配置信息

完整配置文件

<?xml version="1.0" encoding="utf-8"?>

<log4net>

<!-- Define some output appenders -->

<appender name="rollingAppender" type="log4net.Appender.RollingFileAppender">

<!-- value="logs/log.log"-->

<file value="logs/" />

<!--追加日志内容-->

<appendToFile value="true" />

<!--防止多线程时不能写Log,官方说线程非安全-->

<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />

<!--可以为:Once|Size|Date|Composite-->

<!--Composite为Size和Date的组合-->

<rollingStyle value="Composite" />

<!--当备份文件时,为文件名加的后缀-->

<datePattern value="yyyyMMdd/"log.log"" />

<!--日志最大个数,都是最新的-->

<!--rollingStyle节点为Size时,只能有value个日志-->

<!--rollingStyle节点为Composite时,每天有value个日志-->

<maxSizeRollBackups value="20" />

<!--可用的单位:KB|MB|GB-->

<maximumFileSize value="3MB" />

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

<staticLogFileName value="false" />

<!--输出级别在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>

<!-- error日志 -->

<appender name="errorAppender" type="log4net.Appender.RollingFileAppender">

<file value="logs/" />

<appendToFile value="true" />

<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />

<rollingStyle value="Composite" />

<datePattern value="yyyyMMdd/"error.log"" />

<maxSizeRollBackups value="20" />

<maximumFileSize value="3MB" />

<staticLogFileName value="false" />

<filter type="log4net.Filter.LevelRangeFilter">

<param name="LevelMin" value="ERROR" />

<param name="LevelMax" value="ERROR" />

</filter>

<layout type="log4net.Layout.PatternLayout">

<conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/>

</layout>

</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"/>

<!--使用上面配置的那个规则,ref指定上面的规则名称-->

<appender-ref ref="rollingAppender" />

<appender-ref ref="errorAppender" />

</root>

</log4net>

运行,日志打印效果

3.log4net日志写入数据库

这里以log4net写入Mysql为示例

引入Nuget包

复制代码
MySql.Data

数据库日志表脚本

CREATE TABLE `logs` (

`log_id` bigint NOT NULL AUTO_INCREMENT,

`app_name` varchar(100) NOT NULL,

`log_date` datetime NOT NULL,

`thread` varchar(100) NOT NULL,

`level` varchar(50) NOT NULL,

`logger` varchar(255) NOT NULL,

`message` varchar(1000) NOT NULL,

`exception` varchar(2000) NOT NULL,

PRIMARY KEY (`log_id`)

) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

增加配置信息

完整配置文件

<?xml version="1.0" encoding="utf-8"?>

<log4net>

<!-- Define some output appenders -->

<appender name="rollingAppender" type="log4net.Appender.RollingFileAppender">

<!-- value="logs/log.log"-->

<file value="logs/" />

<!--追加日志内容-->

<appendToFile value="true" />

<!--防止多线程时不能写Log,官方说线程非安全-->

<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />

<!--可以为:Once|Size|Date|Composite-->

<!--Composite为Size和Date的组合-->

<rollingStyle value="Composite" />

<!--当备份文件时,为文件名加的后缀-->

<datePattern value="yyyyMMdd/"log.log"" />

<!--日志最大个数,都是最新的-->

<!--rollingStyle节点为Size时,只能有value个日志-->

<!--rollingStyle节点为Composite时,每天有value个日志-->

<maxSizeRollBackups value="20" />

<!--可用的单位:KB|MB|GB-->

<maximumFileSize value="3MB" />

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

<staticLogFileName value="false" />

<!--输出级别在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>

<!-- error日志 -->

<appender name="errorAppender" type="log4net.Appender.RollingFileAppender">

<file value="logs/" />

<appendToFile value="true" />

<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />

<rollingStyle value="Composite" />

<datePattern value="yyyyMMdd/"error.log"" />

<maxSizeRollBackups value="20" />

<maximumFileSize value="3MB" />

<staticLogFileName value="false" />

<filter type="log4net.Filter.LevelRangeFilter">

<param name="LevelMin" value="ERROR" />

<param name="LevelMax" value="ERROR" />

</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="mysqlAppender" type="log4net.Appender.AdoNetAppender">

<!--日志缓存写入条数 设置为0时只要有一条就立刻写到数据库-->

<bufferSize value="0" />

<connectionType value="MySql.Data.MySqlClient.MySqlConnection, MySql.Data" />

<connectionString value="server=127.0.0.1;database=test_db;user=root;pwd=123456;SslMode=none" />

<commandText value="INSERT INTO logs(app_name,log_date, thread, `level`, logger, message, `exception`)VALUES(@app_name,@log_date, @thread,@log_level, @logger, @message, @exception);" />

<parameter>

<parameterName value="@app_name" />

<dbType value="String" />

<size value="100" />

<layout type="log4net.Layout.PatternLayout" >

<conversionPattern value="api" />

</layout>

</parameter>

<parameter>

<parameterName value="@log_date" />

<dbType value="DateTime" />

<layout type="log4net.Layout.RawTimeStampLayout" />

</parameter>

<parameter>

<parameterName value="@thread" />

<dbType value="String" />

<size value="100" />

<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="1000" />

<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"/>

<!--使用上面配置的那个规则,ref指定上面的规则名称-->

<appender-ref ref="rollingAppender" />

<appender-ref ref="errorAppender" />

<appender-ref ref="mysqlAppender" />

</root>

</log4net>

效果

如果是SqlServer

引入Nuget包

复制代码
System.Data.SqlClient

connectionType写上SqlServer的连接类型

复制代码
<connectionType value="System.Data.SqlClient.SqlConnection,System.Data.SqlClient, Version=4.6.1.3, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />

连接字符串处改成SqlServer的连接字符串即可。

二、接入NLog

1.写文本日志

引入Nuget包

复制代码
NLog.Web.AspNetCore

配置文件内容

<?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="NLog\all_log.log">

<targets>

<!--文件日志,archive相关参数:文件拆分,每100M拆分一个新文件-->

<target xsi:type="File"

name="all_log"

fileName="NLog\{shortdate}\\{uppercase:${level}}.log"

layout="{longdate}\|{logger}|{uppercase:{level}}|${message} ${exception}"

archiveFileName="NLog\{shortdate}\\{uppercase:{level}}{shortdate}.{####}.log"

archiveNumbering="Rolling"

archiveAboveSize="10485760"

concurrentwrites="true"

maxArchiveFiles="100"

/>

</targets>

<rules>

<!-- add your logging rules here -->

<!--路由顺序会对日志打印产生影响。路由匹配逻辑为顺序匹配。-->

<logger name="*" minlevel="Trace" writeTo="all_log" />

</rules>

</nlog>

程序引入NLog

程序使用:

结果:

2.过滤日志

有一些组件自带了日志的,像上面的Microsoft.*开头就是.Net Core自带的,我们想屏蔽掉一些dll的日志怎么弄呢

修改配置规则

效果:

3.自定义日志文件名

很多时候我们想把比较重要的功能的日志单独写到一个日志文件方便排查,NLog提供了单独打日志文件的功能

修改配置文件,用一个属性接收,属性由程序端传来:${event-properties:filename}

<?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="NLog\all_log.log">

<targets>

<!--文件日志,archive相关参数:文件拆分,每100M拆分一个新文件-->

<target xsi:type="File"

name="all_log"

fileName="NLog\{shortdate}\\{event-properties:filename}${shortdate}.log"

layout="{longdate}\|{logger}|{uppercase:{level}}|${message} ${exception}"

archiveFileName="NLog\{shortdate}\\{event-properties:filename}${shortdate}.{####}.log"

archiveNumbering="Rolling"

archiveAboveSize="10485760"

concurrentwrites="true"

maxArchiveFiles="100"

/>

</targets>

<rules>

<!-- add your logging rules here -->

<!--路由顺序会对日志打印产生影响。路由匹配逻辑为顺序匹配。-->

<!--Skip Microsoft logs and so log only own logs-->

<!--以Microsoft打头的日志将进入此路由,由于此路由没有writeTo属性,所有会被忽略-->

<!--且此路由设置了final,所以当此路由被匹配到时。不会再匹配此路由下面的路由。未匹配到此路由时才会继续匹配下一个路由-->

<logger name="Microsoft.*" minlevel="Trace" final="true" />

<logger name="*" minlevel="Trace" writeTo="all_log" />

</rules>

</nlog>

封装一个LogHelper.cs

public class LogHelper

{

private static Logger logger= LogManager.GetCurrentClassLogger();

public static void Info(string message,string fileName="INFO")

{

//把文件名通过属性传输

logger.WithProperty("filename", fileName).Info(message);

}

public static void Debug(string message, string fileName = "DEBUG")

{

logger.WithProperty("filename", fileName).Debug(message);

}

public static void Error(string message, string fileName = "Error")

{

logger.WithProperty("filename", fileName).Error(message);

}

public static void Warn(string message, string fileName = "Warn")

{

logger.WithProperty("filename", fileName).Warn(message);

}

}

程序调用:

效果:

4.NLog写入数据库

这里以Mysql为例

引入Nuget包

复制代码
MySql.Data

sql表脚本还是上面Log4net一样。

配置

<?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="NLog\all_log.log">

<targets>

<!--文件日志,archive相关参数:文件拆分,每100M拆分一个新文件-->

<target xsi:type="File"

name="all_log"

fileName="NLog\{shortdate}\\{event-properties:filename}${shortdate}.log"

layout="{longdate}\|{logger}|{uppercase:{level}}|${message} ${exception}"

archiveFileName="NLog\{shortdate}\\{event-properties:filename}${shortdate}.{####}.log"

archiveNumbering="Rolling"

archiveAboveSize="10485760"

concurrentwrites="true"

maxArchiveFiles="100"

/>

<target name="mysql_log" xsi:type="Database"

dbProvider="MySql.Data.MySqlClient.MySqlConnection, MySql.Data"

connectionString="server=127.0.0.1;database=test_db;user=root;pwd=123456;SslMode=none"

commandText="INSERT INTO logs(app_name,log_date, thread, `level`, logger, message, `exception`)VALUES(@app_name,@log_date, @thread,@log_level, @logger, @message, @exception);">

<parameter name="@app_name" layout="AspNetCoreNlog" />

<parameter name="@log_date" layout="${date}" />

<parameter name="@thread" layout="${threadid}" />

<parameter name="@log_level" layout="${level}" />

<parameter name="@logger" layout="${logger}" />

<parameter name="@message" layout="${message}" />

<parameter name="@exception" layout="${exception:tostring}" />

</target>

</targets>

<rules>

<!-- add your logging rules here -->

<!--路由顺序会对日志打印产生影响。路由匹配逻辑为顺序匹配。-->

<!--Skip Microsoft logs and so log only own logs-->

<!--以Microsoft打头的日志将进入此路由,由于此路由没有writeTo属性,所有会被忽略-->

<!--且此路由设置了final,所以当此路由被匹配到时。不会再匹配此路由下面的路由。未匹配到此路由时才会继续匹配下一个路由-->

<logger name="Microsoft.*" minlevel="Trace" final="true" />

<logger name="*" minlevel="Trace" writeTo="all_log" />

<logger name="*" minlevel="Trace" writeTo="mysql_log" />

</rules>

</nlog>

效果:

如果写SqlServer

引入Nuget包

复制代码
System.Data.SqlClient
复制代码
dbProvider="System.Data.SqlClient.SqlConnection, System.Data.SqlClient"
connectionString改为SqlServer的连接字符串即可

5.Log4Net对比NLog

Log4Net对比NLog来说性能相差无几

但是个人推荐用NLog,原因有

1.配置简单

2.可以很方便的自定义日志文件名,这个对于核心模块单独打日志太方便了。

参考文章:.Net Core(.NET6)中接入Log4net和NLog进行日志记录 - 包子wxl - 博客园

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。

相关推荐
csdn_aspnet13 小时前
.Net 6.0 .Net7.0 .Net8.0 .Net9.0 使用 Serilog 按日志等级写入日志及 appsetting.json 配置方式实现
.net6.0·serilog·.net9.0
小乖兽技术21 天前
快速了解开源日志框架log4net:灵活记录应用程序日志信息的利器
开源·.net·log4net
csdn_aspnet22 天前
使用 .NET 6 或 .NET 8 上传大文件
.net6.0·.net8.0
csdn_aspnet1 个月前
在.NET 6中使用Serilog收集日志
webapi·.net6.0
秋雨雁南飞2 个月前
LogViewer NLog, Log4Net, Log4j 文本日志可视化
log4j·nlog·logview
letmebaby7 个月前
Log4Net配置详解及输出自定义消息类示例
log4net
martian6657 个月前
基于C#、Visual Studio 2017以及.NET Framework 4.5的Log4Net使用教程
c#·log4net·visual studio
yangshuquan7 个月前
分享一个 .NET Core Console 项目中应用 NLog 写日志的详细例子
c#·.netcore·日志·nlog
Mudrock__8 个月前
.NET_NLog
.net·nlog