Skip to content

日志记录

框架使用NLog替换了 .NET 官方的日志实现,可以进行更复杂更精细的日志记录控制。例如变量捕获、条件规则等。

初始化项目时,应该从框架的 Api 项目拷贝最新的日志配置文件 nlog.config

记录形式

框架记录的日志级别和记录形式如下表所示。

日志形式日志级别说明
文件任意级别每天会生成一个新文件
控制台Debug及以上
数据库Error及以上不同用途的日志使用独立数据库表存储

提示

自 3.1.0 版本起,控制台使用彩色显示日志,可以明显地区分不同级别的日志。

系统日志

系统日志会写入专门的系统日志表,用来记录系统运行期间产生的错误信息和其它关键信息。前端有配套的查询页面。

  • 异常

    框架在程序运行出现异常时捕获错误,记录至系统日志。内容包括时间、错误消息、调用堆栈。

  • 错误

    Error 及以上级别的日志,也会写入日志表。

  • 其它

    特别地,当日志内容包含[force]前缀时,任意级别都可以写入系统日志表。

用户日志

用户日志通常用来记录系统用户的关键操作,在问题排查和操作追溯等场景使用。前端有配套的查询页面。

框架提供了声明式的用户日志记录支持,只需要在目标控制器方法添加UserLog特性即可。 框架内部会同时记录操作人、请求信息。

csharp
[HttpPost]
[RequiresPermissions("roles:add")]
[UserLog("添加角色", BodyLimit = 500)]
public Result<string> CreateV1(RoleAddDto model)
{
    return service.Create(model).ToResult();
}

提示

3.0.0 以下版本请使用 OperateLog 特性。

UserLogAttribute

3.1.1 版本开始支持以下参数。

名称类型说明
IgnoreQuerybool是否忽略URL参数,默认否
IgnoreBodybool是否忽略请求体,默认否
BodyLimitint请求体记录最大值。默认 500 字节。-1 不限制。

注意

在记录特殊操作(例如:修改密码)时,应使用 IgnoreQuery、IgnoreBody 参数,避免敏感数据写入日志。

在记录 Post / Put 请求时,应合理使用 BodyLimit 参数,避免记录内容过长。

登录日志

登录日志记录用户账号、登入、登出系统的时间、IP、状态等信息,在问题排查、安全审计时有很大作用。前端有配套的查询页面。

框架提供了特性LoginLogAttributeLogoutLogAttribute分别记录登录和退出日志,开发人员通常不需要关注。特殊情况下(如自定义登录)可以按需使用。

csharp
[AllowAnonymous]
[HttpPost("cus-login")]
[LoginLog("p.vm.Account", LoginLogFrom.Local)]
public Result<LoginVo> Login([FromBody] LoginDto vm)
{
    // 省略
}

[HttpPost("logout")]
[LogoutLog]
public async Task<Result> Logout()
{
    // 省略
}

提示

LoginLogAttribute 参数使用了表达式来指定账号字段。

HTTP 日志

Http 日志包含入站请求和出站请求日志。

入站

入站日志指外部访问本应用的日志,可以用来查看请求参数、响应结果。这在排查问题时尤其有用。

框架默认不开启入站日志,管理人员可以在接口配置功能中打开指定服务接口的日志。

api-log

提示

入站日志会写入日志文件、控制台、系统日志表。

出站

出站日志指调用外部接口的日志,同样可以记录请求参数、响应结果信息。

框架集成了声明式的 HTTP 请求库 WebApiClient,要记录日志只需要在目标方法加上 LoggingFilter 特性即可。

管理员也可以在系统设置中随时开启或关闭出站日志。

http-out

提示

出站日志会写入日志文件、控制台。

注意

HTTP 请求类必须放在 *.Service.Http 命名空间下,才能由系统设置控制日志开启状态。否则需要修改 nlog 配置。

SQL 日志

SQL 日志记录程序执行的 SQL 语句和参数,供开发人员调试程序、排查问题使用。

3.1.0版本起,框架默认不开启 SQL 日志。管理员可以在系统设置功能中随时开启或关闭, 尤其方便短期性的线上问题排查。

log-sql

提示

SQL 日志会写入日志文件、控制台。

TraceId v3.3.3+

应用服务器通常以多线程同时处理多个请求,不同线程中产生的多条日志很可能互相交叉,阅读时难以快速区分。 尤其是难以获得一次请求相关的所有日志。我们为日志添加了 TraceId 信息,可以解决这些问题。

配置方式

从框架的 Api 项目拷贝最新的日志配置文件 nlog.config

运行效果

每次记录日志都会包含 trace id 信息。在同一个请求中处理过程中产生的日志,它们的 trace id 一致。 下例显示了一次 trace id 为 46a8eefe3c714713a1f59ba4fdea701d 的请求处理时产生的日志。

text
[debu]<46a8eefe3c714713a1f59ba4fdea701d>HZCC.Frm.DAL.Chloe.DbCommandInterceptor: [sql]SELECT "User"."Id"  FROM "User" AS "User" WHERE ("User"."EmpSn" = @P_0 AND "User"."Password" = @P_1) LIMIT 1 OFFSET 0
[debu]<46a8eefe3c714713a1f59ba4fdea701d>HZCC.Frm.DAL.Chloe.DbCommandInterceptor: [sql]params: string,338951b7e51e78NL==
[debu]<46a8eefe3c714713a1f59ba4fdea701d>HZCC.Frm.DAL.Chloe.DbCommandInterceptor: [sql]time elapsed: 33.0966ms
[debu]<46a8eefe3c714713a1f59ba4fdea701d>HZCC.Frm.DAL.Chloe.DbCommandInterceptor: [sql]select columns: 8
[debu]<46a8eefe3c714713a1f59ba4fdea701d>HZCC.Frm.DAL.Chloe.DbCommandInterceptor: [sql]INSERT INTO "LoginLog"("Id","LogTime","Account","UserName","Success","DetailMsg") VALUES(@P_0,@P_1,@P_2,@P_3,@P_4,@P_5,@P_6,@P_7,@P_8,@P_9,@P_10)
[debu]<46a8eefe3c714713a1f59ba4fdea701d>HZCC.Frm.DAL.Chloe.DbCommandInterceptor: [sql]params: 1139139649444904960,2026/3/23 16:57:07,string,,0,1,Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36,False,用户名或密码错误
[debu]<46a8eefe3c714713a1f59ba4fdea701d>HZCC.Frm.DAL.Chloe.DbCommandInterceptor: [sql]time elapsed: 49.142ms
[debu]<46a8eefe3c714713a1f59ba4fdea701d>HZCC.Frm.DAL.Chloe.DbCommandInterceptor: [sql]affected 1 rows

提示

非 HTTP 请求产生的日志,比如项目启动,不会产生 trace id。