浏览代码

Route AGI console.log through structured logger with execID

Otto's built-in console.log maps to fmt.Println, bypassing the logger
and producing output without timestamp or context. Override it in
injectStandardLibs so every console.log call in an AGI script is routed
through agiLogger.PrintAndLog with the execution ID prepended.

Output changes from:
  CronDemo tick — execID=... user=... run=...
to:
  2026/06/05 00:34:00 [AGI] [<execID>] CronDemo tick — execID=... user=... run=...

https://claude.ai/code/session_01EHns6vxckbmLuuMcZnzBmS
Claude 2 周之前
父节点
当前提交
398d048a20
共有 1 个文件被更改,包括 13 次插入0 次删除
  1. 13 0
      src/mod/agi/agi.system.go

+ 13 - 0
src/mod/agi/agi.system.go

@@ -38,6 +38,19 @@ func (g *Gateway) injectStandardLibs(vm *otto.Otto, scriptFile string, scriptSco
 	// Available in every AGI script — use it for log correlation, deduplication, etc.
 	vm.Set("EXECUTION_ID", execID)
 
+	// Override otto's built-in console.log (which maps to fmt.Println) so that
+	// script output goes through the structured logger and carries the execID.
+	vm.Set("_agi_console_log", func(call otto.FunctionCall) otto.Value {
+		parts := make([]string, 0, len(call.ArgumentList))
+		for _, arg := range call.ArgumentList {
+			str, _ := arg.ToString()
+			parts = append(parts, str)
+		}
+		agiLogger.PrintAndLog("AGI", "["+execID+"] "+strings.Join(parts, " "), nil)
+		return otto.UndefinedValue()
+	})
+	vm.Run(`var console = { log: _agi_console_log, warn: _agi_console_log, error: _agi_console_log, info: _agi_console_log };`) //nolint:errcheck
+
 	//Response related
 	vm.Set("sendResp", func(call otto.FunctionCall) otto.Value {
 		argString, _ := call.Argument(0).ToString()