Asp.Net Core中简单使用日志组件log4net
本文将简单介绍在.NET 6中使用log4net的方法,具体见下文范例。
1.首先新建一个ASP.NET Core空项目

2.通过Nuget包管理器安装下面两个包
log4net
Microsoft.Extensions.Logging.Log4Net.AspNetCore

3.在项目根目录下新建log4net的配置文件log4net.config,并将其设置为始终复制。
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
<!--根配置-->
<root>
<!--日志级别:可选值: ERROR > WARN > INFO > DEBUG -->
<level value="ERROR"/>
<level value="WARN"/>
<level value="INFO"/>
<level value="DEBUG"/>
<appender-ref ref="ErrorLog" />
<appender-ref ref="WarnLog" />
<appender-ref ref="InfoLog" />
<appender-ref ref="DebugLog" />
</root>
<!-- 错误 Error.log-->
<appender name="ErrorLog" type="log4net.Appender.RollingFileAppender">
<!--目录路径,可以是相对路径或绝对路径-->
<param name="File" value="C:\logs\"/>
<!--文件名,按日期生成文件夹-->
<param name="DatePattern" value="/yyyy-MM-dd/"Error.log""/>
<!--追加到文件-->
<appendToFile value="true"/>
<!--创建日志文件的方式,可选值:Date[日期],文件大小[Size],混合[Composite]-->
<rollingStyle value="Composite"/>
<!--写到一个文件-->
<staticLogFileName value="false"/>
<!--单个文件大小。单位:KB|MB|GB-->
<maximumFileSize value="200MB"/>
<!--最多保留的文件数,设为"-1"则不限-->
<maxSizeRollBackups value="-1"/>
<!--日志格式-->
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="[%d{HH:mm:ss}]%m%n"/>
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<param name="LevelMin" value="ERROR" />
<param name="LevelMax" value="ERROR" />
</filter>
</appender> <!-- 警告 Warn.log-->
<appender name="WarnLog" type="log4net.Appender.RollingFileAppender">
<!--目录路径,可以是相对路径或绝对路径-->
<param name="File" value="C:\logs\"/>
<!--文件名,按日期生成文件夹-->
<param name="DatePattern" value="/yyyy-MM-dd/"Warn.log""/>
<!--追加到文件-->
<appendToFile value="true"/>
<!--创建日志文件的方式,可选值:Date[日期],文件大小[Size],混合[Composite]-->
<rollingStyle value="Composite"/>
<!--写到一个文件-->
<staticLogFileName value="false"/>
<!--单个文件大小。单位:KB|MB|GB-->
<maximumFileSize value="200MB"/>
<!--最多保留的文件数,设为"-1"则不限-->
<maxSizeRollBackups value="-1"/>
<!--日志格式-->
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="[%d{HH:mm:ss}]%m%n"/>
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<param name="LevelMin" value="WARN" />
<param name="LevelMax" value="WARN" />
</filter>
</appender> <!-- 信息 Info.log-->
<appender name="InfoLog" type="log4net.Appender.RollingFileAppender">
<!--目录路径,可以是相对路径或绝对路径-->
<param name="File" value="C:\logs\"/>
<!--文件名,按日期生成文件夹-->
<param name="DatePattern" value="/yyyy-MM-dd/"Info.log""/>
<!--追加到文件-->
<appendToFile value="true"/>
<!--创建日志文件的方式,可选值:Date[日期],文件大小[Size],混合[Composite]-->
<rollingStyle value="Composite"/>
<!--写到一个文件-->
<staticLogFileName value="false"/>
<!--单个文件大小。单位:KB|MB|GB-->
<maximumFileSize value="200MB"/>
<!--最多保留的文件数,设为"-1"则不限-->
<maxSizeRollBackups value="-1"/>
<!--日志格式-->
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="[%d{HH:mm:ss}]%m%n"/>
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<param name="LevelMin" value="INFO" />
<param name="LevelMax" value="INFO" />
</filter>
</appender> <!-- 调试 Debug.log-->
<appender name="DebugLog" type="log4net.Appender.RollingFileAppender">
<!--目录路径,可以是相对路径或绝对路径-->
<param name="File" value="C:\logs\"/>
<!--文件名,按日期生成文件夹-->
<param name="DatePattern" value="/yyyy-MM-dd/"Debug.log""/>
<!--追加到文件-->
<appendToFile value="true"/>
<!--创建日志文件的方式,可选值:Date[日期],文件大小[Size],混合[Composite]-->
<rollingStyle value="Composite"/>
<!--写到一个文件-->
<staticLogFileName value="false"/>
<!--单个文件大小。单位:KB|MB|GB-->
<maximumFileSize value="200MB"/>
<!--最多保留的文件数,设为"-1"则不限-->
<maxSizeRollBackups value="-1"/>
<!--日志格式-->
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="[%d{HH:mm:ss}]%m%n"/>
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<param name="LevelMin" value="DEBUG" />
<param name="LevelMax" value="DEBUG" />
</filter>
</appender> </log4net>
log4net配置参数此处不多赘述,只针对日志的输出格式参数conversionPattern配置做简要说明。
%p(priority)::日志的当前优先级别(DEBUG、INFO、WARN 等)
%t(thread id):当前记录器所在的线程 ID
%d(datetime):当前记录器运行时的时刻
%F(file):当前记录器所在的文件名
%L(line):当前记录器所在的行号
%m(message):需要输出的日志消息
%n(new line):换行
%M 方法名
%m 输出代码中指定的消息
%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
%r 输出自应用启动到输出该log信息耗费的毫秒数
%c 输出所属的类目,通常就是所在类的全名
%t 输出产生该日志事件的线程名
%n 输出一个回车换行符,Windows平台为“rn”,Unix平台为“n”
%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 :10:28,921
%l 或 %L 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。
%c 输出日志信息所属的类的全名
%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy-MM-dd HH:mm:ss },输出类似:2002-10-18- 22:10:28
%f 输出日志信息所属的类的类名
%l 输出日志事件的发生位置,即输出日志信息的语句处于它所在的类的第几行
%m 输出代码中指定的信息,如log(message)中的message
%n 输出一个回车换行符,Windows平台为“rn”,Unix平台为“n”
%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL。如果是调用debug()输出的,则为DEBUG,依此类推
%r 输出自应用启动到输出该日志信息所耗费的毫秒数
%t 输出产生该日志事件的线程名
4.在Program中使用log4net输出自定义日志内容
using log4net; var builder = WebApplication.CreateBuilder(args);
//注入Log4Net
builder.Services.AddLogging(cfg =>
{
cfg.AddLog4Net();
//默认的配置文件路径是在根目录,且文件名为log4net.config
//如果文件路径或名称有变化,需要重新设置其路径或名称
//比如在项目根目录下创建一个名为cfg的文件夹,将log4net.config文件移入其中,并改名为log.config
//则需要使用下面的代码来进行配置
//cfg.AddLog4Net(new Log4NetProviderOptions()
//{
// Log4NetConfigFileName = "cfg/log.config",
// Watch = true
//});
});
var app = builder.Build();
//访问根页面时
app.MapGet("/", (ILogger<Program> logger) =>
{
logger.LogInformation("logger:测试一下Log4Net=》Info");
return "Hello World!";
});
//访问test页面时
app.MapGet("/test", () =>
{
var log = LogManager.GetLogger(typeof(Program));
log.Info("log:这是一条普通日志信息");
});
app.Run();
5.将项目运行起来,即可发现日志文件已生成


