ASP.NET Core使用log4net的详细流程

ASP.NET Core使用log4net的详细流程

ASP.NET Core 中,最佳实践是通过 Microsoft.Extensions.Logging 抽象层集成 log4net,从而利用依赖注入(DI)和统一日志接口。

一、安装 NuGet 包

你需要安装两个包:log4net 核心库和 ASP.NET Core 的适配包。

c# 复制代码
Install-Package log4net
Install-Package Microsoft.Extensions.Logging.Log4Net.AspNetCore
// 根据你的数据库类型选择对应的驱动
// SQL Server
dotnet add package System.Data.SqlClient 
//或者    SQL Server
dotnet add package Microsoft.Data.SqlClient 
二、创建配置文件
2.1、日志写入本地文件

在项目根目录创建 log4net.config 文件,并将属性设置为 ‌"复制到输出目录: 如果较新则复制"‌。

xml 复制代码
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
  <!-- 定义滚动日志文件追加器 -->
  <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
    <!-- 日志文件路径 -->
    <file value="Logs/rbac-.log" />
    <!-- 是否追加到现有文件 -->
    <appendToFile value="true" />
    <!-- 滚动方式:按日期 -->
    <rollingStyle value="Date" />
    <!-- 日期格式 -->
    <datePattern value="yyyyMMdd'.log'" />
    <!-- 最多保留30个备份文件 -->
    <maxSizeRollBackups value="30" />
    <!-- 每个文件最大10MB -->
    <maximumFileSize value="10MB" />
    <!-- 静态文件名,为false则动态生成 -->
    <staticLogFileName value="false" />
    <!-- 日志布局格式 -->
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
    </layout>
    <!-- 编码格式 -->
    <encoding value="utf-8" />
  </appender>

  <!-- 定义控制台追加器 -->
  <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
    </layout>
  </appender>

  <!-- 根日志配置 -->
  <root>
    <!-- 日志级别:INFO及以上 -->
    <level value="INFO" />
    <!-- 引用追加器 -->
    <appender-ref ref="RollingFileAppender" />
    <appender-ref ref="ConsoleAppender" />
  </root>

  <!-- 操作日志记录器 -->
  <logger name="OperationLog">
    <level value="INFO" />
    <appender-ref ref="RollingFileAppender" />
  </logger>
</log4net>
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
  <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
    </layout>
  </appender>

  <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
    <file value="logs/app.log" />
    <appendToFile value="true" />
    <rollingStyle value="Date" />
    <datePattern value="yyyyMMdd'.log'" />
    <staticLogFileName value="false" />
    <maxSizeRollBackups value="10" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
    </layout>
  </appender>

  <root>
    <level value="Info" />
    <appender-ref ref="ConsoleAppender" />
    <appender-ref ref="RollingFileAppender" />
  </root>
</log4net>
2.2、日志写入SQL Server

创建数据库表

在您的数据库中创建一个用于存储日志的表。表结构应至少包含时间、日志级别、消息等基本信息,也可以根据需要添加自定义字段(如用户ID、IP地址等)。

sql 复制代码
CREATE TABLE ProgramLog (
  Id int IDENTITY(1,1) PRIMARY KEY,
  Date datetime NOT NULL,
  Thread nvarchar(255) NOT NULL,
  Level nvarchar(50) NOT NULL,
  Logger nvarchar(255) NOT NULL,
  Message nvarchar(max) NOT NULL,
  Exception nvarchar(max),
  UserId nvarchar(100), -- 自定义字段示例
  IpAddress nvarchar(45) -- 自定义字段示例
);

配置Log4Net (通常在 log4net.config 文件中)

  • 定义一个 AdoNetAppender
  • 设置 connectionString 为您的数据库连接字符串。
  • 设置 commandText 为您插入日志的SQL语句(通常是 INSERT INTO ... VALUES (...))。
  • 使用 <mapping> 元素将SQL参数(如 @log_date, @log_message)映射到Log4Net事件的属性(如 %date, %message)。
xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>

  <log4net>
    <!-- AdoNetAppender 配置 -->
    <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
      <!-- 数据库连接字符串 -->
      <connectionString value="Server=your_server;Database=your_db;Trusted_Connection=true;" />
      <connectionType value="System.Data.SqlClient.SqlConnection, System.Data.SqlClient" />

      <!-- SQL 插入命令 -->
      <commandText value="INSERT INTO ProgramLog (Date, Thread, Level, Logger, Message, Exception, UserId, IpAddress) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception, @user_id, @ip_address)" />

      <!-- 参数映射 -->
      <parameter>
        <parameterName value="@log_date" />
        <dbType value="DateTime" />
        <layout type="log4net.Layout.PatternLayout" value="%date{yyyy-MM-dd HH:mm:ss.fff}" />
      </parameter>
      <parameter>
        <parameterName value="@thread" />
        <dbType value="String" />
        <size value="255" />
        <layout type="log4net.Layout.PatternLayout" value="%thread" />
      </parameter>
      <parameter>
        <parameterName value="@log_level" />
        <dbType value="String" />
        <size value="50" />
        <layout type="log4net.Layout.PatternLayout" value="%level" />
      </parameter>
      <parameter>
        <parameterName value="@logger" />
        <dbType value="String" />
        <size value="255" />
        <layout type="log4net.Layout.PatternLayout" value="%logger" />
      </parameter>
      <parameter>
        <parameterName value="@message" />
        <dbType value="String" />
        <size value="4000" />
        <layout type="log4net.Layout.PatternLayout" value="%message" />
      </parameter>
      <parameter>
        <parameterName value="@exception" />
        <dbType value="String" />
        <size value="4000" />
        <layout type="log4net.Layout.ExceptionLayout" />
      </parameter>
      <!-- 自定义字段映射示例 -->
      <parameter>
        <parameterName value="@user_id" />
        <dbType value="String" />
        <size value="100" />
        <layout type="log4net.Layout.PatternLayout" value="%property{UserId}" />
      </parameter>
       <parameter>
        <parameterName value="@ip_address" />
        <dbType value="String" />
        <size value="45" />
        <layout type="log4net.Layout.PatternLayout" value="%property{IpAddress}" />
      </parameter>

    </appender>

    <!-- Root Logger 配置 -->
    <root>
      <level value="DEBUG" />
      <appender-ref ref="AdoNetAppender" />
    </root>
  </log4net>
</configuration>
2.3、日志同时写入SQL Server和本地文件
xml 复制代码
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
  <!-- 定义滚动日志文件追加器 -->
  <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
    <!-- 日志文件路径 -->
    <file value="Logs/rbac-.log" />
    <!-- 是否追加到现有文件 -->
    <appendToFile value="true" />
    <!-- 滚动方式:按日期 -->
    <rollingStyle value="Date" />
    <!-- 日期格式 -->
    <datePattern value="yyyyMMdd'.log'" />
    <!-- 最多保留30个备份文件 -->
    <maxSizeRollBackups value="30" />
    <!-- 每个文件最大10MB -->
    <maximumFileSize value="10MB" />
    <!-- 静态文件名,为false则动态生成 -->
    <staticLogFileName value="false" />
    <!-- 日志布局格式 -->
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
    </layout>
    <!-- 编码格式 -->
    <encoding value="utf-8" />
  </appender>

	<!-- AdoNetAppender 配置 -->
	<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">


		<!-- 1. 指定数据库驱动类型 -->
		<connectionType value="System.Data.SqlClient.SqlConnection, System.Data.SqlClient" />
		
		<!-- 2. 数据库连接字符串 -->
		<connectionString value="Server=HC-PC\HC;Database=FMS_Db;User ID=sa;Password=68501507;integrated security=false;persist security info=True;Trusted_Connection=true;" />
		<!-- 3. 命令缓冲区大小(可选,提高性能) -->
		<bufferSize value="100" />

		<!-- SQL 插入命令 -->
		<commandText value="INSERT INTO ProgramLog (Date, Thread, Level, Logger, Message, Exception, UserId, IpAddress) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception, @user_id, @ip_address)" />

		<!-- 参数映射 -->
		<parameter>
			<parameterName value="@log_date" />
			<dbType value="DateTime" />
			<layout type="log4net.Layout.PatternLayout" value="%date{yyyy-MM-dd HH:mm:ss.fff}" />
		</parameter>
		<parameter>
			<parameterName value="@thread" />
			<dbType value="String" />
			<size value="255" />
			<layout type="log4net.Layout.PatternLayout" value="%thread" />
		</parameter>
		<parameter>
			<parameterName value="@log_level" />
			<dbType value="String" />
			<size value="50" />
			<layout type="log4net.Layout.PatternLayout" value="%level" />
		</parameter>
		<parameter>
			<parameterName value="@logger" />
			<dbType value="String" />
			<size value="255" />
			<layout type="log4net.Layout.PatternLayout" value="%logger" />
		</parameter>
		<parameter>
			<parameterName value="@message" />
			<dbType value="String" />
			<size value="4000" />
			<layout type="log4net.Layout.PatternLayout" value="%message" />
		</parameter>
		<parameter>
			<parameterName value="@exception" />
			<dbType value="String" />
			<size value="4000" />
			<layout type="log4net.Layout.ExceptionLayout" />
		</parameter>
		<!-- 自定义字段映射示例 -->
		<parameter>
			<parameterName value="@user_id" />
			<dbType value="String" />
			<size value="100" />
			<layout type="log4net.Layout.PatternLayout" value="%property{UserId}" />
		</parameter>
		<parameter>
			<parameterName value="@ip_address" />
			<dbType value="String" />
			<size value="45" />
			<layout type="log4net.Layout.PatternLayout" value="%property{IpAddress}" />
		</parameter>

	</appender>

	
	

	<!-- 根日志配置 -->
  <root>
    <!-- 日志级别:INFO及以上 -->
    <level value="INFO" />
    <!-- 引用追加器 -->
    <appender-ref ref="RollingFileAppender" />
	<appender-ref ref="AdoNetAppender" />
  </root>

  <!-- 操作日志记录器 -->
  <logger name="OperationLog">
    <level value="INFO" />
    <appender-ref ref="RollingFileAppender" />
  </logger>
