惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Microsoft Azure Blog
Microsoft Azure Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Webroot Blog
Webroot Blog
腾讯CDC
The Last Watchdog
The Last Watchdog
博客园 - 司徒正美
H
Hacker News: Front Page
I
InfoQ
A
Arctic Wolf
H
Hackread – Cybersecurity News, Data Breaches, AI and More
H
Heimdal Security Blog
L
LINUX DO - 最新话题
T
Threat Research - Cisco Blogs
宝玉的分享
宝玉的分享
Last Week in AI
Last Week in AI
Security Latest
Security Latest
D
DataBreaches.Net
C
Check Point Blog
J
Java Code Geeks
www.infosecurity-magazine.com
www.infosecurity-magazine.com
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Attack and Defense Labs
Attack and Defense Labs
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
L
Lohrmann on Cybersecurity
雷峰网
雷峰网
Vercel News
Vercel News
WordPress大学
WordPress大学
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Spread Privacy
Spread Privacy
Forbes - Security
Forbes - Security
阮一峰的网络日志
阮一峰的网络日志
Hacker News: Ask HN
Hacker News: Ask HN
大猫的无限游戏
大猫的无限游戏
I
Intezer
N
News and Events Feed by Topic
小众软件
小众软件
B
Blog RSS Feed
Help Net Security
Help Net Security
Google DeepMind News
Google DeepMind News
Apple Machine Learning Research
Apple Machine Learning Research
博客园 - 三生石上(FineUI控件)
S
Security @ Cisco Blogs
美团技术团队
Recent Announcements
Recent Announcements
Martin Fowler
Martin Fowler
Engineering at Meta
Engineering at Meta
The GitHub Blog
The GitHub Blog
MyScale Blog
MyScale Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main

博客园 - 大西瓜3721

SVN分支/合并原理及最佳实践 Web.Config中Runtime节点-DLL版本冲突问题 工作问题 Vue资料 轻松实现WCF服务的构造函数依赖注入 WCF 依赖注入-- Attribute MVC视图分析 C#简单枚举和标志枚举的用法和区别 XDate Admin.NET框架资料 关于NopCommerce3.6版用户登录详解 AutoFac注册的动态实例 Named和Keyed NOP源码分析 六 NOP源码分析五---set的存储 NOP源码分析四 Nop源码分析三 NOP源码分析 二 NOP源码分析 一 NopCommerce的资料 IServiceCollection和IServiceProvider 控制反转——Autofac框架 精选10款C#/.NET开发必备类库 11个免费开源后台管理系统模板 H5连接蓝牙打印机打印小票 自定义控件 - 流式布局:TagFlowLayout MVC开源CMS nginx的安装&一个最简单的配置(windows和Centos) DNS解析
日志管理之log4net+Autofac
大西瓜3721 · 2026-03-31 · via 博客园 - 大西瓜3721

一、前言

在项目开发的过程中,日志是必不可少的一部分,可以帮我们定位异常,分析错误原因等功能,log4net是.Net下一个非常优秀的开源日志记录组件。log4net记录日志的功能非常强大。它可以将日志分不同的等级,以不同的格式,输出到不同的媒介。本文主要是介绍在前几篇已经创建好的项目里加上日志处理机制

二、安装并使用log4net

1.使用nuget安装log4net

2.log4net的用法类似下面的代码:

        [Route("log4")]
        [HttpGet]
        public IHttpActionResult Log()
        {
            // 通过LogManager的静态方法GetLogger生成一个Ilog对象
            ILog log = LogManager.GetLogger(typeof(IndexController)); // 下面是日志处理
            log.Debug("测试debug", new Exception("debug异常"));
            log.Info("测试Info", new Exception("Info异常"));
            log.Warn("测试Warn", new Exception("Warn异常"));
            log.Error("测试Error", new Exception("Error异常"));
            log.Fatal("测试Fatal", new Exception("Fatal异常"));
            return Ok("已经写入日志");

        }

3.运行项目,浏览器调用请求

三、通过autofac解耦Ilog对象

