Skip to content

操作日志

Hei Gin 提供了完整的操作日志系统,能够自动录制用户的操作行为,为审计和安全追溯提供数据基础。

SysLog 中间件

文件core/log/syslog.go

SysLog 是操作日志录制的核心中间件,通过在路由注册时挂载,自动捕获和记录 API 请求信息。它接受一个操作名称并返回一个 gin.HandlerFunc

go
func SysLog(name string) gin.HandlerFunc

没有额外的录制选项参数。请求参数(Body)的录制行为由中间件内部自动处理(仅 POST/PUT/PATCH 方法),响应结果默认不录制。

注册方式

go
import "hei-gin/core/log"

// 记录操作日志
r.POST("/user/save",
    middleware.HeiCheckLogin(),
    middleware.HeiCheckPermission("sys:user:create"),
    log.SysLog("创建用户"),
    handler.UserSave,
)

参数说明

参数类型说明
namestring操作名称,如"创建用户"、"修改配置"

RecordAuthLog 函数

文件core/log/record.go

用于程序化记录登录/登出等认证相关日志。与 SysLog 中间件不同,它不需要从上下文中获取操作人,而是直接接受操作人名称参数——这对尚无可用的认证 Token 的登录事件至关重要。

go
func RecordAuthLog(c *gin.Context, name, category, exeStatus, exeMessage, opUser string)

该函数当前为控制台日志输出log.Printf),尚未接入数据库持久化,待日志模块完成后接入。

参数说明

参数类型说明
namestring日志名称
categorystring日志分类(如 "LOGIN"、"LOGOUT")
exeStatusstring执行状态("SUCCESS" / "FAIL")
exeMessagestring执行消息
opUserstring操作人用户名

录制内容

中间件内部通过 saveLog 函数将日志写入数据库,每条记录包含以下字段:

字段类型说明中间件是否填充
idstring雪花 ID(分布式唯一)
categorystring日志分类:"OPERATE"(成功)或 "EXCEPTION"(异常)
namestring操作名称(如"创建用户")
exe_statusstring执行状态:"SUCCESS""FAIL"
exe_messagestring具体消息(BusinessError 详情或 panic 信息,成功时为空)
op_ipstring客户端 IP 地址
op_addressstringIP 地理位置(城市,由 ip2region 解析)
op_browserstring浏览器名称(由 User-Agent 解析)
op_osstring操作系统名称(由 User-Agent 解析)
class_namestring类名称
method_namestring方法名称
req_methodstringHTTP 方法(GET/POST/PUT/DELETE)
req_urlstring请求 URL
param_jsonstring请求参数 JSON(仅 POST/PUT/PATCH 方法,排除 request/db/file 参数)
result_jsonstring返回结果 JSON否*
op_timetime操作时间
trace_idstring跟踪 ID
op_userstring操作人用户名(从 gin.Context 的 "loginUser" 键获取)
sign_datastringSM3 签名数据否*
created_attime创建时间
created_bystring创建用户
updated_attime更新时间
updated_bystring更新用户

*result_jsonsign_data 字段存在于数据库 schema 中,提供 GetResultJsonGenerateLogSignature 工具函数,但当前 SysLog 中间件不会自动填充这两个字段。如需要,可在业务 handler 中手动调用并设置。

请求参数提取机制

ExtractParamsJson 函数(core/log/utils.go)负责提取请求参数:

  • 仅对 POST / PUT / PATCH 方法生效;GET / DELETE 返回空字符串
  • 自动排除基础设施参数:requestdbfile
  • 排除值为 nil 的参数
  • 读取 Body 后会自动恢复,不影响下游 handler 的 ShouldBindJSON 等操作

SM3 签名工具

GenerateLogSignature 函数(core/log/utils.go)可用于对日志数据进行防篡改签名:

go
func GenerateLogSignature(opData map[string]any) string
  • 使用 SM3 算法和盐值 "hei-log-sign" 进行哈希
  • opData map 序列化为 JSON 后计算签名
  • 当前为可选功能,中间件不会自动调用此函数;需在业务代码中手动使用

日志查询 API

日志模块(modules/sys/log/)提供以下接口,均注册在 /api/v1/sys/log/ 路径下。

日志列表

http
GET /api/v1/sys/log/page

请求参数(Query):

参数类型说明
currentint页码,默认 1
sizeint每页条数,默认 10
keywordstring按操作名称模糊搜索(可选)
categorystring按分类筛选:OPERATE / EXCEPTION(可选)
exe_statusstring按执行状态筛选:SUCCESS / FAIL(可选)

列表查询排除大字段(exe_messageparam_jsonresult_jsonsign_data),按操作时间降序排列。

日志详情

http
GET /api/v1/sys/log/detail?id={logId}

返回单条日志的完整信息,包含所有字段。

创建日志

http
POST /api/v1/sys/log/create

手动创建操作日志记录。

修改日志

http
POST /api/v1/sys/log/modify

编辑现有操作日志记录。

删除日志

http
POST /api/v1/sys/log/remove

按 ID 列表批量删除日志。

按分类删除

http
POST /api/v1/sys/log/delete-by-category

请求参数(JSON Body):

参数类型说明
categorystring日志分类,如 OPERATEEXCEPTION

访问量折线图

http
GET /api/v1/sys/log/vis/line-chart-data

返回最近 7 天每日的 LOGIN / LOGOUT 数量。

访问量饼图

http
GET /api/v1/sys/log/vis/pie-chart-data

返回 LOGIN / LOGOUT 总量。

操作量柱状图

http
GET /api/v1/sys/log/op/bar-chart-data

返回最近 7 天每日的 OPERATE / EXCEPTION 数量。

操作量饼图

http
GET /api/v1/sys/log/op/pie-chart-data

返回 OPERATE / EXCEPTION 总量。

数据模型

操作日志的数据模型定义在 ent/schema/syslog.go,映射数据库表 sys_log

字段名数据库类型Go 类型说明
idvarchar(32)string主键,雪花 ID
categoryvarchar(255)*string日志分类(OPERATE / EXCEPTION)
namevarchar(255)*string日志名称
exe_statusvarchar(255)*string执行状态(SUCCESS / FAIL)
exe_messagetext*string具体消息
op_ipvarchar(255)*string操作 IP
op_addressvarchar(255)*string操作地址
op_browservarchar(255)*string操作浏览器
op_osvarchar(255)*string操作系统
class_namevarchar(255)*string类名称
method_namevarchar(255)*string方法名称
req_methodvarchar(255)*string请求方式
req_urltext*string请求地址
param_jsontext*string请求参数
result_jsontext*string返回结果
op_timedatetime*time.Time操作时间
trace_idvarchar(64)*string跟踪 ID
op_uservarchar(255)*string操作人姓名
sign_datatext*string签名数据
created_atdatetime*time.Time创建时间
created_byvarchar(32)*string创建用户
updated_atdatetime*time.Time更新时间
updated_byvarchar(32)*string更新用户

最佳实践

1. 选择合适的记录方式

go
// SysLog 中间件 - 自动记录,适合标准 API 路由
r.POST("/api/v1/sys/user", log.SysLog("创建用户"), handler.UserSave)

// RecordAuthLog - 程序化记录,适合登录/登出等特殊场景
log.RecordAuthLog(c, "用户登录", "LOGIN", "SUCCESS", "", username)

2. 手动录制响应结果或签名

当前中间件不会自动记录 result_jsonsign_data。若需要,可在 handler 中手动调用工具函数:

go
import "hei-gin/core/log"

func MyHandler(c *gin.Context) {
    data := doBusiness(c)
    
    // 手动获取响应结果 JSON
    resultJSON := log.GetResultJson(data)
    
    // 手动生成签名
    sign := log.GenerateLogSignature(map[string]any{
        "result": data,
        "user":   "xxx",
    })
    
    // 将 data 存入日志或通过其他方式持久化
    _ = resultJSON
    _ = sign
}

3. 避免记录敏感信息

ExtractParamsJson 会自动排除 requestdbfile 等基础设施参数,但仍需注意:

  • 登录接口的密码字段虽然已 SM2 加密,但仍建议不在请求体中包含明文敏感信息
  • 涉及个人隐私的数据(身份证、手机号)建议在传输前脱敏
  • 大文件上传接口的请求体不会被记录(文件参数被排除)

4. 日志清理策略

操作日志数据量会随时间增长,可通过 API 定期清理:

http
POST /api/v1/sys/log/delete-by-category
Content-Type: application/json

{"category": "OPERATE"}

或通过系统配置模块设置自动清理策略。

相关文件

文件说明
core/log/syslog.goSysLog 中间件实现(自动录制 + 数据库写入)
core/log/record.goRecordAuthLog 函数(程序化记录,当前为控制台日志)
core/log/utils.go工具函数:User-Agent 解析、参数提取、结果序列化、签名生成
ent/schema/syslog.go数据库模型定义
modules/sys/log/日志查询管理模块(API + Service + 参数)

Released under the MIT License.