goose 日志与数据存储体系完全指南:会话记录、命令历史与系统日志的本地管理
【免费下载链接】goosean open source, extensible AI agent that goes beyond code suggestions - install, execute, edit, and test with any LLM项目地址: https://gitcode.com/GitHub_Trending/goose3/goose
goose 将 CLI 与桌面端的每一次对话、交互与组件运行日志统一存储在本机,形成"命令历史 + 会话记录 + 系统日志"三套互补的数据体系。本文以 logging system 文档 为核心,结合 路径解析源码、日志子系统实现 与 会话存储实现,完整说明这些数据的存放位置、文件组织方式、保留策略与底层原理,帮助你在排查问题、审计会话和备份数据时精准定位。
统一存储:所有交互数据都保存在本地
goose 使用一套统一的本地存储体系承载会话与交互数据。无论你通过 CLI 还是桌面应用使用 goose,会话与交互记录都会被持久化到本机固定目录中,且遵循平台惯例(通过etcetera的AppStrategy解析,应用名goose、厂商Block),具体位置如下表所示:
| 类型 | 类 Unix(macOS / Linux) | Windows |
|---|---|---|
| Command History(命令历史) | ~/.config/goose/history.txt | %APPDATA%\Block\goose\data\history.txt |
| Session Records(会话记录) | ~/.local/share/goose/sessions/sessions.db | %APPDATA%\Block\goose\data\sessions\sessions.db |
| System Logs(系统日志) | ~/.local/state/goose/logs/ | %APPDATA%\Block\goose\data\logs\ |
从源码看,这三类路径分别对应Paths::config_dir()、Paths::data_dir()与Paths::state_dir()三个解析入口(见 paths.rs)。在 Windows 上,etcetera的state_dir()不可用时实现会回退到data_dir()(paths.rs),因此 Windows 下日志被统一收纳到%APPDATA%\Block\goose\data\logs\。
隐私说明
goose 是本地应用,上述所有数据默认只保存在你的机器上,不会发送到任何外部服务器或第三方,日志数据始终在你的掌控之中。需要注意:goose 在你授权下调用的 LLM 与工具服务,可能有它们自己的日志与隐私策略,两者互不混淆。
路径的底层解析与自定义
路径解析核心位于 crates/goose/src/config/paths.rs。其中:
- 类 Unix 目录:
~/.config/goose、~/.local/share/goose、~/.local/state/goose分别由config_dir/data_dir/state_dir提供; - 厂商名兼容:源码注释明确指出
"Block"是刻意保留的兼容字符串,用于兼容历史版本已经创建的配置/数据目录(例如~/Library/Application Support/Block/goose/),避免升级后旧数据"失联"(paths.rs); - 自定义根目录:若设置了绝对路径环境变量
GOOSE_PATH_ROOT,则配置、数据、状态目录分别变为<GOOSE_PATH_ROOT>/config、<GOOSE_PATH_ROOT>/data、<GOOSE_PATH_ROOT>/state(paths.rs),这为在 CI、沙箱或便携场景中把整个 goose 数据目录收拢到一处提供了便利。
Command History:跨会话的命令记忆
goose 会持久化命令历史,从而在多次聊天会话之间记住你之前敲过哪些命令。命令历史文件的默认位置为:
- 类 Unix:
~/.config/goose/history.txt - Windows:
%APPDATA%\Block\goose\data\history.txt
它由 CLI 的输入层维护,位于配置目录中,与"会话内容"解耦——命令历史侧重记录交互输入本身,而真正的对话内容则交给下面的 Session Records。
Session Records:SQLite 数据库中的完整会话档案
存储位置与数据内容
goose 为每个会话维护完整的对话历史与交互记录,统一存放在一个 SQLite 数据库文件中:
- 类 Unix:
~/.local/share/goose/sessions/sessions.db - Windows:
%APPDATA%\Block\goose\data\sessions\sessions.db
该数据库包含了所有已保存的会话数据,从源码建表语句(session_manager.rs)可以精确对应文档描述的内容:
- 会话元数据:
id、name、working_dir、created_at/updated_at、session_type、project_id、parent_session_id、archived_at、goose_mode等; - 对话消息:
messages表按会话保存每条用户命令、助手响应、角色(role)与序列化内容(content_json),并建立session_id、timestamp、message_id索引以支持高效查询; - 工具调用与结果:消息内容中以结构化形式记录工具调用的 ID、参数与执行结果状态;
- Token 用量统计:
usage_ledger表按会话逐条记录model、input_tokens、output_tokens、total_tokens、cache_read_tokens/cache_write_tokens、cost以及是否为压缩产生的记录(is_compaction); - 扩展数据与配置:
sessions表通过extension_data、recipe_json、provider_name、model_config_json等字段保存扩展与应用配置。
数据库连接使用 WAL 日志模式(SqliteJournalMode::Wal)、开启外键约束并设置 30 秒忙等待超时(session_manager.rs),兼顾并发读写安全与一致性。
会话 ID 命名与查询
会话 ID 采用YYYYMMDD_<COUNT>格式,例如20250310_2。每次启动会话时,goose CLI 会在开头输出本次的会话 ID,方便你在多个并行会话中快速对应。
要列出所有可用会话,使用goose session list子命令(goose-cli-commands.md)。它支持以下选项:
| 选项 | 说明 | 示例 |
|---|---|---|
-f, --format <text\|json> | 指定输出格式,默认text | goose session list --format json |
--ascending | 按时间正序(旧在前)排列 | goose session list --ascending |
-w, --working_dir <path> | 按工作目录过滤会话 | goose session list -w ~/projects/myapp |
-l, --limit <number> | 只显示最近 N 个会话 | goose session list --limit 10 |
如需在会话内或会话间做文本检索,可以参考 会话管理指南。
从 .jsonl 到 SQLite:v1.10.0 的自动迁移
在v1.10.0 之前,goose 将会话记录以单个.jsonl文件形式存放在~/.local/share/goose/sessions/。升级到 v1.10.0 及以后版本后:
- goose 首次打开数据库时会检测
schema_version表是否存在(session_manager.rs); - 若数据库为空,则创建新 schema,并自动调用
import_legacy把旧.jsonl会话批量导入数据库; - 旧
.jsonl文件仍保留在磁盘上,但不再由 goose 管理,可视为只读归档。
即使导入失败,goose 也只会打印Failed to import some legacy sessions警告,而不会阻塞启动(session_manager.rs)。后续版本升级则通过带版本的 schema 迁移脚本平滑演进。
System Logs:组件日志与两周自动清理
goose 为 CLI、服务器(goosed守护进程)等组件分别记录日志。所有系统日志统一收敛到:
- 类 Unix:
~/.local/state/goose/logs/ - Windows:
%APPDATA%\Block\goose\data\logs\
其目录结构在设计上有两个关键约定(logging.rs):
- 按组件分子目录、按日期再细分:形如
logs/cli/2025-11-13/、logs/server/2025-11-13/,日期格式为%Y-%m-%d; - 两周自动清理:每次创建日志目录前会调用
cleanup_old_logs(component),删除该组件目录下修改时间超过 14 天的子目录(logging.rs),防止日志无限累积挤占磁盘。
当日志启用 提示注入检测 时,CLI 与服务器日志还会额外记录:
- 安全发现:携带唯一 ID,格式为
SEC-{uuid}; - 用户决策:与发现 ID 关联的允许(allow)/ 拒绝(deny)操作。
此外,扩展(Extension)可以自行选择在~/.local/state/goose/logs/下的子目录中记日志,具体子目录结构由各扩展的实现决定。
Desktop Application Log
桌面应用对自身运行过程维护一套独立日志,遵循平台惯例:
- macOS:
~/Library/Application Support/Goose/logs/main.log - Windows:
%APPDATA%\Block\goose\logs\main.log
需要注意的是:桌面应用只把"自身操作日志与状态数据"放在上述平台目录,真正的会话与对话内容依然写入标准的sessions.db(即上文 Session Records)。这意味着无论你通过 CLI 还是桌面应用与 goose 交互,对话历史都是一致的、可无缝衔接的。
CLI Logs
CLI 日志存放于:
- 类 Unix:
~/.local/state/goose/logs/cli/ - Windows:
%APPDATA%\Block\goose\data\logs\cli\
日志按日期分子目录(如cli/2025-11-13/),超过两周的子目录会被自动删除。CLI 会话日志中记录:
- 工具调用与返回结果;
- 命令执行细节;
- 会话标识符;
- 时间戳。
CLI 日志同样捕获扩展相关活动,包括:工具初始化、工具能力与 schema、扩展专属操作、命令执行结果、错误信息与调试信息、扩展配置状态以及扩展相关的协议信息。
从日志实现看,每个运行单元的日志文件名形如<时间戳>.log(若配置了会话名,则为<时间戳>-<名称>.log),文件内容默认包含日志级别、target、源码文件与行号;写入格式可切换为 JSON 或纯文本(logging.rs)。日志级别通过EnvFilter控制:若设置了RUST_LOG环境变量则直接采用;否则使用内置默认(mcp_client=info、goose=info,全局WARN兜底),再叠加各组件附加指令(logging.rs)。
Server Logs
服务器日志存放于:
- 类 Unix:
~/.local/state/goose/logs/server/ - Windows:
%APPDATA%\Block\goose\data\logs\server\
同样按日期分子目录(如server/2025-11-13/)并执行两周自动清理。Server 日志记录的是 goose 守护进程goosed的运行情况——该进程是运行在你机器上的本地服务组件,负责在 CLI、扩展与 LLM 之间进行通信调度。
Server 日志通常包含以下内容:服务器初始化细节、JSON-RPC 通信日志、服务器能力、协议版本信息、客户端与服务器交互、扩展加载与初始化、工具定义与 schema、扩展指令与能力、调试级传输信息、系统能力与配置、操作系统信息、工作目录信息、传输层通信细节、消息解析与处理信息、请求/响应周期、错误状态与处理,以及扩展初始化序列。
如何快速定位 CLI / Server 日志
排查问题时,可以按日期找到最新目录并查看其中的.log文件。类 Unix 环境下可参考:
# 查看最近一天 CLI 日志目录 ls -lt ~/.local/state/goose/logs/cli/ | head # 实时跟踪最新 CLI 日志文件 tail -f ~/.local/state/goose/logs/cli/$(date +%Y-%m-%d)/*.log # 查看 server 侧今天的日志 tail -n 200 ~/.local/state/goose/logs/server/$(date +%Y-%m-%d)/*.logLLM Request Logs:模型请求的原始往返记录
当 goose 与语言模型服务商通信时,会记录发送给 provider 的原始请求与响应数据,用于诊断模型行为与 token 消耗:
- 类 Unix:
~/.local/state/goose/logs/llm_request.*.jsonl - Windows:
%APPDATA%\Block\goose\data\logs\llm_request.*.jsonl
编号轮换机制
LLM 请求日志采用**编号轮换(numbered rotation)**机制,最多保留最近 10 次完整请求,对应文件llm_request.0.jsonl到llm_request.9.jsonl。底层实现在 providers/utils.rs:
LOGS_TO_KEEP = 10是保留数量的常量(utils.rs);- 每个请求开始时会先写入一个临时文件
llm_request.{uuid}.jsonl(Uuid::new_v4()生成请求 ID,见 utils.rs); - 请求完成(
finish)时,把已有文件依次后移:llm_request.0 → 1 → 2 …,然后把临时文件改名为llm_request.0.jsonl(utils.rs)。因此编号越小越新,llm_request.0.jsonl总是最近一次完成的请求; - 若将
logs_to_keep配置为 0,则直接删除临时文件、不保留请求日志。
每个日志文件都包含模型配置、输入负载、响应数据与 token 用量信息,与usage_ledger表中的统计形成可对照的原始证据链。会话诊断相关代码也会引用llm_request.0.jsonl(见 session/diagnostics.rs),把最近一次模型请求纳入诊断信息收集。
如果你要检查某次请求的原始负载,用文本查看最近的编号文件即可:
# 查看最近一次完整 LLM 请求 head -c 2000 ~/.local/state/goose/logs/llm_request.0.jsonl从源码理解日志层:tracing 与可观测性
CLI / Server 日志统一由共享的 tracing 订阅器(build_logging_subscriber)构建(logging.rs)。它把日志分三条路径输出:
- 文件层:写入按日期组织的组件目录,可选 JSON 或纯文本格式(纯文本包含源码文件信息,便于回溯代码位置);
- 控制台层:按配置输出到 stderr,使用 pretty 格式并附行号,便于开发调试时实时观察;
- 可选的可观测性层:在启用
otelfeature 时会挂接 OTLP 相关 layer,同时可能接入 langfuse 观察层(若配置存在则注册到日志体系)。
也就是说,你看到的cli/2025-11-13/目录、两周清理策略以及按会话/进程命名的时间戳日志文件,全部由这一套统一的prepare_log_directory+cleanup_old_logs机制产出;而 LLM 请求日志则走独立的RequestLog编号轮换通道。两者都落在~/.local/state/goose/logs/下,构成完整的本地可观测性栈。
实用排查速查表
下面把三套数据的关键信息汇总成一张速查表,方便日常运维与排障时对照:
| 数据 | 类 Unix 路径 | Windows 路径 | 保留策略 |
|---|---|---|---|
| 命令历史 | ~/.config/goose/history.txt | %APPDATA%\Block\goose\data\history.txt | 持续累积 |
| 会话数据库 | ~/.local/share/goose/sessions/sessions.db | %APPDATA%\Block\goose\data\sessions\sessions.db | 持续累积(含版本化迁移) |
| CLI 日志 | ~/.local/state/goose/logs/cli/ | %APPDATA%\Block\goose\data\logs\cli\ | 按日期分目录,超过两周自动删除 |
| Server 日志 | ~/.local/state/goose/logs/server/ | %APPDATA%\Block\goose\data\logs\server\ | 按日期分目录,超过两周自动删除 |
| LLM 请求日志 | ~/.local/state/goose/logs/llm_request.{0..9}.jsonl | %APPDATA%\Block\goose\data\logs\llm_request.{0..9}.jsonl | 轮换保留最近 10 次请求 |
| 桌面应用日志 | ~/Library/Application Support/Goose/logs/main.log | %APPDATA%\Block\goose\logs\main.log | 遵循平台约定 |
几个补充事实值得记住:
- 会话数据库使用 SQLite 的WAL 模式,运行期间可能出现
sessions.db-wal/sessions.db-shm伴随文件,属正常现象; - 若需在测试或隔离环境中验证日志行为,可通过绝对路径环境变量
GOOSE_PATH_ROOT重定向 config / data / state 三类根目录(见 paths.rs),从而在不污染真实用户目录的前提下做实验; - 会话列表、删除与检索能力由
goose session子命令族提供,具体选项可继续查阅 goose-cli-commands.md 中的 session 相关章节,以及在 会话管理指南 中了解基于内容的检索方式。
小结
goose 的日志与存储体系遵循"对话归数据目录、日志归状态目录、历史归配置目录"的清晰职责划分,并通过 SQLite 统一收敛会话内容、通过基于日期的目录与两周清理策略控制系统日志体积、通过llm_request.*.jsonl编号轮换保留最近 10 次模型请求原始记录。理解这套布局后,无论是排查一次失败的工具调用、审计某段对话、核对 token 消耗,还是做数据备份迁移,你都能在数秒内定位到对应的本地文件,让 goose 的运行状态对你完全透明。
【免费下载链接】goosean open source, extensible AI agent that goes beyond code suggestions - install, execute, edit, and test with any LLM项目地址: https://gitcode.com/GitHub_Trending/goose3/goose
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考