【后端】.NET Core API框架搭建(9) --配置使用Log4Net日志

目录

1.添加包

2.新建公用类

3.新建配置

4.注册

4.1.类库项目设置

5.使用


在 .NET Core 项目中使用 Log4Net 做日志记录,具有很多优势。尽管 .NET Core 自带了 ILogger 接口(如使用内置的 ConsoleLoggerDebugLogger 等),但 Log4Net 提供了更强大、灵活和可配置的日志功能,尤其适合企业级应用或需要精细控制日志输出的场景。

1.添加包

添加 log4net 和 Microsoft.Extensions.Logging.Log4Net.AspNetCore 包。

2.新建公用类

创建 LogHelper 公共静态类。

复制代码
using log4net;
using System.Collections.Concurrent;
using System.Runtime.CompilerServices;

namespace Frame5_LibraryLogger.LogHelper
{
    /// <summary>
    /// 日志类-记录调用名称
    /// </summary>
    public static class LogHelper
    {
        // 缓存 ILog 对象(线程安全)
        private static readonly ConcurrentDictionary<string, ILog> _loggerCache = new ConcurrentDictionary<string, ILog>();

        // 获取 ILog 实例(确保只初始化一次)
        private static ILog GetLogger([CallerMemberName] string caller = "")
        {
            return _loggerCache.GetOrAdd(caller, LogManager.GetLogger);
        }

        /// <summary>
        /// 记录 DEBUG 级别日志
        /// </summary>
        public static void Debug(string message, [CallerMemberName] string caller = "")
        {
            var logger = GetLogger(caller);
            if (logger.IsDebugEnabled)
                logger.Debug(message);
        }

        /// <summary>
        /// 记录 INFO 级别日志
        /// </summary>
        public static void Info(string message, [CallerMemberName] string caller = "")
        {
            var logger = GetLogger(caller);
            if (logger.IsInfoEnabled)
                logger.Info(message);
        }

        /// <summary>
        /// 记录 WARN 级别日志
        /// </summary>
        public static void Warn(string message, [CallerMemberName] string caller = "")
        {
            GetLogger(caller).Warn(message);
        }

        /// <summary>
        /// 记录 ERROR 级别日志
        /// </summary>
        public static void Error(string message, Exception ex = null, [CallerMemberName] string caller = "")
        {
            var logger = GetLogger(caller);
            if (ex != null)
                logger.Error(message, ex);
            else
                logger.Error(message);
        }

        /// <summary>
        /// 记录 FATAL 级别日志
        /// </summary>
        public static void Fatal(string message, Exception ex = null, [CallerMemberName] string caller = "")
        {
            var logger = GetLogger(caller);
            if (ex != null)
                logger.Fatal(message, ex);
            else
                logger.Fatal(message);
        }
    }
}

案例如下

3.新建配置

新建 log4net.config 应用程序配置文件

点击所需项目 → 添加 → 新建项目 → 右上角搜索 应用程序配置文件

