
WeKnora 日志配置完全指南环境变量驱动、自定义模板与源码级实现解析【免费下载链接】WeKnoraOpen-source LLM knowledge platform: turn raw documents into a queryable RAG, an autonomous reasoning agent, and a self-maintaining Wiki.项目地址: https://gitcode.com/GitHub_Trending/we/WeKnoraWeKnora 的日志系统由 internal/logger 包统一管理全部行为通过环境变量驱动无需修改任何代码即可完成日志级别、落盘与输出格式的定制。本文以 docs/日志配置.md 为骨架结合源码实现深入讲解LOG_LEVEL、LOG_PATH、LOG_FORMAT三个核心变量的语义与注意事项并补充 LLM 调试日志、Docker 部署与常见排查场景帮助你在开发、容器化部署与日志采集环境下快速完成配置并理解其底层原理。一、日志系统总览环境变量驱动零代码改动WeKnora 的服务端含桌面版统一使用 internal/logger/logger.go 中封装的 logrus 私有实例appLogger。之所以使用私有实例而非 logrus 全局 logger源码注释明确说明是为了避免外部依赖改写 logrus 全局状态导致日志丢失见 logger.go。整个配置链路非常简单进程启动时logger包的init()会调用一次ConfigureFromEnv()见 logger.gomain入口加载.env文件后会再次调用logger.ConfigureFromEnv()使环境变量生效桌面版见 cmd/desktop/main.go服务端同理。这保证了你写在.env或 shell 环境中的日志配置一定能被读取ConfigureFromEnv()内部依次完成关闭旧日志文件 → 解析LOG_LEVEL→ 解析LOG_PATH并打开文件 → 探测是否为 TTY → 解析LOG_FORMAT设置格式化器见 logger.go。核心环境变量一览来自 docs/日志配置.md变量是否必填默认值说明LOG_LEVEL否debug日志级别取值debug/info/warn(warning) /error/fatal无效值回退到debugLOG_PATH否空仅打到 stdoutmacOS.app打包模式下落到~/Library/Logs/AppName/AppName.log落盘路径启用后同时写 stdout 与该文件文件按 lumberjack 滚动单文件 50MB / 3 份 / 28 天 / 压缩归档LOG_FORMAT否空沿用内置默认格式自定义日志输出模板支持表 2 中的占位符终端颜色行为终端TTY环境下 ANSI 颜色自动启用非 TTY容器日志采集、docker logs重定向等会自动关闭颜色避免颜色控制字符污染日志聚合与检索系统。这一判断来自源码中对os.Stdout.Stat()的os.ModeCharDevice位检测见 logger.go。二、日志级别LOG_LEVEL取值与回退逻辑LOG_LEVEL用于控制全局日志输出阈值支持五个取值大小写不敏感源码中会先strings.ToLower取值对应 logrus 级别语义debugDebugLevel输出全部日志默认值开发排障首选infoInfoLevel输出信息级及以上warn/warningWarnLevel两种拼写均被接受errorErrorLevel仅输出错误级及以上fatalFatalLevel仅致命错误输出后会退出进程无效值回退到debug而不是常见的info。这一点容易在误填如拼写为WARNING以外的变体、或留了空格导致 trim 后为空时带来日志比预期多的意外但也能保证服务永远有足够日志可查。对应实现见 logger.go 的getLogLevelFromEnv()。级别还会影响输出染色在开启颜色的终端下DEBUG用青色、INFO用绿色、WARNING用黄色、ERROR用红色、FATAL用紫色见levelColorForlogger.go。三、日志落盘LOG_PATH文件滚动与双写机制设置LOG_PATH后日志同时输出到 stdout 与指定文件双写文件写入前会经过ansiStripWriter把 ANSI 颜色序列剥离保证落盘文件是纯文本便于 grep 与采集见 logger.go。文件滚动使用 lumberjack 实现参数硬编码在openLogFile()见 logger.go单文件上限MaxSize 50MB保留份数MaxBackups 3连同当前文件最多 4 个保留天数MaxAge 28天压缩归档Compress true滚动出的旧文件以 gzip 压缩日志文件所在目录会被自动创建os.MkdirAll(dir, 0o755)。macOS 桌面版特例若检测到可执行文件路径包含.app/Contents/MacOS即 Wails 打包的桌面应用即使不设置LOG_PATH日志也会默认写到~/Library/Logs/AppName/AppName.log其中AppName从.appbundle 名推断默认WeKnora Lite。判断逻辑见 logger.go 的defaultMacAppLogPath()。配置示例写入 shell 或.envexport LOG_LEVELinfo export LOG_PATH/var/log/weknora/weknora.log部署侧透传在 docker-compose.yml 中服务端容器已把这三个变量透传environment: # 日志 # 日志级别默认debug - LOG_LEVEL${LOG_LEVEL:-debug} # 日志文件路径留空则只输出 stdoutLLM_DEBUG_LOG 开启时同目录写 llm_debug.log - LOG_PATH${LOG_PATH:-} # 自定义日志格式模板留空用内置默认格式 - LOG_FORMAT${LOG_FORMAT:-}对应的 .env.example 也给出了注释模板Docker 部署时只需在.env中按需开启即可。注意LOG_PATH需要容器内的路径可写建议配合 volume 挂载持久化否则重启容器后日志会丢失。四、默认日志格式与历史行为一致LOG_FORMAT为空时使用内置默认格式源码中CustomFormatter.Template为空串即走默认分支见 logger.go。终端开启颜色时的默认输出形如INFO [2026-05-21 10:20:30.123] [req-abc k1v1] file.go:42[fn] | message body各段含义段来源说明INFO日志级别颜色模式下按级别染色[2026-05-21 10:20:30.123]时间戳格式2006-01-02 15:04:05.000毫秒精度[req-abc k1v1]结构化字段其中request_id即req-abc优先输出并蓝色高亮其余字段如k1v1按键名升序排列error字段值红色高亮file.go:42[fn]caller 信息格式文件名:行号[函数名]由addCaller在打日志时通过runtime.Caller注入见 logger.gomessage body消息正文logger.Info(c, ...)等 API 传入的正文调用方可以通过logger.WithField(c, key, value)/logger.WithFields(c, fields)向 context 注入结构化字段如租户 ID、知识库 ID这些字段会进入默认格式的[...]段便于日志采集系统做 K/V 索引。需要说明的是WithField/WithFields修改的是 context 中携带的 logger通过types.LoggerContextKey存取见 logger.go。五、自定义模板LOG_FORMAT六个占位符与精确染色设置非空LOG_FORMAT后进入模板模式内置的六个占位符如下占位符含义%d时间戳2006-01-02 15:04:05.000%level日志级别DEBUG/INFO/WARNING/ERROR/FATAL开启颜色时仅此占位符被染色%thread当前 goroutine ID。未引用该占位符时不会调用runtime.Stack无额外开销%loggercaller 信息file.go:line[func]过长时从末尾截取后 50 字符%traceId请求 ID即上下文中的request_id%msg消息正文 剩余结构化字段keyvalue按 key 升序拼接官方示例export LOG_FORMAT[%d] %level %thread %logger %traceId | %msg输出终端开启颜色时仅%level段着色[2026-05-21 10:20:30.123] INFO 17 service.go:88[Handle] req-abc | hello extraok模板模式的实现细节与注意事项从 logger.go 的模板格式化分支可以确认以下关键行为它们直接关系到你在生产环境能否放心使用模板单趟替换无级联污染占位符替换使用strings.NewReplacer完成单趟扫描。前一个占位符的值即使包含其它占位符字面串例如某字段值恰好是%msg也不会被二次替换。对应回归测试TestFormat_TemplateNoCascadingReplace见 logger_test.go用request_id %msg验证输出恰为%msgactual-msg。级别染色只发生在%level位置ANSI 颜色在%level替换阶段直接注入不会误染消息正文中字面出现的INFO/ERROR等字符串。这是修复过的一处 bug——旧实现对整行做 ReplaceAll 会把正文里的INFO一并染色回归测试TestFormat_ColorDoesNotPolluteMessage见 logger_test.go断言输出中绿色开序列恰好只有 1 处。%thread的零开销设计ConfigureFromEnv()会预先计算threadNeeded strings.Contains(tmpl, %thread)并缓存到CustomFormatter见 logger.go。只有模板引用了%thread时才会在每条日志中调用getGoroutineID()底层是runtime.Stack见 logger.go未引用时完全不触发避免高吞吐日志场景下不必要的性能损耗。%logger截断caller 超过 50 字符时从末尾截取后 50 字符保留文件名与行号丢弃过长的包前缀。结构化字段只能拼在%msg之后模板模式下logger.WithField/WithFields注入的字段会被统一拼接到%msg占位符末尾keyvalue升序暂不支持把任意字段抽出为独立占位符。若需要把特定字段如租户 ID作为独立 K/V 供日志系统结构化检索请直接关闭LOG_FORMAT使用默认格式——默认格式会把字段放入独立的[...]段。%traceId的来源它读取日志 entry 的request_id字段该字段由logger.WithRequestID(c, requestID)注入到 context见 logger.go。服务端中间件通常会为每个 HTTP 请求生成request_id并注入因此默认格式与模板中都能用它串联一条请求的完整链路。六、进阶LLM 调试日志LLM_DEBUG_LOG除了上述三个基础变量源码中还提供了一份独立于主日志的LLM 调试日志实现于 internal/logger/llm_logger.go用于完整记录每次模型调用的入参/出参对排查 RAG 问答、Agent 工具调用问题非常有用启用方式LLM_DEBUG_LOGtrue写LOG_PATH同目录的llm_debug/子目录或LLM_DEBUG_LOG指定目录留空/false/0关闭见 llm_logger.go。目录解析规则优先LOG_PATH所在目录下的llm_debug/其次 macOS.app日志目录最后当前工作目录下的llm_debug/。文件组织同一request_id的多次模型调用追加到同一个request_id.log文件无request_id时以时间戳命名。每条记录包含调用类型Chat/Chat Stream/Embedding/Rerank/VLM、模型名、耗时、分段内容消息列表、工具调用、错误等并以分隔线分块见formatRecordllm_logger.go。自动清理启动时启动一个 goroutine删除目录中7 天前的调试文件见 llm_logger.go。在 docker-compose.yml 与 .env.example 中同样预留了该变量的透传与注释。七、实操常见场景配置组合场景一开发调试终端直接运行保持默认即可获得最详细日志与终端颜色export LOG_LEVELdebug ./weknora server # 或 go run ./cmd/server场景二Docker 容器部署 日志采集容器内建议关闭颜色、控制级别并将日志写到 stdout 由 Docker 引擎采集或落盘挂载卷# .env LOG_LEVELinfo LOG_PATH/data/logs/weknora.log LOG_FORMAT配合docker-compose.yml的环境变量透传重启容器即生效。场景三按需保留结构化 K/V 检索需要按租户、知识库等字段过滤日志时不要设置LOG_FORMAT使用默认格式并在业务代码中通过logger.WithFields(c, logger.Fields{tenant_id: tid, kb_id: kb})注入字段采集端即可按tenant_idxxx检索。场景四排查 LLM 调用问题LLM_DEBUG_LOGtrue LOG_PATH/var/log/weknora/weknora.log模型调用的完整记录会写入/var/log/weknora/llm_debug/request_id.log。八、验证与回归测试用例如何兜底internal/logger/logger_test.go 中针对本主题的核心行为都有自动化用例兜底可作为配置正确性的依据TestFormat_DefaultModeUnchanged默认格式必须包含级别前缀、毫秒时间戳、request_id、k1v1字段与 callerlogger_test.goTestFormat_TemplateReplacesAllPlaceholders模板模式下六个占位符全部被替换且无残留字面量logger_test.goTestAnsiStripWriter落盘文件剥离 ANSI 序列纯文本可检索logger_test.go染色与级联替换的回归测试见上文第四节。小结WeKnora 的日志配置秉持环境变量驱动、零代码改动的设计原则LOG_LEVEL控制阈值与染色、LOG_PATH控制双写与滚动归档、LOG_FORMAT控制输出模板。深入源码可以看到其在性能%thread惰性求值、正确性单趟替换防级联、局部染色防误染与采集兼容性非 TTY 去色、落盘剥离 ANSI上的精细考量。按本文的配置组合与实践注意事项即可在开发、Docker 部署与日志采集环境中获得清晰、可检索、可回溯的日志体系。【免费下载链接】WeKnoraOpen-source LLM knowledge platform: turn raw documents into a queryable RAG, an autonomous reasoning agent, and a self-maintaining Wiki.项目地址: https://gitcode.com/GitHub_Trending/we/WeKnora创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考