.Net Core(.NET6)中接入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进行日志记录的更多相关文章
- Asp.Net Core 2.0 项目实战(9) 日志记录,基于Nlog或Microsoft.Extensions.Logging的实现及调用实例
本文目录 1. Net下日志记录 2. NLog的使用 2.1 添加nuget引用NLog.Web.AspNetCore 2.2 配置文件设置 2.3 依赖配置及调用 ...
- [转]asp.net5中使用NLog进行日志记录
本文转自:http://www.cnblogs.com/sguozeng/articles/4861303.html asp.net5中使用NLog进行日志记录 asp.net5中提供了性能强大的日志 ...
- asp.net5中使用NLog进行日志记录
asp.net5中提供了性能强大的日志框架,本身也提供了几种日志记录方法,比如记录到控制台或者事件中等,但是,对大部分程序员来说,更喜欢使用类似log4net或者Nlog这种日志记录方式,灵活而强大. ...
- EF Core使用SQL调用返回其他类型的查询 ASP.NET Core 2.0 使用NLog实现日志记录 CSS 3D transforms cSharp:use Activator.CreateInstance with an Interface? SqlHelper DBHelper C# Thread.Abort方法真的让线程停止了吗? 注意!你的Thread.Abort方法真
EF Core使用SQL调用返回其他类型的查询 假设你想要 SQL 本身编写,而不使用 LINQ. 需要运行 SQL 查询中返回实体对象之外的内容. 在 EF Core 中,执行该操作的另一种方法 ...
- ASP.NET Core 集成测试中通过 Serilog 向控制台输出日志
日志是程序员的雷达,不仅在生产环境中需要,在集成测试环境中也需要,可以在持续集成失败后帮助定位问题.与生产环境不同,在集成测试环境中使用控制台输出日志更方便,这样可以通过持续集成 runner 执行 ...
- 转:使用log4net完成程序异常日志记录(使用SQLite数据库记录和普通文本记录)
http://www.cnblogs.com/kyo-yo/archive/2010/06/11/use-log4net-to-log-exception.html 在前端时间开发的时候由于需要将异常 ...
- log4net.NoSql +ElasticSearch 实现日志记录
前言: 前两天在查找如何扩展log4net的日志格式时找到一个开源项目Log4net.NoSql,它通过扩展Appender实现了把日志输出到ElasticSearch里面.顺藤摸瓜,发现涉及的项目还 ...
- .NET Core(.NET6)中gRPC使用
一.简介 简单解析一下gRPC,gRPC 是一个由Google开源的,跨语言的,高性能的远程过程调用(RPC)框架. 特点: 跨语言 内容protobuf格式(比json体积小),网络传输快 使用HT ...
- Asp.Net Core WebApi中接入Swagger组件(初级)
开发WebApi时通常需要为调用我们Api的客户端提供说明文档.Swagger便是为此而存在的,能够提供在线调用.调试的功能和API文档界面. 环境介绍:Asp.Net Core WebApi + S ...
随机推荐
- js 利用||和&&赋值小技巧
感谢原文作者:nayi_224 原文链接:https://blog.csdn.net/nayi_224/article/details/80437329 对于需要返回boolean类型数值的地方,比如 ...
- C语言system函数
我们今天来看看在windows操作系统下system () 函数详解(主要是在C语言中的应用) 注意:在windows下的system函数中命令可以不区别大小写! 函数名: system 功 能: 发 ...
- attachEvent
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- _call妙用
class Magic { function __call($name,$arguments) { if($name=='foo') { if(is_int($arguments[0])) $this ...
- 日期类 Date
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; impor ...
- k8s补充
k8s补充 容器云发展及主要内容 1.云计算,交付标准(iaas--openstack) 国内:阿里云一华为云(振兴杯)百度云(私有云) 国外:AWS 2.平台即服务(PAAS) 例如:新浪云(号称免 ...
- Java中eq、ne、ge、gt、le、lt的含义
Java中eq.ne.ge.gt.le.lt 关系运算符包括EQ.NE.GE.GT.LE.LT几个,关系运算符返回的是真"True"或假"False". eq( ...
- HTTP状态码100、200、300、400、500、600的含义
1xx (临时响应)表示临时响应并需要请求者继续执行操作的状态代码. 100 (继续) 请求者应当继续提出请求. 服务器返回此代码表示已收到请求的第一部分,正在等待其余部分. 101 (切换协议) 请 ...
- SpringMVC 解析(三) Controller 注解
我在前面的文章中介绍了Spring MVC最核心的组件DispatcherServlet,DispatcherServlet把Servlet容器(如Tomcat)中的请求和Spring中的组件联系到一 ...
- 前端框架 bootstrap 的使用
内容概要 前端框架 bootstrap 简介 引入方式 布局容器 栅格系统 图标 内容详细 简介 网址:https://v3.bootcss.com/ 版本: 2.X 3.X 4.X 推荐使用3.X版 ...