复制代码
<?xml version="1.0" encoding="utf-8"?>
<!-- XML文件声明,版本1.0,UTF-8编码 -->
<log4net>
  <!-- 开始log4net配置 -->
  <!-- 关闭所有Microsoft开头的命名空间日志 -->
  <logger name="Microsoft">
    <level value="OFF" />
  </logger>

  <!-- 关闭System开头的命名空间日志 -->
  <logger name="System">
    <level value="OFF" />
  </logger>

  <!-- INFO级别日志配置开始 -->
  <appender name="InfoFileAppender" type="log4net.Appender.RollingFileAppender">
    <!-- 定义一个名为InfoFileAppender的appender,使用滚动文件类型 -->

    <file type="log4net.Util.PatternString" value="logs/INFO/INFO_" />
    <!-- 日志文件路径模板,使用PatternString支持动态路径 -->

    <datePattern value="yyyy-MM-dd'.txt'" />
    <!-- 日期模式,用于文件滚动命名,每天生成一个新文件 -->

    <staticLogFileName value="false" />
    <!-- 不使用静态文件名,允许根据日期模式变化 -->

    <appendToFile value="true" />
    <!-- 以追加模式写入文件,不清空原有内容 -->

    <rollingStyle value="Date" />
    <!-- 滚动策略:按日期滚动 -->

    <layout type="log4net.Layout.PatternLayout">
      <!-- 定义日志输出布局为模式布局 -->

      <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
      <!-- 日志格式:
           %date - 日期时间
           [%thread] - 线程ID
           %-5level - 日志级别(左对齐,5字符宽度)
           %logger - 记录器名称
           %message - 日志消息
           %newline - 换行符
      -->
    </layout>

    <filter type="log4net.Filter.LevelMatchFilter">
      <!-- 添加级别匹配过滤器 -->
      <levelToMatch value="INFO" />
      <!-- 只匹配INFO级别日志 -->
    </filter>

    <filter type="log4net.Filter.DenyAllFilter" />
    <!-- 拒绝所有不匹配的日志 -->
  </appender>

  <!-- DEBUG级别日志配置开始 -->
  <appender name="DebugFileAppender" type="log4net.Appender.RollingFileAppender">
    <!-- 定义DEBUG级别appender -->

    <file type="log4net.Util.PatternString" value="logs/DEBUG/DEBUG_" />
    <!-- DEBUG日志文件路径 -->

    <datePattern value="yyyy-MM-dd'.txt'" />
    <!-- 日期格式 -->

    <staticLogFileName value="false" />
    <!-- 动态文件名 -->

    <appendToFile value="true" />
    <!-- 追加模式 -->

    <rollingStyle value="Date" />
    <!-- 按日期滚动 -->

    <layout type="log4net.Layout.PatternLayout">
      <!-- 布局配置 -->
      <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
      <!-- 同INFO格式 -->
    </layout>

    <filter type="log4net.Filter.LevelMatchFilter">
      <!-- DEBUG级别过滤器 -->
      <levelToMatch value="DEBUG" />
    </filter>

    <filter type="log4net.Filter.DenyAllFilter" />
    <!-- 拒绝其他级别 -->
  </appender>

  <!-- WARN级别日志配置开始 -->
  <appender name="WarnFileAppender" type="log4net.Appender.RollingFileAppender">
    <!-- WARN级别appender定义 -->

    <file type="log4net.Util.PatternString" value="logs/WARN/WARN_" />
    <!-- WARN日志路径 -->

    <datePattern value="yyyy-MM-dd'.txt'" />
    <!-- 日期格式 -->

    <staticLogFileName value="false" />
    <!-- 动态文件名 -->

    <appendToFile value="true" />
    <!-- 追加模式 -->

    <rollingStyle value="Date" />
    <!-- 按日期滚动 -->

    <layout type="log4net.Layout.PatternLayout">
      <!-- 布局配置 -->
      <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
    </layout>

    <filter type="log4net.Filter.LevelMatchFilter">
      <!-- WARN级别过滤器 -->
      <levelToMatch value="WARN" />
    </filter>

    <filter type="log4net.Filter.DenyAllFilter" />
    <!-- 拒绝其他级别 -->
  </appender>

  <!-- ERROR级别日志配置开始 -->
  <appender name="ErrorFileAppender" type="log4net.Appender.RollingFileAppender">
    <!-- ERROR级别appender -->

    <file type="log4net.Util.PatternString" value="logs/ERROR/ERROR_" />
    <!-- ERROR日志路径 -->

    <datePattern value="yyyy-MM-dd'.txt'" />
    <!-- 日期格式 -->

    <staticLogFileName value="false" />
    <!-- 动态文件名 -->

    <appendToFile value="true" />
    <!-- 追加模式 -->

    <rollingStyle value="Date" />
    <!-- 按日期滚动 -->

    <layout type="log4net.Layout.PatternLayout">
      <!-- 布局配置 -->
      <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
    </layout>

    <filter type="log4net.Filter.LevelMatchFilter">
      <!-- ERROR级别过滤器 -->
      <levelToMatch value="ERROR" />
    </filter>

    <filter type="log4net.Filter.DenyAllFilter" />
    <!-- 拒绝其他级别 -->
  </appender>

  <!-- FATAL级别日志配置开始 -->
  <appender name="FatalFileAppender" type="log4net.Appender.RollingFileAppender">
    <!-- FATAL级别appender -->

    <file type="log4net.Util.PatternString" value="logs/FATAL/FATAL_" />
    <!-- FATAL日志路径 -->

    <datePattern value="yyyy-MM-dd'.txt'" />
    <!-- 日期格式 -->

    <staticLogFileName value="false" />
    <!-- 动态文件名 -->

    <appendToFile value="true" />
    <!-- 追加模式 -->

    <rollingStyle value="Date" />
    <!-- 按日期滚动 -->

    <layout type="log4net.Layout.PatternLayout">
      <!-- 布局配置 -->
      <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
    </layout>

    <filter type="log4net.Filter.LevelMatchFilter">
      <!-- FATAL级别过滤器 -->
      <levelToMatch value="FATAL" />
    </filter>

    <filter type="log4net.Filter.DenyAllFilter" />
    <!-- 拒绝其他级别 -->
  </appender>

  <!-- 根记录器配置开始 -->
  <root>
    <!-- 根日志记录器配置 -->

    <level value="ALL" />
    <!-- 记录所有级别的日志 -->

    <appender-ref ref="InfoFileAppender" />
    <!-- 引用INFO appender -->

    <appender-ref ref="DebugFileAppender" />
    <!-- 引用DEBUG appender -->

    <appender-ref ref="WarnFileAppender" />
    <!-- 引用WARN appender -->

    <appender-ref ref="ErrorFileAppender" />
    <!-- 引用ERROR appender -->

    <appender-ref ref="FatalFileAppender" />
    <!-- 引用FATAL appender -->
  </root>

