☰
Remotely Save 插件调试指南:从同步计划导出到控制台日志的完整排查方案
2026/9/26 6:46:44 网站建设 项目流程
  • 数据同步

【免费下载链接】remotely-save

Sync notes between local and cloud with smart conflict: S3 (Amazon S3/Cloudflare R2/Backblaze B2/...), Dropbox, webdav (NextCloud/InfiniCLOUD/Synology/...), OneDrive, Google Drive (GDrive), Box, pCloud, Yandex Disk, Koofr, Azure Blob Storage.

项目地址:https://gitcode.com/gh_mirrors/re/remotely-save
点击查看免费下载

理想情况下,Remotely Save 插件的同步应当是"零维护"的:配置好远程服务后,自动同步会静默完成一切。但一旦出现文件丢失、冲突异常或同步停滞,用户就必须深入细节定位根因。本指南围绕仓库docs/how_to_debug/目录下的四篇调试文档,按"由易到难"的四个层级,系统讲解如何在 Obsidian 桌面端、iOS 与 Android 移动端上排查 Remotely Save 的同步问题:先导出并解读同步计划(Sync Plans),再通过控制台日志观察插件内部行为,最终借助第三方插件拿到移动端的完整日志。读完本文,你将掌握一套完整的、可操作的插件侧调试流程,并能理解同步计划中每个关键字段的含义。

调试手段按难度分为四档,对应原文档 docs/how_to_debug/README.md 的整体结构:

难度场景手段详细文档
简单全平台通用导出同步计划(Sync Plans)docs/how_to_debug/export_sync_plans.md
中等桌面端与 Android直接查看 Obsidian 控制台docs/how_to_debug/check_console_output.md
中等移动端(iOS / Android)使用Obsidian vConsole插件查看控制台docs/how_to_debug/check_vconsole_output.md
高级全平台,尤其 iOS使用Logstravaganza插件把日志导出到笔记docs/how_to_debug/use_logstravaganza.md

第一层(简单):导出同步计划,定位"决策是否正确"

什么是同步计划

每次插件启动一次同步时,都会先收集所有必要信息,为每个文件、每个文件夹生成一个"同步计划"(sync plan):它列出针对每个对象的每一项操作,并分配对应的实际动作。换言之,同步计划是插件在动手之前"想清楚要做什么"的完整决策记录。

因此,如果同步出了问题,第一步应当检查同步计划——先确认插件"打算做什么",再判断是决策错了,还是执行阶段出了问题。这能从源头上把问题区间缩小一半。

导出同步计划的操作步骤

  1. 首先关闭自动同步。进入插件设置,关闭自动同步(auto sync),避免调试过程中有意外同步任务插队运行,干扰观察结果。
  2. 确保至少手动同步过一次。同步计划只有在同步发生时才会生成并保存。如果此前从未同步过当前 vault,请先手动触发一次同步,让插件产生至少一份计划;如果此前已经同步过,插件通常已保存了若干历史同步计划,可直接进入下一步。
  3. 导出到文件。进入插件设置,向下滚动到 "Debug"(调试)分区,找到 "Export sync plans"(导出同步计划)选项并点击导出按钮。插件会在 vault 根目录下新建一个_debug_remotely_save/文件夹,并在其中生成一份名为sync_plans_hist_exported_on_{时间戳}.md的文件。

说明:原文档中该文件名写作sync_plans_hist_exported_on_{a_timestamp},md.,其中包含笔误。仓库源码 src/baseTypes.ts 明确给出常量定义:DEFAULT_DEBUG_FOLDER = "_debug_remotely_save/"、DEFAULT_SYNC_PLANS_HISTORY_FILE_PREFIX = "sync_plans_hist_exported_on_",因此实际生成的文件名为sync_plans_hist_exported_on_{时间戳}.md,扩展名是.md。

导出按钮的多个选项(源码细节)

在 src/settings.ts 的 Debug 分区实现中,"Export sync plans" 并非只有一个按钮,而是提供了五个导出按钮,对应不同的导出范围:

按钮调用参数含义
导出最近 1 条(仅变更)howMany=1, onlyChange=true只导出最近 1 条计划,且仅保留有变更的对象
导出最近 5 条(仅变更)howMany=5, onlyChange=true只导出最近 5 条计划,仅保留有变更的对象
导出最近 1 条(全部)howMany=1, onlyChange=false导出最近 1 条计划的完整内容
导出最近 5 条(全部)howMany=5, onlyChange=false导出最近 5 条计划的完整内容
导出全部howMany=0导出历史中全部同步计划

这些按钮均调用 src/debugMode.ts 中的exportVaultSyncPlansToFiles函数。该函数从本地数据库读取同步计划历史记录(readAllSyncPlanRecordTextsByVault),随后拼接成 Markdown 文件写入 vault。其中onlyChange=true时,会通过getSubsetOfSyncPlan过滤掉change === false的对象(/$@meta元数据条目始终保留),只输出发生过变更的文件/文件夹,便于快速聚焦问题点;若历史记录为空,文件内容则只有一行提示 "No sync plans history found"。

如何阅读同步计划

用任意 Markdown 编辑器打开导出的sync_plans_hist_exported_on_{时间戳}.md,里面是一个或多个 JSON 代码块,每个 JSON 代表一次同步计划。典型的计划结构如下:

{ "ts": 1646960867560, "remoteType": "onedrive", "mixedStates": { "abc.md": { "key": "abc.md", "existRemote": true, "mtimeRemote": 1646566632000, "sizeRemote": 56797, "remoteEncryptedKey": "abc.md", "changeMtimeUsingMapping": true, "existLocal": true, "mtimeLocal": 1646566632000, "sizeLocal": 56797, "decision": "skipUploading", "decisionBranch": 1 }, "New folder/": { "key": "New folder/", "deltimeRemote": 1646925354372, "existLocal": false, "existRemote": false, "decision": "keepRemoteDelHistFolder", "decisionBranch": 9 } } }

顶层字段中,ts是该次同步的时间戳(Unix 毫秒),remoteType是远程服务类型(示例中为onedrive,实际可能是s3、webdav、dropbox等,对应 src/baseTypes.ts 中定义的各种远程类型)。

排查时通常只需要关心mixedStates属性:其中的每一项代表一个文件或一个文件夹,键名(如"abc.md"、"New folder/")就是其在同步体系中的唯一标识(key)。这与源码 pro/src/sync.ts 中SyncPlanType = Record<string, MixedEntity>的类型定义一致——同步计划本质上就是"路径 key → 实体状态 MixedEntity"的映射表。

找到你怀疑出问题的那个文件/文件夹,然后重点核对以下属性:

decision 插件对该文件/文件夹做出的决策。 decisionBranch 同步代码中实际逻辑分支的标记编号,用于调试定位走到了哪一条判断路径。 existRemote 该文件/文件夹是否存在于远程服务上。 mtimeRemote 远程服务上的"最后修改时间"。 deltimeRemote 远程记录中的"删除时间"。 existLocal 该文件/文件夹是否存在于本地。 mtimeLocal 本地的"最后修改时间"与"创建时间"二者中的较大值。 deltimeLocal 本地的"删除时间"。

这些字段与 src/baseTypes.ts 中MixedEntity接口的成员一一对应,还包括sizeLocal/sizeRemote(本地与远程文件大小)、sizeLocalEnc/sizeRemoteEnc(加密场景下的大小)、remoteEncryptedKey(远程加密后的键名)、changeRemoteMtimeUsingMapping/changeLocalMtimeUsingMapping(是否使用映射机制改写时间戳)以及syncDone等。其中,mtimeLocal的定义值得注意——它不是单纯的最后修改时间,而是"修改时间与创建时间的最大值",这是 Remotely Save 为兼容不同文件系统时间戳行为而采取的策略。

decision 与 decisionBranch:决策从何而来

decision应当由修改时间与删除时间共同决定,逻辑详见 同步算法文档。简而言之:插件会收集四个时间戳(mtimeRemote、deltimeRemote、mtimeLocal、deltimeLocal),以四个时间戳中的最大值对应的那个操作作为最终决策。

例如示例中的"abc.md":mtimeRemote与mtimeLocal相等(均为 1646566632000),existRemote与existLocal均为 true,于是插件判定两侧内容一致,做出skipUploading(跳过上传)的决策,decisionBranch为 1。

decisionBranch是一个纯调试用的整数编号,指向 pro/src/sync.ts 中具体的判断分支。源码中可见decisionBranch从 1、2、9、26 一直到 101~138 等大量取值,每一档都对应一套"存在性 × 时间戳大小关系"的组合。当向开发者报告 bug 时,同时提供decision和decisionBranch能极大加速问题定位。

常见问题:操作系统时间戳异常

一些用户反馈,其操作系统的"最后修改时间"或"创建时间"没有被正确设置。在这种情形下,插件无能为力——因为同步计划完全建立在时间戳比较之上,时间戳本身不可信,一切决策都会失真。建议此时检查操作系统的相关设置,或者排查是否有其他程序在偷偷改动文件(例如同步盘客户端、备份软件、杀毒软件对文件的触碰等)。

第二层(中等):桌面端与 Android 直接查看 Obsidian 控制台

如果你在桌面端(Windows / Linux / macOS)或 Android 上使用 Obsidian,可以直接打开 Obsidian 的控制台查看插件日志。

步骤 1:先关闭自动同步

与导出同步计划一样,调试前先禁用自动同步,避免意外同步任务干扰日志观察。

步骤 2:把日志级别改为 debug

进入插件设置,向下滚动到 "Debug" 分区,找到 "alter console log level"(调整控制台日志级别)选项,将其从默认的info改为debug。

这一设置在源码 src/settings.ts 中实现为settings_debuglevel下拉框,提供info与debug两个选项,选择结果写入this.plugin.settings.currLogLevel并持久化保存。切换为debug后,插件会输出更细粒度的调试日志,覆盖同步过程中的中间状态与详细决策过程。

步骤 3:打开控制台并触发同步

桌面端(Windows / Linux / macOS):按下快捷键Ctrl+Shift+I(Windows / Linux)或Cmd+Shift+I(macOS),即可打开 Obsidian 的开发者控制台。console.info、console.debug等输出都会显示在这里。

Android:有两种方式查看控制台:

  • 借助桌面 Chrome 查看:首先在 Android 手机上启用 USB 调试(USB debugging,需在系统开发者选项中开启),然后用 USB 线连接手机与电脑;在桌面 Chrome 浏览器中打开特殊页面chrome://inspect,该页面内会出现可用的 "inspect" 链接,点击即可打开手机端 Obsidian 的控制台。调试完毕后,记得关闭 USB 调试以保障设备安全。
  • 直接在手机上查看:参考下一节的Obsidian vConsole方案,见 docs/how_to_debug/check_vconsole_output.md。

控制台就绪后,点击侧边栏 Ribbon 上的同步图标手动触发一次同步。控制台中会出现(但愿是)有用的输出,据此可以更直观地判断发生了什么、哪里出了问题。

第三层(中等):移动端使用Obsidian vConsole查看控制台

在手机上调试相当困难——既没有桌面端的 DevTools 快捷键,网络请求也不易抓取。好在有第三方插件Obsidian vConsole可以帮忙,它适用于 iOS(iPhone / iPad)和 Android 两端。

步骤 1:先关闭自动同步

与前述一致,调试前先禁用自动同步。

步骤 2:把日志级别改为 debug

同样进入插件设置 "Debug" 分区,把 "alter console log level" 从info改为debug。

步骤 3:安装并启用Obsidian vConsole

  1. 安装第三方插件Obsidian vConsole(可在 Obsidian 社区插件市场搜索安装)。
  2. 启用该插件后,Obsidian 移动端界面右下角会出现一个绿色按钮,可以拖拽到任意位置。
  3. 触发同步,然后立刻点击这个绿色按钮,其面板中会展示控制台日志!更妙的是,面板里还能查看浏览器网络请求(Network)和本地存储(LocalStorage)——当怀疑远程请求失败或配置存储异常时,这两项非常有用。
  4. 每条日志行旁有一个小的"磁盘"图标,点击即可复制该条日志;也可以直接截图。将日志或截图提交给 Remotely Save 的 GitHub 仓库来报告 bug。不需要看日志时,点击面板中的 "Hide" 即可隐藏面板。
  5. 调试结束后,如果不再需要,可禁用Obsidian vConsole插件,绿色按钮随之消失。

第四层(高级):使用Logstravaganza把日志导出到笔记

在 iOS 上直接查看控制台日志相当困难,此时可以借助第三方插件Logstravaganza(作者 Carlo Zottmann)——它能把控制台输出重定向写入一篇笔记中,让日志"落地"为可检索、可复制的文本。

使用方法非常简单:

  1. 在 Obsidian 社区插件市场安装Logstravaganza。
  2. 启用它。
  3. 做点操作,触发一些控制台日志(例如手动触发一次同步)。
  4. 打开 vault 根目录下的LOGGING-NOTE (设备名).md,即可看到被重定向写入的日志内容。

由于它不依赖屏幕取词或 DevTools,在 iOS 上尤为实用:把日志以笔记形式保存后,既可以直接在 Obsidian 内阅读、搜索,也可以方便地复制出来提交给开发者。该方案的详细说明见 docs/how_to_debug/use_logstravaganza.md。

调试路径速查与小结

面对一次同步异常,推荐的排查顺序是:

  1. 先看同步计划(全平台通用,成本最低):导出sync_plans_hist_exported_on_{时间戳}.md,核对问题文件/文件夹的decision、decisionBranch与四个时间戳字段,判断是"决策阶段"还是"执行阶段"出了问题;
  2. 再看控制台日志(桌面端 / Android 直接用 Obsidian 控制台,移动端用Obsidian vConsole或Logstravaganza):把日志级别调到debug,手动触发同步,观察插件实际执行的调用链与报错;
  3. 报 bug 时带上证据:导出文件、decisionBranch编号、控制台日志或截图一并提交,能显著提升开发者定位问题的效率。

以上所有调试入口均集中在插件设置的 "Debug" 分区,并在 src/settings.ts 中有完整实现;同步计划的生成与导出逻辑分别位于 pro/src/sync.ts 与 src/debugMode.ts。值得再次提醒的是:同步决策完全依赖操作系统提供的时间戳,若本地文件系统时间戳本身不准确,任何调试手段都无法得出正确结论——请先从操作系统层面确认时间戳的可靠性。

  • 数据同步

【免费下载链接】remotely-save

Sync notes between local and cloud with smart conflict: S3 (Amazon S3/Cloudflare R2/Backblaze B2/...), Dropbox, webdav (NextCloud/InfiniCLOUD/Synology/...), OneDrive, Google Drive (GDrive), Box, pCloud, Yandex Disk, Koofr, Azure Blob Storage.

项目地址:https://gitcode.com/gh_mirrors/re/remotely-save
点击查看免费下载
上一篇:Neo4j Graph Data Science 项目常见问题解决方案
下一篇:OpenChamber 1.0.1 首发解析:monorepo 架构、GitHub Actions 发布流水线与 OpenCode 聊天体验

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询