</log4net>
三、在 Program.cs 中注册

在 Program.cs 中,使用 AddLog4Net扩展方法将 log4net 添加到日志构建器中。

csharp 复制代码
// 1. 清除默认的日志提供者(可选,如果你只想用 Log4Net)
builder.Logging.ClearProviders();

// 2. 添加 Log4Net
// 方法 A: 使用扩展方法自动读取 log4net.config (推荐)
// 注意:确保 log4net.config 文件存在于项目根目录并已设置为复制
builder.Logging.AddLog4Net("log4net.config");

// 或者明确指定配置文件地址
//builder.Logging.AddLog4Net(Path.Combine(Directory.GetCurrentDirectory(), "log4net.config"));


// 其他服务注册...
builder.Services.AddControllers();

var app = builder.Build();

// 中间件配置...
app.MapControllers();
app.Run();
四、在控制器中使用

通过构造函数注入 ILogger 即可使用,无需直接引用 log4net 的 API。

csharp 复制代码
    [Authorize(Policy = "AdminOnly")]
    public class GatewayController : LayuiApiController
    {
        private readonly IGatewayRepository _gatewayRepository;
        /// <summary>
        /// 日志记录器,用于记录告警相关的操作日志和错误日志
        /// </summary>
        private readonly ILogger<GatewayController> _logger;
        public GatewayController(IGatewayRepository gatewayRepository, ILogger<GatewayController> logger)
        {
            _gatewayRepository = gatewayRepository;
            _logger = logger;
        }


        /// <summary>
        /// 网关主页
        /// </summary>
        /// <returns></returns>
        public IActionResult GatewayIndex()
        {
            ViewData["Title"] = "网关管理";
            return View();
        }

        /// <summary>
        /// 获取所有网关列表(支持分页)
        /// </summary>
        /// <param name="page">页码</param>
        /// <param name="limit">每页数量</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> GatewayList(int page = 1, int limit = 10)
        {
            try
            {
                var gateways = await _gatewayRepository.GetAllGatewaysAsync();
                var total = gateways.Count();
                var pagedData = gateways.Skip((page - 1) * limit).Take(limit).ToList();
                
                return SuccessResult(data: pagedData, count: total);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "GatewayList的方法,获取网关列表失败");
                return ErrorResult($"获取网关列表失败:{ex.Message}");
            }
        }
   }
  }
相关推荐
光泽雨12 小时前
c#中的“跨界找人”
c#
yuan1999713 小时前
基于 C# 实现的 Omron HostLink (FINS) 协议 PLC 通讯
开发语言·c#
火星papa14 小时前
C# 任务(Task)的基础实现
c#·任务·task
烛阴16 小时前
Unity资源加载进化论:从AssetBundle到Addressables,一文带你吃透手游资源管理
前端·c#·unity3d
aini_lovee19 小时前
C#与倍福PLC(通过ADS协议)通信上位机源程序实现
开发语言·c#
2501_9307077820 小时前
使用C#代码压平 PDF 表单字段
数据库·pdf·c#
IT知识分享1 天前
数字上标、下标如何打,6种常用方法详解
开发语言·c#·xhtml
码农学院1 天前
itextsharp .net中如何设置两个表格的间距设为0,取网站的域名,协议、端口、当前站点目录的地址
开发语言·c#·.net