</log4net>
<!-- log4net配置结束 -->

案例如下

4.注册

在 Program 或 Startup 中注册日志。

复制代码
//构建 log4net 配置文件的完整路径
var configFilePath = Path.Combine(AppContext.BaseDirectory, "log4net.config");
//将 log4net 集成到 .NET Core 的统一日志系统中
builder.Logging.AddLog4Net(configFilePath);

案例如下

4.1.类库项目设置

如果是类库项目,需设置 log4net.config 文件属性

点击到文件 → 属性 → 设置

复制到输出目录:始终赋值 / 如果较新则复制

生成操作: 内容

5.使用

在需要的地方可以随意使用。

复制代码
using Frame4_LibraryCore.BaseConfig;
using Frame5_LibraryLogger.LogHelper;
using Microsoft.AspNetCore.Mvc;

namespace DemoAPI.Controllers
{
    /// <summary>
    /// 日志测试控制器
    /// </summary>
    //[Authorize]// 保护整个控制器
    [Route("api/[controller]/[action]")]//标记路由地址规格
    [ApiController] // 标记该类为 API 控制器,启用一些默认的行为,如模型绑定、输入验证等
    [ApiExplorerSettings(GroupName = nameof(ApiVersionInfo.V1))]//设置控制器的API版本
    public class LoggerController : BaseController
    {
        /// <summary>
        /// 测试日志
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public bool InsertLogAsync()
        {
            //测试日志
            LogHelper.Info("Info");
            LogHelper.Error("Error");
            LogHelper.Debug("Debug");
            LogHelper.Fatal("Fatal");
            LogHelper.Warn("Warn");
            return true;
        }
    }
}

案例如下

相关推荐
zopple5 小时前
常见的 Spring 项目目录结构
java·后端·spring
cjy0001117 小时前
springboot的 nacos 配置获取不到导致启动失败及日志不输出问题
java·spring boot·后端
小江的记录本8 小时前
【事务】Spring Framework核心——事务管理:ACID特性、隔离级别、传播行为、@Transactional底层原理、失效场景
java·数据库·分布式·后端·sql·spring·面试
sheji34168 小时前
【开题答辩全过程】以 基于springboot的校园失物招领系统为例,包含答辩的问题和答案
java·spring boot·后端
程序员cxuan8 小时前
人麻了,谁把我 ssh 干没了
人工智能·后端·程序员
wuyikeer9 小时前
Spring Framework 中文官方文档
java·后端·spring
Victor3569 小时前
MongoDB(61)如何避免大文档带来的性能问题?
后端
Victor3569 小时前
MongoDB(62)如何避免锁定问题?
后端
wuyikeer10 小时前
Spring BOOT 启动参数
java·spring boot·后端
子木HAPPY阳VIP11 小时前
Ubuntu 22.04 VMware 设置固定IP配置
人工智能·后端·目标检测·机器学习·目标跟踪