6.扩展使用:使用简单工厂模式IOC注入到自定义类中使用
新建一个ITestLog4Net接口文件,并为其定义一个Log方法。
public interface ITestLog4Net
{
public void Log();
}
并且新建一个TestLog4Net的自定义类,继承于ITestLog4Net,并实现该Log方法。
public class TestLog4Net : ITestLog4Net
{
private readonly ILogger<TestLog4Net> _logger;
public TestLog4Net(ILogger<TestLog4Net> logger)
{
_logger = logger;
_logger.LogInformation("ctor测试一下Log4Net=》Info");
} public void Log()
{
_logger.LogInformation("测试一下Log4Net=》Info");
}
}
在Program中注入我们的自定义类TestLog4Net
builder.Services.AddTransient<ITestLog4Net, TestLog4Net>();
testLog4Net.Log();
使用方法
var testLog4Net = app.Services.GetService<ITestLog4Net>()!;
或者
var services = new ServiceCollection()!;
var provider = services.BuildServiceProvider()!;
var testLog4Net = provider.GetService<ITestLog4Net>()!;
testLog4Net.Log();
其中,使用下面这种写法,将会收到一个编译警告信息。
warning ASP0000: Calling 'BuildServiceProvider' from application code results in an additional copy of singleton services being created. Consider alternatives such as dependency injecting services as parameters to 'Configure'.