1.我们用autofac的Module方式去注册log4net组件,项目AutoFac目录下新建Module文件夹,并新建LoggingModule类

 public class LoggingModule : Autofac.Module
    {
        private static void InjectLoggerProperties(object instance)
        {
            var instanceType = instance.GetType();

            // Get all the injectable properties to set.
            // If you wanted to ensure the properties were only UNSET properties,
            // here's where you'd do it.
            var properties = instanceType
              .GetProperties(BindingFlags.Public | BindingFlags.Instance)
              .Where(p => p.PropertyType == typeof(ILog) && p.CanWrite && p.GetIndexParameters().Length == 0);

            // Set the properties located.
            foreach (var propToSet in properties)
            {
                propToSet.SetValue(instance, LogManager.GetLogger(instanceType), null);
            }
        }

        private static void OnComponentPreparing(object sender, PreparingEventArgs e)
        {
            e.Parameters = e.Parameters.Union(
              new[]
              {
        new ResolvedParameter(
            (p, i) => p.ParameterType == typeof(ILog),
            (p, i) => LogManager.GetLogger(p.Member.DeclaringType)
        ),
              });
        }

        protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration)
        {
            registration.Preparing += OnComponentPreparing;

            // Handle properties.
            registration.Activated += (sender, e) => InjectLoggerProperties(e.Instance);
        }
    }

这段代码为autofac官网里提供的,参考地址:http://autofaccn.readthedocs.io/en/latest/examples/log4net.html?highlight=module

 2.ContainerBuilerCommon下注册module

 public static IContainer GetWebApiContainer()
        {
            var builder = new ContainerBuilder();
            // 注册webapi的所有控制器
            builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
            // 注册一个用于测试的组件。
            builder.RegisterType<Person>();
            //注册日志组件
            builder.RegisterModule<LoggingModule>();
            return builder.Build();
        }

3.控制器通过构造函数注入Ilog

        private ILog _log;
        public IndexController(ILog log, Person person)
        {
            _person = person;
            _log = log;
        }

4.新建get请求

        [Route("autolog4")]
        [HttpGet]
        public IHttpActionResult AutoLog()
        {
            // 通过LogManager的静态方法GetLogger生成一个Ilog对象
            _log.Debug("测试debug", new Exception("debug异常"));
            _log.Info("测试Info", new Exception("Info异常"));
            _log.Warn("测试Warn", new Exception("Warn异常"));
            _log.Error("测试Error", new Exception("Error异常"));
            _log.Fatal("测试Fatal", new Exception("Fatal异常"));
            return Ok("已经写入日志");

        }

5.现在编译程序后用postman工具的get方法访问接口:http://localhost:xxx/api/autolog4,程序是运行正常的 。但现在日志即没有写入到某个文件、数据库或是发送到邮件里,也没有输出到控制台上。这就是log4net的设计的好处,在程序里你只管做日志的处理,如调用ILog的Debug()、Info()、Warn()、Error()、Fatal(),至于日志是由什么机制去处理(如写入文件,写入数据库等)是由另一个流程来控制,即log4net的配置文件。如果程序里没有log4net的配置文件,程序也能正常运行。

四、配置Log4net

1.新建Log4net.config,代码如下

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
    </configSections>

    <system.web>
        <compilation debug="true" targetFramework="4.5.2" />
        <httpRuntime targetFramework="4.5.2" />
    </system.web>
