mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-07 16:16:37 +08:00
fix(db): log SQL statements at debug level
Move routine GORM SQL output to debug and omit SQL text from slow-query and query-error logs to prevent sensitive parameters from being emitted at production log levels.
This commit is contained in:
+1
-1
@@ -31,7 +31,7 @@ database:
|
|||||||
max_open_conn: 128
|
max_open_conn: 128
|
||||||
conn_max_lifetime: 1800
|
conn_max_lifetime: 1800
|
||||||
conn_max_idle_time: 600
|
conn_max_idle_time: 600
|
||||||
log_level: "info" # error | warn | info | debug | silent
|
log_level: "info" # error | warn | info | debug | silent;SQL 语句仅在 log.level=debug 时输出
|
||||||
ssl_mode: "disable"
|
ssl_mode: "disable"
|
||||||
time_zone: "UTC"
|
time_zone: "UTC"
|
||||||
application_name: "openflare-server"
|
application_name: "openflare-server"
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ sidebar: false
|
|||||||
|
|
||||||
### 修复
|
### 修复
|
||||||
|
|
||||||
|
- GORM SQL 语句改为仅在全局 `debug` 日志级别输出;生产默认日志级别不再记录查询文本,慢查询与执行错误也不包含 SQL 参数,避免节点访问令牌等敏感信息写入应用日志。
|
||||||
- WAF 规则编辑器支持通过按钮或键盘删除普通节点和连线,节点属性栏改为选中节点后按需显示,并修复拖动节点时因 React Flow 初始化状态丢失导致的画面闪烁与 error 015。
|
- WAF 规则编辑器支持通过按钮或键盘删除普通节点和连线,节点属性栏改为选中节点后按需显示,并修复拖动节点时因 React Flow 初始化状态丢失导致的画面闪烁与 error 015。
|
||||||
- WAF 规则编辑器新增启用/停用控制,并移除已废弃的规则组侧站点绑定入口;站点规则顺序统一在反代路由详情中管理。
|
- WAF 规则编辑器新增启用/停用控制,并移除已废弃的规则组侧站点绑定入口;站点规则顺序统一在反代路由详情中管理。
|
||||||
- 修复 Agent 心跳无法从活动 WAF 运行图发现 IP 组引用的问题,并对发布与同步的完整 IP 组快照增加 20 MiB 聚合容量保护。
|
- 修复 Agent 心跳无法从活动 WAF 运行图发现 IP 组引用的问题,并对发布与同步的完整 IP 组快照增加 20 MiB 聚合容量保护。
|
||||||
|
|||||||
@@ -53,30 +53,25 @@ func (l *gormZapLogger) Trace(ctx context.Context, begin time.Time, fc func() (s
|
|||||||
elapsed := time.Since(begin)
|
elapsed := time.Since(begin)
|
||||||
switch {
|
switch {
|
||||||
case err != nil && l.logLevel >= gormLogger.Error && (!errors.Is(err, gorm.ErrRecordNotFound) || !l.ignoreRecordNotFoundError):
|
case err != nil && l.logLevel >= gormLogger.Error && (!errors.Is(err, gorm.ErrRecordNotFound) || !l.ignoreRecordNotFoundError):
|
||||||
sql, rows := fc()
|
_, rows := fc()
|
||||||
if rows == -1 {
|
logger.ErrorF(ctx, "database query failed: %s [%.3fms] [rows:%v]", err, float64(elapsed.Nanoseconds())/nanoToMilli, formatRows(rows))
|
||||||
logger.ErrorF(ctx, "%s\n[%.3fms] [rows:%v] %s", err, float64(elapsed.Nanoseconds())/nanoToMilli, "-", sql)
|
|
||||||
} else {
|
|
||||||
logger.ErrorF(ctx, "%s\n[%.3fms] [rows:%v] %s", err, float64(elapsed.Nanoseconds())/nanoToMilli, rows, sql)
|
|
||||||
}
|
|
||||||
case elapsed > l.slowThreshold && l.slowThreshold != 0 && l.logLevel >= gormLogger.Warn:
|
case elapsed > l.slowThreshold && l.slowThreshold != 0 && l.logLevel >= gormLogger.Warn:
|
||||||
sql, rows := fc()
|
_, rows := fc()
|
||||||
slowLog := fmt.Sprintf("SLOW SQL >= %v", l.slowThreshold)
|
slowLog := fmt.Sprintf("SLOW SQL >= %v", l.slowThreshold)
|
||||||
if rows == -1 {
|
logger.WarnF(ctx, "%s [%.3fms] [rows:%v]", slowLog, float64(elapsed.Nanoseconds())/nanoToMilli, formatRows(rows))
|
||||||
logger.WarnF(ctx, "%s\n[%.3fms] [rows:%v] %s", slowLog, float64(elapsed.Nanoseconds())/nanoToMilli, "-", sql)
|
|
||||||
} else {
|
|
||||||
logger.WarnF(ctx, "%s\n[%.3fms] [rows:%v] %s", slowLog, float64(elapsed.Nanoseconds())/nanoToMilli, rows, sql)
|
|
||||||
}
|
|
||||||
case l.logLevel == gormLogger.Info:
|
case l.logLevel == gormLogger.Info:
|
||||||
sql, rows := fc()
|
sql, rows := fc()
|
||||||
if rows == -1 {
|
logger.DebugF(ctx, "[%.3fms] [rows:%v] %s", float64(elapsed.Nanoseconds())/nanoToMilli, formatRows(rows), sql)
|
||||||
logger.InfoF(ctx, "[%.3fms] [rows:%v] %s", float64(elapsed.Nanoseconds())/nanoToMilli, "-", sql)
|
|
||||||
} else {
|
|
||||||
logger.InfoF(ctx, "[%.3fms] [rows:%v] %s", float64(elapsed.Nanoseconds())/nanoToMilli, rows, sql)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func formatRows(rows int64) interface{} {
|
||||||
|
if rows == -1 {
|
||||||
|
return "-"
|
||||||
|
}
|
||||||
|
return rows
|
||||||
|
}
|
||||||
|
|
||||||
func parseLogLevel(level string) gormLogger.LogLevel {
|
func parseLogLevel(level string) gormLogger.LogLevel {
|
||||||
level = strings.ToLower(level)
|
level = strings.ToLower(level)
|
||||||
switch level {
|
switch level {
|
||||||
@@ -88,6 +83,8 @@ func parseLogLevel(level string) gormLogger.LogLevel {
|
|||||||
return gormLogger.Warn
|
return gormLogger.Warn
|
||||||
case "info":
|
case "info":
|
||||||
return gormLogger.Info
|
return gormLogger.Info
|
||||||
|
case "debug":
|
||||||
|
return gormLogger.Info
|
||||||
default:
|
default:
|
||||||
return gormLogger.Info
|
return gormLogger.Info
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
// Copyright 2026 Arctel.net
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package db
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
gormLogger "gorm.io/gorm/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParseLogLevel(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
configuredLevel string
|
||||||
|
want gormLogger.LogLevel
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "debug enables SQL trace processing",
|
||||||
|
configuredLevel: "debug",
|
||||||
|
want: gormLogger.Info,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "development preserves configured level",
|
||||||
|
configuredLevel: "warn",
|
||||||
|
want: gormLogger.Warn,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := parseLogLevel(tt.configuredLevel); got != tt.want {
|
||||||
|
t.Fatalf("parseLogLevel() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user