推荐使用上面的写法,百度之后,得到的答案是:不要通过调用BuildServiceProvider(). 这个方法应该只被 Host 调用一次。重复的服务提供者可能会导致一些意想不到的错误。如果有哪位大佬知道具体原因,请告知一下,谢谢!
Tips:代码中的感叹号!表示该对象不会为空,一定要确保该对象不会为空才能这样写,这是C#10中的新特性。
Asp.Net Core中简单使用日志组件log4net的更多相关文章
- [.Net Core] 在 Mvc 中简单使用日志组件
在 Mvc 中简单使用日志组件 基于 .Net Core 2.0,本文只是蜻蜓点水,并非深入浅出. 目录 使用内置的日志组件 简单过渡到第三方组件 - NLog 使用内置的日志 下面使用控制器 Hom ...
- asp.net core 3 使用nlog日志组件,使用$ {basedir}保存位置不对,记录下怎么解决
$ {basedir}指向的是 AppDomain.CurrentDomain.BaseDirectory, Asp.Net.Core的解决方法可能如下(在Program.cs中添加两行): var ...
- Asp.Net Core中利用Seq组件展示结构化日志功能
在一次.Net Core小项目的开发中,掌握的不够深入,对日志记录并没有好好利用,以至于一出现异常问题,都得跑动服务器上查看,那时一度怀疑自己肯定没学好,不然这一块日志不可能需要自己扒服务器日志来查看 ...
- 如何在ASP.NET Core中自定义Azure Storage File Provider
文章标题:如何在ASP.NET Core中自定义Azure Storage File Provider 作者:Lamond Lu 地址:https://www.cnblogs.com/lwqlun/p ...
- 玩转ASP.NET Core中的日志组件
简介 日志组件,作为程序员使用频率最高的组件,给程序员开发调试程序提供了必要的信息.ASP.NET Core中内置了一个通用日志接口ILogger,并实现了多种内置的日志提供器,例如 Console ...
- ASP.NET Core 中文文档 第三章 原理(8)日志
原文:Logging 作者:Steve Smith 翻译:刘怡(AlexLEWIS) 校对:何镇汐.许登洋(Seay) ASP.NET Core 内建支持日志,也允许开发人员轻松切换为他们想用的其他日 ...
- ASP.Net Core 中使用Zookeeper搭建分布式环境中的配置中心系列一:使用Zookeeper.Net组件演示基本的操作
前言:马上要过年了,祝大家新年快乐!在过年回家前分享一篇关于Zookeeper的文章,我们都知道现在微服务盛行,大数据.分布式系统中经常会使用到Zookeeper,它是微服务.分布式系统中必不可少的分 ...
- 如何简单的在 ASP.NET Core 中集成 JWT 认证?
前情提要:ASP.NET Core 使用 JWT 搭建分布式无状态身份验证系统 文章超长预警(1万字以上),不想看全部实现过程的同学可以直接跳转到末尾查看成果或者一键安装相关的 nuget 包 自上一 ...
- (14)ASP.NET Core 中的日志记录
1.前言 ASP.NET Core支持适用于各种内置和第三方日志记录提供应用程序的日志记录API.本文介绍了如何将日志记录API与内置提供应用程序一起使用. 2.添加日志提供程序 日志记录提供应用程序 ...
随机推荐
- 测试rac数据文件建本地及处理
模拟用户zytuser的表空间ZYTUSER_TBS表空间添加数据文件到本地.--环境准备1.创建一个表空间--创建表空间create tablespace ZYTUSER_TBS datafile ...
- docker之swarm容器部署及运维
1.概念 Docker Swarm 是 Docker 的集群管理工具.它将 Docker 主机池转变为单个虚拟 Docker 主机. Docker Swarm 提供了标准的 Docker API,所有 ...
- DRF的action装饰器
1.action装饰器 Django默认的路由分发规则决定了视图函数只能以get.post等请求方式命名,如果想要使用自定义的方式命名,我们可以使用action去映射请求方法名与自定义方法 view. ...
- 一文弄懂CGAffineTransform和CTM
一文弄懂CGAffineTransform和CTM 一些概念 坐标空间(系):视图(View)坐标空间与绘制(draw)坐标空间 CTM:全称current transformation matrix ...
- Python技法3:匿名函数、回调函数和高阶函数
1.定义匿名或内联函数 如果我们想提供一个短小的回调函数供sort()这样的函数用,但不想用def这样的语句编写一个单行的函数,我们可以借助lambda表达式来编写"内联"式的函数 ...
- 对epoll机制的学习理解v1
epoll机制 wrk用非阻塞多路复用IO技术创造出大量的连接,从而达到很好的压力测试效果.epoll就是实现IO多路复用的关键. 本节是对epoll的本质的学习总结,进一步的参考资料为: <深 ...
- 【UE4 设计模式】装饰器模式 Decorator Pattern
概述 描述 动态地给一个对象增加一些额外的职责(Responsibility),就增加对象功能来说,装饰模式比生成子类实现更为灵活.是一种对象结构型模式. 套路 抽象构件(Component) 具体构 ...
- Noip模拟62 2021.9.26
T1 Set 真就随机化拿了$90$?? 不过还是有依据的,毕竟这道题出解的几率很大,随出答案的概率也极大 所以不妨打一个随机化 1 #include<bits/stdc++.h> 2 # ...
- 零基础入门c语言函数之递归函数
今天来总结一下关于递归函数的使用方面的问题. 递归函数就是在函数使用的时候自己调用自己,层层调用,来实现你想要的功能. 有两个最常用的例子,我们来写一下. (1)计算阶乘 #include int f ...
- 字符串与模式匹配算法(五):BMH算法
一.BMH算法介绍 在BM算法的实际应用中,坏字符偏移函数的应用次数要远远超过好后缀偏移函数的应用次数,坏字符偏移函数在匹配过程中起着移动指针的主导作用.在实际匹配过程,只是用坏字符偏移函数也非常有效 ...