From 5e83eaa1bc37f2f708bfad68e0fc8b69ed9af861 Mon Sep 17 00:00:00 2001 From: Abdurrahman Dridi Date: Sat, 18 May 2024 20:42:44 +0100 Subject: [PATCH 1/2] Added support for including sql variables in debug statement --- core/config.go | 3 +++ serv/http.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/core/config.go b/core/config.go index 535aaa2a..15d9cd13 100644 --- a/core/config.go +++ b/core/config.go @@ -69,6 +69,9 @@ type Config struct { // Log warnings and other debug information Debug bool `jsonschema:"title=Debug,default=false"` + // Replace variable placeholders in the debug sql query with actual values + DebugReplaceVars bool `mapstructure:"debug_replace_vars" json:"debug_replace_vars" yaml:"debug_replace_vars" jsonschema:"title=Debug Replace Variables,default=false"` + // Database polling duration (in seconds) used by subscriptions to // query for updates. SubsPollDuration time.Duration `mapstructure:"subs_poll_duration" json:"subs_poll_duration" yaml:"subs_poll_duration" jsonschema:"title=Subscription Polling Duration,default=5s"` diff --git a/serv/http.go b/serv/http.go index dc2e1aae..d793d929 100644 --- a/serv/http.go +++ b/serv/http.go @@ -342,6 +342,20 @@ func (s *service) reqLog(res *core.Result, rc core.ReqConfig, resTimeMs int64, e zap.String("role", res.Role()), zap.Int64("responseTimeMs", resTimeMs), } + + if s.conf.Core.DebugReplaceVars { + var vars map[string]interface{} + if err := json.Unmarshal(res.Vars, &vars); err == nil { + for i := 1; ; i++ { + placeholder := fmt.Sprintf("$%d", i) + if val, ok := vars[getKeyByIndex(vars, i-1)]; ok { + sql = replacePlaceholder(sql, placeholder, val) + } else { + break + } + } + } + } } if ns, ok := rc.GetNamespace(); ok { @@ -364,6 +378,34 @@ func (s *service) reqLog(res *core.Result, rc core.ReqConfig, resTimeMs int64, e } } +func getKeyByIndex(m map[string]interface{}, index int) string { + i := 0 + for k := range m { + if i == index { + return k + } + i++ + } + return "" +} + +func replacePlaceholder(sql, placeholder string, value interface{}) string { + switch v := value.(type) { + case string: + valStr := fmt.Sprintf("'%s'", v) + return strings.Replace(sql, placeholder, valStr, -1) + case int, int64, float64: + valStr := fmt.Sprintf("%v", v) + return strings.Replace(sql, placeholder, valStr, -1) + case bool: + valStr := fmt.Sprintf("%t", v) + return strings.Replace(sql, placeholder, valStr, -1) + default: + valStr := fmt.Sprintf("%v", v) + return strings.Replace(sql, placeholder, valStr, -1) + } +} + func (s *service) setHeaderVars(r *http.Request) map[string]interface{} { vars := make(map[string]interface{}) for k, v := range s.conf.Core.HeaderVars { From 5a90ff9b514e8f3b1a4329a715df7e108964fcd0 Mon Sep 17 00:00:00 2001 From: Abdurrahman Dridi Date: Mon, 20 May 2024 23:17:23 +0100 Subject: [PATCH 2/2] replaced in-line variable replacement --- core/config.go | 4 ++-- serv/http.go | 51 +++++++++----------------------------------------- 2 files changed, 11 insertions(+), 44 deletions(-) diff --git a/core/config.go b/core/config.go index 15d9cd13..45f36d74 100644 --- a/core/config.go +++ b/core/config.go @@ -69,8 +69,8 @@ type Config struct { // Log warnings and other debug information Debug bool `jsonschema:"title=Debug,default=false"` - // Replace variable placeholders in the debug sql query with actual values - DebugReplaceVars bool `mapstructure:"debug_replace_vars" json:"debug_replace_vars" yaml:"debug_replace_vars" jsonschema:"title=Debug Replace Variables,default=false"` + // Log SQL Query variable values + LogSQLVars bool `mapstructure:"log_sql_vars" json:"log_sql_vars" yaml:"log_sql_vars" jsonschema:"title=Log SQL Variables,default=false"` // Database polling duration (in seconds) used by subscriptions to // query for updates. diff --git a/serv/http.go b/serv/http.go index d793d929..ad2d2d84 100644 --- a/serv/http.go +++ b/serv/http.go @@ -342,26 +342,21 @@ func (s *service) reqLog(res *core.Result, rc core.ReqConfig, resTimeMs int64, e zap.String("role", res.Role()), zap.Int64("responseTimeMs", resTimeMs), } - - if s.conf.Core.DebugReplaceVars { - var vars map[string]interface{} - if err := json.Unmarshal(res.Vars, &vars); err == nil { - for i := 1; ; i++ { - placeholder := fmt.Sprintf("$%d", i) - if val, ok := vars[getKeyByIndex(vars, i-1)]; ok { - sql = replacePlaceholder(sql, placeholder, val) - } else { - break - } - } - } - } } if ns, ok := rc.GetNamespace(); ok { fields = append(fields, zap.String("namespace", ns)) } + if res.Vars != nil && s.conf.Core.LogSQLVars { + var vars map[string]interface{} + err := json.Unmarshal(res.Vars, &vars) + if err != nil { + s.log.Error("failed to unmarshal sql vars", zap.Error(err)) + } + fields = append(fields, zap.Any("sqlVars", vars)) + } + if sql != "" && s.logLevel >= logLevelDebug { fields = append(fields, zap.String("sql", sql)) } @@ -378,34 +373,6 @@ func (s *service) reqLog(res *core.Result, rc core.ReqConfig, resTimeMs int64, e } } -func getKeyByIndex(m map[string]interface{}, index int) string { - i := 0 - for k := range m { - if i == index { - return k - } - i++ - } - return "" -} - -func replacePlaceholder(sql, placeholder string, value interface{}) string { - switch v := value.(type) { - case string: - valStr := fmt.Sprintf("'%s'", v) - return strings.Replace(sql, placeholder, valStr, -1) - case int, int64, float64: - valStr := fmt.Sprintf("%v", v) - return strings.Replace(sql, placeholder, valStr, -1) - case bool: - valStr := fmt.Sprintf("%t", v) - return strings.Replace(sql, placeholder, valStr, -1) - default: - valStr := fmt.Sprintf("%v", v) - return strings.Replace(sql, placeholder, valStr, -1) - } -} - func (s *service) setHeaderVars(r *http.Request) map[string]interface{} { vars := make(map[string]interface{}) for k, v := range s.conf.Core.HeaderVars {