<log4net>
    <!--错误日志:::记录错误日志-->
    <!--按日期分割日志文件 一天一个-->
    <!-- appender 定义日志输出方式   将日志以回滚文件的形式写到文件中。-->
    <appender name="ErrorAppender" type="log4net.Appender.RollingFileAppender">
        <!--保存路径:下面路径项目启动的时候自动在C盘中创建log、logError文件-->
        <file value="log/error/error_" />
        <!-- 如果想在本项目中添加路径,那就直接去掉C:\\  只设置log\\LogError   项目启动中默认创建文件 -->
        <appendToFile value="true"/>
        <!--按照何种方式产生多个日志文件(日期[Date],文件大小[Size],混合[Composite])-->
        <rollingStyle value="Date"/>
        <!--这是按日期产生文件夹-->
        <datePattern value="yyyy-MM-dd'.log'"/>
        <!--是否只写到一个文件中-->
        <staticLogFileName value="false"/>
        <!--保留的log文件数量 超过此数量后 自动删除之前的   好像只有在 按Size分割时有效 设定值value="-1"为不限文件数-->
        <param name="MaxSizeRollBackups" value="100"/>
        <!--每个文件的大小。只在混合方式与文件大小方式下使用。超出大小后在所有文件名后自动增加正整数重新命名,数字最大的最早写入。可用的单位:KB|MB|GB。不要使用小数,否则会一直写入当前日志-->
        <maximumFileSize value="50M" />
        <!-- layout 控制Appender的输出格式,也可以是xml  一个Appender只能是一个layout-->
        <layout type="log4net.Layout.PatternLayout">
            <!--每条日志末尾的文字说明-->
            <!--输出格式 模板-->
            <!-- <param name="ConversionPattern"  value="记录时间:%date 线程ID:[%thread] 日志级别:%-5level 记录类:%logger   
        操作者ID:%property{Operator} 操作类型:%property{Action}%n  当前机器名:%property%n当前机器名及登录用户:%username %n  
        记录位置:%location%n 消息描述:%property{Message}%n   异常:%exception%n 消息:%message%newline%n%n" />-->

            <!--样例:2008-03-26 13:42:32,111 [10] INFO  Log4NetDemo.MainClass [(null)] - info-->
            <!--<conversionPattern value="%newline %n记录时间:%date %n线程ID:[%thread] %n日志级别: %-5level %n错误描述:%message%newline %n"/>-->
            <conversionPattern value="%n==========
                                  %n【日志级别】%-5level
                                  %n【记录时间】%date
                                  %n【执行时间】[%r]毫秒
                                  %n【出错文件】%F
                                  %n【出错行号】%L
                                  %n【出错的类】%logger 属性[%property{NDC}]
                                  %n【错误描述】%message
                                  %n【错误详情】%newline"/>
        </layout>
        <filter type="log4net.Filter.LevelRangeFilter,log4net">
            <levelMin value="ERROR" />
            <levelMax value="FATAL" />
        </filter>
    </appender>

    <!--DEBUG:::记录DEBUG日志-->
    <!--按日期分割日志文件 一天一个-->
    <!-- appender 定义日志输出方式   将日志以回滚文件的形式写到文件中。-->
    <appender name="DebugAppender" type="log4net.Appender.RollingFileAppender">
        <!--保存路径:下面路径项目启动的时候自动在C盘中创建log、logError文件-->
        <file value="log/debug/debug_" />
        <!-- 如果想在本项目中添加路径,那就直接去掉C:\\  只设置log\\LogError   项目启动中默认创建文件 -->
        <appendToFile value="true"/>
        <!--按照何种方式产生多个日志文件(日期[Date],文件大小[Size],混合[Composite])-->
        <rollingStyle value="Date"/>
        <!--这是按日期产生文件夹-->
        <datePattern value="yyyy-MM-dd'.log'"/>
        <!--是否只写到一个文件中-->
        <staticLogFileName value="false"/>
        <!--保留的log文件数量 超过此数量后 自动删除之前的   好像只有在 按Size分割时有效 设定值value="-1"为不限文件数-->
        <param name="MaxSizeRollBackups" value="100"/>
        <!--每个文件的大小。只在混合方式与文件大小方式下使用。超出大小后在所有文件名后自动增加正整数重新命名,数字最大的最早写入。可用的单位:KB|MB|GB。不要使用小数,否则会一直写入当前日志-->
        <maximumFileSize value="50M" />
        <!-- layout 控制Appender的输出格式,也可以是xml  一个Appender只能是一个layout-->
        <layout type="log4net.Layout.PatternLayout">
            <!--每条日志末尾的文字说明-->
            <!--输出格式 模板-->
            <!-- <param name="ConversionPattern"  value="记录时间:%date 线程ID:[%thread] 日志级别:%-5level 记录类:%logger   
        操作者ID:%property{Operator} 操作类型:%property{Action}%n  当前机器名:%property%n当前机器名及登录用户:%username %n  
        记录位置:%location%n 消息描述:%property{Message}%n   异常:%exception%n 消息:%message%newline%n%n" />-->

            <!--样例:2008-03-26 13:42:32,111 [10] INFO  Log4NetDemo.MainClass [(null)] - info-->
            <!--<conversionPattern value="%newline %n记录时间:%date %n线程ID:[%thread] %n日志级别: %-5level %n错误描述:%message%newline %n"/>-->
            <conversionPattern value="%n==========
                                  %n【日志级别】%-2level
                                  %n【记录时间】%date
                                  %n【执行时间】[%r]毫秒
                                  %n【debug文件】%F
                                  %n【debug行号】%L
                                  %n【debug类】%logger 属性[%property{NDC}]
                                  %n【debug描述】%message"/>
        </layout>
        <filter type="log4net.Filter.LevelRangeFilter,log4net">
            <levelMin value="DEBUG" />
            <levelMax value="WARN" />
        </filter>
    </appender>
    <!--Set root logger level to DEBUG and its only appender to A1-->
    <root>
        <!--控制级别,由低到高: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF-->
        <level value="ALL" />
        <appender-ref ref="DebugAppender" />
        <appender-ref ref="ErrorAppender" />
    </root>
</log4net>
</configuration>

2.properties下的AssemblyInfo.cs文件里添加以下代码:

[assembly: XmlConfigurator(Watch = true, ConfigFile = "Log4Net.config")]

3.运行程序,调用日志请求,log4net会在项目主目录下的log文件夹生成日志文件

 

DEBUG日志:

 

ERROR日志: