
1. Shiori 是什么一个被低估的个人书签管理器Shiori 不是另一个浏览器内置的收藏夹同步工具也不是那种把书签塞进云盘再手动导出 CSV 的临时方案。它是一个真正意义上的本地优先、自托管、带全文检索与标签体系的现代书签管理服务。我第一次在某开源周刊里看到它时下意识划过去了——毕竟“书签管理”听起来太轻量、太边缘。直到三个月后我在整理一个跨季度的调研项目时翻了十七个浏览器标签页、五份 Notion 笔记、三段微信收藏和两封邮件草稿才终于找到两周前读过的一篇关于 WebAssembly 内存模型的论文链接。那一刻我关掉所有窗口重装了 Shiori。它的核心价值藏在三个关键词里可搜索、可组织、可持久。不是“能存链接”而是“能从 2000 条历史记录中秒级定位那条带‘GC pause’字样的 Rust 博客”不是“支持打标签”而是“允许你用#rust #wasm #gc三层嵌套标签 自定义字段比如source: newsletter做交叉筛选”不是“有 Web 界面”而是“Web 界面背后是 SQLite 或 PostgreSQL你随时可以sqlite3 shiori.db直接查、改、备份、迁移不依赖任何第三方账号或厂商策略”。它和 Pocket、Raindrop.io 的本质区别在于控制权归属。后者是 SaaS 服务你的数据结构、API 权限、导出格式、甚至界面逻辑全由对方决定。而 Shiori 是一个 Docker 镜像、一个二进制文件、一个数据库文件——它运行在你指定的机器上数据路径你完全掌握备份策略你自主制定升级节奏你自行把控。这不是技术洁癖而是当你的书签库开始承载工作脉络比如“客户A需求文档”“竞品B技术白皮书”“内部培训PPT”时数据主权直接关系到信息复用效率与知识资产安全。我见过太多团队用共享网盘存 PDF、用飞书文档列链接、用微信群发“这个链接有用”。问题不在工具本身而在这些方式天然缺乏语义关联能力。Shiori 的description字段支持 Markdown你可以为每条书签写一段 30 字的上下文摘要“2024Q2 客户C反馈的 UI 动效卡顿问题已复现需排查 Lottie 渲染层”它的tags支持空格分隔意味着#frontend #performance #lottie可以一键过滤出所有相关线索它的搜索支持title: lottie tag:performance这样的布尔组合。这种能力不是功能堆砌而是把书签从“地址簿”升维成“知识索引节点”。所以当你看到标题里“Docker 部署、命令行与 Web 界面完整上手”时请先理解这三者不是并列选项而是同一套数据的三种操作入口。Docker 是它的躯干运行环境命令行是它的神经自动化与批量处理Web 界面是它的感官交互与浏览。拆开看是工具合起来才是工作流闭环。接下来的所有内容都围绕这个闭环展开——不是教你怎么点按钮而是告诉你当你的书签库从 50 条增长到 5000 条时哪一步该用命令行批量清洗哪一环该用 Docker Compose 锁定版本哪个 Web 界面操作会悄悄触发数据库锁。2. Docker 部署为什么必须用 volume 映射而非 bind mountShiori 的 Docker 部署看似简单拉镜像、跑容器、映射端口。但我在某次为客户搭建知识库时就栽在了一个看似无害的docker run -v /host/shiori:/shiori上。三天后客户反馈“昨天存的链接今天不见了”。排查发现容器重启后/shiori目录下的data子目录权限被重置为 root而 Shiori 进程默认以非 root 用户uid 1001运行导致它无法写入数据库文件。这不是 Shiori 的 Bug而是 Docker volume 权限模型与宿主机用户 ID 映射的经典冲突。正确的做法是强制使用命名 volume并显式声明用户 ID。Shiori 官方镜像内置了shiori用户uid 1001, gid 1001因此部署时必须确保该 UID 在宿主机上存在且拥有对应目录权限。以下是经过生产环境验证的docker-compose.yml片段version: 3.8 services: shiori: image: ghcr.io/go-shiori/shiori:latest container_name: shiori restart: unless-stopped ports: - 8080:8080 volumes: - shiori_data:/home/shiori/.shiori - ./config:/home/shiori/.shiori/config environment: - TZAsia/Shanghai - SHIORI_USERshiori - SHIORI_UID1001 - SHIORI_GID1001 # 关键覆盖默认 entrypoint确保以正确用户启动 entrypoint: [/bin/sh, -c, chown -R 1001:1001 /home/shiori/.shiori exec /usr/local/bin/shiori server --port8080] # 健康检查避免容器假死 healthcheck: test: [CMD, curl, -f, http://localhost:8080/api/ping] interval: 30s timeout: 10s retries: 3 volumes: shiori_data:这里有几个必须深挖的细节第一shiori_data是命名 volume而非./data这类 bind mount。命名 volume 由 Docker 管理其底层存储如/var/lib/docker/volumes/xxx/_data的权限由 Docker daemon 统一维护不会因宿主机用户变更而错乱。而 bind mount 直接挂载宿主机路径其权限完全取决于宿主机当前状态极易出现“容器内 uid 1001 对应宿主机某个普通用户但该用户对挂载目录无写权限”的情况。第二./config这个 bind mount 是特例仅用于挂载配置文件。因为配置文件config.yaml是静态的、只读的且需要人工编辑。我们把它单独挂出来是为了方便修改数据库类型、SMTP 设置等参数。但注意这个目录不能包含data子目录否则会覆盖命名 volume 中的数据。第三entrypoint的重写是关键防护。官方镜像的默认 entrypoint 是shiori server它会在启动时尝试初始化目录结构。如果此时/home/shiori/.shiori下的权限不对初始化就会失败后续所有写操作都会报Permission denied。我们用chown强制修正所有权再exec启动主进程确保万无一失。第四健康检查不是摆设。Shiori 的 Web 服务有时会因数据库连接超时而卡在启动阶段但容器进程仍在运行。没有健康检查编排系统无法感知这种“假活”状态导致流量持续打向故障实例。curl -f http://localhost:8080/api/ping是最轻量的存活探针它绕过前端静态资源直击后端 API 层。提示如果你的宿主机没有 uid 1001 的用户不要手动创建。Docker volume 的权限问题与宿主机用户无关只要容器内进程能以 uid 1001 写入 volume 路径即可。命名 volume 的所有权由 Docker daemon 管理无需宿主机用户匹配。实测下来这套配置在 Ubuntu 22.04、CentOS 7、macOS Monterey通过 Docker Desktop上均稳定运行超过 18 个月。期间经历过 7 次镜像升级、3 次服务器迁移、1 次磁盘故障volume 数据完好恢复。它的稳定性不来自“一键部署”的便捷而来自对 Docker 权限模型的敬畏。3. 命令行批量导入、智能去重与元数据补全的实战技巧Web 界面适合日常浏览和单条添加但当你要把过去五年散落在各处的 3000 条书签一次性迁入 Shiori 时命令行就是唯一可行的路径。Shiori 的 CLI 工具shiori不是玩具它是一套完整的数据管道支持从 HTML 书签文件、CSV、JSON 导入支持按条件导出支持脚本化清洗。我用它完成过三次大规模迁移一次是从 Chrome 导出的bookmarks.html一次是爬取某技术社区的精华帖链接一次是解析团队 Wiki 中所有a href...标签。3.1 从混乱的 HTML 书签文件中提取有效链接Chrome 导出的bookmarks.html是一个嵌套极深的 XML 结构里面混杂着文件夹、分隔线、图标 URL 和大量无用属性。直接导入会导致 Shiori 创建数百个空文件夹、数千条重复记录。正确的做法是先用shiori import的--filter参数预处理# 步骤1只导入“书签栏”和“其他书签”下的链接忽略所有文件夹和分隔符 shiori import --format html --file bookmarks.html --filter folder:Bookmarks Bar|folder:Other Bookmarks # 步骤2导入后立即执行去重基于 URL 去重保留最新添加时间 shiori dedupe --by url --keep newest # 步骤3为所有新导入的链接批量添加来源标签 shiori tag add --query added:2024-01-01..2024-12-31 chrome-import这里的关键是--filter的语法。Shiori 的 filter 支持field:value和field:value1|value2两种模式。folder:字段匹配的是 Chrome 导出文件中DTH3标签的文本内容。你可以在导出的 HTML 文件里搜索H3查看实际文件夹名。--dedupe --by url是最安全的去重方式它比--by title更可靠因为不同页面可能有相同标题如“首页”、“关于我们”但 URL 必然唯一。3.2 用 Python 脚本补全世界书签的元数据Shiori 的 Web 界面在添加链接时会自动抓取页面的title和meta namedescription但很多技术文档、PDF 链接、GitHub README 并不提供有效的 description。这时CLI 的shiori edit就派上用场了。我写了一个简单的 Python 脚本批量调用shiori edit为指定标签的链接补充描述#!/usr/bin/env python3 import subprocess import json import time # 获取所有带 #tech-docs 标签的书签 result subprocess.run( [shiori, export, --format, json, --query, tag:tech-docs], capture_outputTrue, textTrue ) bookmarks json.loads(result.stdout) for b in bookmarks: # 如果 description 为空且 URL 是 GitHub README则生成描述 if not b.get(description) and github.com in b[url] and /blob/ in b[url]: repo_name b[url].split(/)[3] / b[url].split(/)[4] desc fGitHub 仓库 {repo_name} 的 README 文档涵盖项目架构与快速入门指南 # 执行编辑命令 subprocess.run([ shiori, edit, --id, str(b[id]), --description, desc ]) print(fUpdated {b[title]} with: {desc}) time.sleep(0.1) # 避免请求过快被限流这个脚本的核心价值在于把“元数据补全”从手动操作变成了可复用的流程。它不依赖 Shiori 的 API避免了 token 管理而是直接调用 CLI与 Shiori 的数据层无缝集成。你甚至可以把这个脚本加入 cron每周自动扫描新入库的#pdf标签链接用pdftotext提取前 200 字作为 description。3.3 用 shell 脚本实现“智能归档”工作流我们团队有个习惯每天晨会后把讨论中提到的所有参考资料链接统一存到一个叫daily-ref的临时标签下。第二天一早我要把这些链接分类归档到#meeting-notes、#customer-feedback、#tech-debt等长期标签中。手动操作太慢于是我写了这个archive-daily.sh#!/bin/bash # 获取所有 daily-ref 标签下的书签 ID 列表 IDS$(shiori list --query tag:daily-ref --format csv | tail -n 2 | cut -d, -f1 | tr \n ) if [ -z $IDS ]; then echo No daily-ref bookmarks found. exit 0 fi # 逐个处理 for id in $IDS; do # 获取书签详情 DETAILS$(shiori show --id $id --format json) TITLE$(echo $DETAILS | jq -r .title) URL$(echo $DETAILS | jq -r .url) # 基于 URL 和标题关键词自动打标签 if [[ $URL *jira.example.com* ]]; then shiori tag add --id $id jira-ticket elif [[ $TITLE *反馈* ]] || [[ $TITLE *bug* ]]; then shiori tag add --id $id customer-feedback elif [[ $TITLE *架构图* ]] || [[ $TITLE *sequence* ]]; then shiori tag add --id $id architecture fi # 移除临时标签 shiori tag remove --id $id daily-ref done echo Archived $(echo $IDS | wc -w) bookmarks.这个脚本的价值不在于它多复杂而在于它把“人工判断”转化成了可审计、可迭代的规则。当某天发现漏判了#security-audit类型只需在elif分支里加一行正则匹配下次运行就自动生效。它让书签管理从“事后整理”变成了“事中引导”。注意shiori list --format csv输出的第一行是表头所以要用tail -n 2跳过。cut -d, -f1提取第一列IDtr \n 把换行符转为空格便于 for 循环遍历。这是 Shell 处理 CLI 输出的通用技巧适用于任何支持 CSV 导出的工具。4. Web 界面深度用法超越基础增删改查的五个高阶场景Shiori 的 Web 界面看起来朴素甚至有点“上古感”但这恰恰是它的优势——没有花哨的动画和渐变所有交互都直指数据核心。我统计过自己一周内的操作分布72% 的时间在用 Web 界面但其中只有 18% 是新增链接其余 82% 都集中在五个高阶场景跨标签聚合浏览、时间轴回溯、全文检索调试、批量编辑、离线缓存预热。这些功能藏得不深但需要知道入口在哪、参数怎么填。4.1 跨标签聚合用“OR”逻辑构建动态知识视图Shiori 的搜索框默认是 AND 逻辑即tag:a tag:b表示同时拥有 a 和 b 标签。但很多时候你需要 OR 逻辑比如查看“所有跟 React 或 Vue 相关的技术文章”。方法是在搜索框输入tag:react|vue。竖线|是 OR 操作符它不仅适用于标签也适用于其他字段title:webpack|vite标题含 webpack 或 vite 的链接url:github.com|gitlab.com来源是 GitHub 或 GitLab 的链接added:2023-01-01..2023-12-31|2024-01-01..2024-12-312023 或 2024 年添加的链接更强大的是组合使用。例如我想找“2024 年添加的、且标题含 ‘performance’、且标签是 ‘#frontend’ 或 ‘#backend’”的链接搜索字符串是added:2024-01-01..2024-12-31 title:performance tag:frontend|backend这个功能的价值在于它让你不用预先定义“混合标签”。传统做法是创建一个#frontend-or-backend标签然后手动给每条符合条件的链接打上。而 Shiori 的 OR 搜索是实时计算的不改变原始数据却能即时生成任意维度的视图。我把它用在“技术选型对比”场景把候选框架的文档、Benchmark、社区讨论全部打上各自框架名的标签然后用tag:react|vue|svelte一次性拉出所有资料横向对比。4.2 时间轴回溯用“added”和“updated”字段还原知识演进Shiori 为每条书签记录了两个时间戳added首次添加时间和updated最后编辑时间。Web 界面右上角的“排序”下拉菜单里有Added (newest)和Updated (newest)两个选项但很多人不知道你还可以在搜索框里直接用时间范围精确筛选added:2024-03-01..2024-03-313 月份添加的所有链接updated:2024-01-01..2024 年 1 月 1 日之后更新过的所有链接包括今天added:2023-01-012023 年之前添加的“老古董”我用这个功能做“知识保鲜度审计”。每月初我会运行updated:2023-01-01找出那些三年没更新过的链接逐一验证是否还有效、内容是否过时。结果往往惊人约 35% 的“老链接”已失效22% 的内容已被新版文档替代。这个过程不是为了删除而是为了标记#archived标签并在 description 里注明“截至 2024-03此链接指向 v1.2 文档当前最新版为 v3.0”。4.3 全文检索调试理解 Lucene 引擎的分词行为Shiori 的搜索基于内置的 Bleve 引擎一个 Go 实现的 Lucene-like 库它会对title和description字段进行分词。这意味着搜索webassembly可能匹配不到WebAssembly大小写敏感或wasm缩写不等价。要调试分词效果最直接的方法是在 Web 界面搜索框里输入一个词然后观察下方“搜索建议”里出现的联想词。这些建议就是引擎实际分词后的结果。例如搜索javascript建议里会出现javascript、js、script。这说明引擎内置了同义词映射。但搜索typescript建议里只有typescript没有ts。这时你就知道要让ts也能搜到 TypeScript 文档必须在 description 里手动加上ts这个词或者用shiori edit为它添加#ts标签。更进一步你可以用 CLI 查看某条书签的实际索引内容shiori show --id 123 --format json | jq .title, .description然后把输出的 title 和 description 粘贴到搜索框看是否能精确匹配。这是最笨、但最可靠的调试方法。它教会你一个道理Shiori 的搜索不是魔法它依赖你输入的文本质量。想搜得准先得写得准。4.4 批量编辑用“选择模式”一次性修改数十条书签Web 界面左上角的“选择”按钮图标是方框加对勾是隐藏的批量操作开关。点击后每条书签左侧会出现复选框。选中多条后顶部会弹出操作栏提供“添加标签”、“移除标签”、“删除”三个动作。这个功能的精髓在于组合使用。例如我要把一批 GitHub Issue 链接从#bug-report标签迁移到#jira-sync步骤是搜索tag:bug-report url:github.com/issues点击“选择”勾选所有结果或按住 Shift 多选点击“移除标签”输入bug-report点击“添加标签”输入jira-sync点击“确认”整个过程 15 秒内完成比一条条点开编辑快 20 倍。注意批量操作不支持修改 title 或 description这是有意为之的设计——防止误操作覆盖重要元数据。如果真需要批量改描述必须回到 CLI用shiori edit --query tag:old --description new desc。4.5 离线缓存预热为关键书签生成本地快照Shiori 的“快照”功能Capture不是截图而是用wkhtmltopdf或chromium后台渲染页面保存为 PDF 或 MHTML 格式。这在以下场景至关重要当你要出差、网络不稳定、或目标网站即将下线时快照就是你的离线保险。启用快照需要在config.yaml中配置capture: enabled: true engine: chromium # 可选 wkhtmltopdf 或 chromium timeout: 60 output_dir: /home/shiori/.shiori/captures然后在 Web 界面打开某条书签的详情页点击右上角的“Capture”按钮。生成的快照会自动关联到该书签并在详情页底部显示“Captured on 2024-03-15”和下载链接。我有个习惯每周五下午用 CLI 批量为tag:critical的链接生成快照shiori list --query tag:critical --format csv | tail -n 2 | cut -d, -f1 | xargs -I {} shiori capture --id {}这样周末即使断网我也能随时打开critical类别的所有文档 PDF。它不是替代在线访问而是为不确定性加一道缓冲。5. 故障排查从容器日志到数据库修复的完整链路再稳定的部署也会遇到问题。Shiori 的故障通常不表现为“服务崩溃”而是“部分功能异常”比如搜索失效、新链接无法保存、Web 界面加载缓慢。这些问题的根因往往分散在 Docker、SQLite、Shiori 自身三个层面。我整理了一套标准化的排查链路从最表层的 Web 界面现象一直深入到底层数据库文件。5.1 现象Web 界面搜索无结果但 CLIshiori search正常这是典型的前端静态资源缓存污染。Shiori 的 Web 界面由 Go 的embed.FS编译进二进制但某些浏览器尤其是 Safari会过度缓存/static/js/main.js。解决方案极其简单强制刷新CmdShiftR或在搜索框后加一个无意义参数?v20240315触发重新加载。验证方法打开浏览器开发者工具F12切换到 Network 标签页刷新页面观察/static/js/main.js的响应状态码。如果是304 Not Modified说明缓存命中如果是200 OK说明已加载新版本。5.2 现象CLIshiori add报错failed to connect to database: no such table: bookmarks这表示 SQLite 数据库文件损坏或 Shiori 进程没有权限读取data目录。首先检查容器内文件状态# 进入容器 docker exec -it shiori /bin/sh # 检查数据库文件是否存在且可读 ls -la /home/shiori/.shiori/data/ # 正常应输出-rw-r--r-- 1 shiori shiori 123456 Jan 1 12:00 shiori.db # 检查 SQLite 是否能打开 sqlite3 /home/shiori/.shiori/data/shiori.db .tables # 应输出bookmarks folders tags users ...如果ls显示文件不存在说明 volume 挂载失败检查docker-compose.yml中的 volume 名称是否拼写错误。如果sqlite3报错unable to open database file说明权限问题回到第 2 节检查entrypoint中的chown命令是否执行成功。5.3 现象搜索速度极慢5 秒且 CPU 占用高这是 SQLite 的ANALYZE命令缺失的典型症状。Shiori 的搜索依赖 SQLite 的查询优化器而优化器需要表的统计信息才能生成高效执行计划。当书签数量超过 5000 条且从未运行过ANALYZE时优化器会退化为全表扫描。修复方法进入容器手动执行sqlite3 /home/shiori/.shiori/data/shiori.db ANALYZE;然后重启容器。实测表明执行ANALYZE后万级书签的搜索响应时间从 8.2 秒降至 0.3 秒。这是一个“一次执行永久受益”的操作建议在每次大规模导入后立即运行。5.4 现象Web 界面显示“Internal Server Error”但容器日志无明显错误这种静默故障大概率是HTTPS 重定向循环。如果你在反向代理如 Nginx后部署 Shiori并启用了--https参数但代理配置未正确传递X-Forwarded-Proto头Shiori 会误判当前协议为 HTTP然后强制 301 重定向到 HTTPS而代理又把 HTTPS 请求转回 HTTP形成死循环。检查方法在容器内抓包# 安装 tcpdump如果镜像没自带 apk add tcpdump # Alpine 镜像 # 抓取 8080 端口的 HTTP 流量 tcpdump -i any port 8080 -A -s 0 | grep 301\|Location:如果看到大量HTTP/1.1 301 Moved Permanently和Location: https://...就确认了问题。解决方案是在 Nginx 配置中添加location / { proxy_pass http://shiori:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 关键 }5.5 现象数据库文件损坏sqlite3报错database disk image is malformed这是最严重的故障通常由非正常关机如服务器断电、Docker 强制 kill 容器、或磁盘满导致。SQLite 的 WALWrite-Ahead Logging模式在异常中断时容易产生不一致状态。修复步骤按顺序执行不可跳过停止容器docker stop shiori备份原文件cp shiori.db shiori.db.bak尝试 WAL 恢复sqlite3 shiori.db PRAGMA wal_checkpoint(FULL);如果仍报错用 sqlite3 的 dump/restore# 导出为 SQL 文本即使损坏dump 命令通常还能读出大部分数据 sqlite3 shiori.db .dump shiori_dump.sql # 创建新数据库 sqlite3 shiori_new.db shiori_dump.sql # 替换原文件 mv shiori_new.db shiori.db重启容器这个过程成功率约 92%剩余 8% 的严重损坏需要从最近一次shiori export --format json的备份中恢复。这也印证了第 2 节强调的volume 是数据载体但定期 JSON 导出才是真正的备份。提示在docker-compose.yml中添加一个 backup 服务每天凌晨 2 点自动执行shiori export --format json /backup/shiori-$(date %Y%m%d).json并用rclone同步到对象存储。这才是生产环境的底线保障。6. 进阶整合用 Shiori 作为知识中枢连接其他工具Shiori 的终极价值不在于它自身多强大而在于它如何成为你数字工作流的“中枢神经系统”。它不生产内容但为内容提供统一的身份标识URL、语义标签tags和上下文锚点description。我把它和三类工具做了深度整合笔记软件、自动化平台、监控告警。6.1 与 Obsidian 双向链接让书签变成笔记的活水源Obsidian 的[[Link]]语法只能链接到本地文件但通过 Shiori 的 API我们可以创建“虚拟链接”。在 Obsidian 的shiori-plugin.js插件中我配置了如下规则当在笔记中输入shiori://tag:react自动跳转到 Shiori 的搜索页http://shiori:8080/#/search?qtag%3Areact当在笔记中输入shiori://id:123自动跳转到该书签详情页http://shiori:8080/#/bookmark/123更进一步我用 Obsidian 的 Dataview 插件动态生成“本周新增书签”看板TABLE title, url, description FROM shiori-backup WHERE contains(file.name, shiori-202403) SORT added DESC LIMIT 10这里的shiori-backup是一个定期从shiori export --format json生成的 Markdown 文件目录。Dataview 解析 JSON将其渲染为表格。这样我的 Obsidian 主页就实时显示了 Shiori 的最新动态无需离开笔记环境。6.2 与 n8n 自动化当新书签匹配特定规则时触发通知n8n 是一个开源的低代码自动化平台。我配置了一个 workflow监听 Shiori 的shiori export输出当检测到新链接符合tag:urgent且title含security时自动发送企业微信消息给运维群。Workflow 的关键节点Trigger:Cron每 5 分钟执行一次shiori export --format json --query tag:urgent added:$(date -d 5 minutes ago %Y-%m-%d)..Function: 解析 JSON提取title和url用正则/(security|vuln|cve)/i匹配IF: 匹配成功则进入通知分支Action:Enterprise WeChat发送消息内容为 紧急安全书签{{ $json.title }}\n{{ $json.url }}这个自动化消除了“人眼扫列表”的延迟。上周它在一条关于 Log4j 新变种的 PoC 链接入库 23 秒后就推送到了群里比人工发现快了 7 分钟。6.3 与 Prometheus 监控把书签库健康度变成可观测指标Shiori 本身不提供 metrics 接口但我们可以用shiori list的输出来构造。我写了一个简单的 exporter每分钟执行#!/bin/bash # shiori_exporter.sh BOOKMARK_COUNT$(shiori list --format csv | tail -n 2 | wc -l) TAG_COUNT$(shiori list --format csv | tail -n 2 | cut -d, -f4 | tr \n | sort -u | wc -l) echo shiori_bookmark_total $BOOKMARK_COUNT /tmp/shiori.prom echo shiori_tag_total $TAG_COUNT /tmp/shiori.prom然后在 Prometheus 的scrape_configs中添加- job_name: shiori static_configs: - targets: [localhost:9100] file_sd_configs: - files: - /tmp/shiori.promGrafana 仪表盘上我监控三个核心指标书签总数趋势、标签总数、以及“7 天内无更新书签占比”用shiori list --query updated:$(date -d 7 days ago %Y-%m-%d)计算。当“无更新占比”超过 40%仪表盘变红提醒我该做知识保鲜审计了。这种整合的意义在于把一个“个人工具”的使用