Skip to content
dsh.fish
Bundle

dsh-plugin-log-forwarder

DeepSeek Harness 实时日志转发插件:将 Agent 运行事件实时转发到 WebSocket / Loki / 本地文件

Source
zhaoxuejie
License
MIT
Updated
Updated 5 hours ago

Readme

# dsh-plugin-log-forwarder

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) ![Node.js ≥ 20](https://img.shields.io/badge/Node-%E2%89%A520-brightgreen) ![Version 1.0.4](https://img.shields.io/badge/Version-1.0.4-blue)

[English](README.en.md) | **简体中文**

DeepSeek Harness 实时日志转发插件:把 Agent 运行时的全部事件**实时**转发到外部日志系统(**WebSocket / Loki / 本地文件**),可用于外部页面实时监控 Agent 的每一步思考与工具执行,适合调试、监控、演示场景。

> 仓库:<https://github.com/zhaoxuejie/dsh-plugin-log-forwarder>

## 特性总览

| 能力 | 说明 |
|---|---|
| 全量事件采集 | 订阅 Harness 会话事件流(`session/created`、`session/event`、`session/disposed`、`agent/error`),标准化为统一 JSON |
| 三路并行输出 | WebSocket / Loki / 本地文件三个通道互不依赖,**可同时启用** |
| 事件过滤 | `includeEventTypes` 白名单(优先)与 `excludeEventTypes` 黑名单 |
| 敏感信息脱敏 | 递归、大小写不敏感;默认脱敏 `api_key` / `password` / `token` / `secret` 等字段 |
| 暂停 / 恢复 | 全局暂停(停止采集,WebSocket Server 保持在线),可经 Agent 工具或面板按钮操作 |
| 通道监控 | 每个通道实时展示运行状态与转发 / 失败 / 丢弃统计 |
| 旁路设计 | 只读转发、不干预 Agent 运行;卸载时干净关闭全部连接与缓冲,无残留 |

工作原理(拓扑):

```
DeepSeek Harness 会话事件流
  (session/created · session/event · session/disposed · agent/error)
        │ 订阅
        ▼
dsh-plugin-log-forwarder —— 标准化 → 脱敏 → 过滤 → 实时分发
        │
        ├─► websocket   ws://127.0.0.1:18765(状态页 / 多客户端广播)
        ├─► file        *.jsonl 按会话落盘(路径支持 {sessionId})
        └─► loki        POST /loki/api/v1/push(批量 / 缓冲 / 退避重试)
                        └─► Loki ⇄ Grafana(Explore / Live / 图表)
```

## 运行效果

<p align="center">
  <img src="docs/snapshot/demo2-websocket.png" width="49%" alt="WebSocket 通道:实时事件流"/>
  <img src="docs/snapshot/demo1-set.png" width="49%" alt="DSH 设置 → 日志转发器面板"/>
</p>
<p align="center">
  <img src="docs/snapshot/demo3-Loki.png" width="49%" alt="Grafana Explore 检索 Loki 日志"/>
  <img src="docs/snapshot/demo4-Loki.png" width="49%" alt="Grafana × Loki:查询另一视角"/>
</p>

<p align="center"><sub>左:WebSocket 实时事件流 · 右上:设置面板(通道开关 / 统计 / 暂停 / 恢复)· 下排:Grafana 查询 Loki 日志</sub></p>

---

## 快速开始

### 0. 前置条件

- 已安装并正常启动 DeepSeek Harness(桌面版或 headless)。
- 知道当前使用的 profile 目录:`~/.dsh/profiles/<profile>`(Windows 为 `%USERPROFILE%\.dsh\profiles\<profile>`)。下文统一用 `desktop` 代指,请替换成你自己的。
- Node.js ≥ 20(仅在本地构建时需要)。

### 1. 安装插件(任选一种)

#### 方式一:源码 + 目录链接 —— 不依赖发布、可改源码

```bash
git clone https://github.com/zhaoxuejie/dsh-plugin-log-forwarder.git
cd dsh-plugin-log-forwarder
npm install     # 安装依赖(@deepseek-ai/cordis 等)
npm run build   # 生成 lib/(构建产物不入库,需自行生成)
```

把插件链接进 profile 的 `node_modules`,让 Harness 能按包名解析到它:

- Windows(PowerShell,使用目录联接):
  ```powershell
  New-Item -ItemType Junction -Path "$env:USERPROFILE\.dsh\profiles\desktop\node_modules\dsh-plugin-log-forwarder" -Target "D:\path\to\dsh-plugin-log-forwarder"
  ```
- macOS / Linux(软链接):
  ```bash
  ln -s /path/to/dsh-plugin-log-forwarder ~/.dsh/profiles/desktop/node_modules/dsh-plugin-log-forwarder
  ```

#### 方式二:官方命令安装(非源码,推荐)

DeepSeek Harness 自带插件管理命令(等价于在 profile 目录执行 `pnpm add`)。包**发布到 npm 后**直接安装:

```bash
dsh plugin --profile desktop add dsh-plugin-log-forwarder    # desktop 换成你的 profile
```

尚未发布到 npm 时,下面两种替代同样可用(都能被 pnpm 解析):

```bash
# 替代一:直接装 GitHub 仓库(pnpm 会自动执行 prepare 构建 lib/)
dsh plugin --profile desktop add github:zhaoxuejie/dsh-plugin-log-forwarder

# 替代二:本地打 tgz 再安装(npm pack 经 prepare 自动构建,tgz 已含 lib/)
npm pack                                        # 仓库内,产出 dsh-plugin-log-forwarder-1.0.4.tgz
dsh plugin --profile desktop add D:/path/to/dsh-plugin-log-forwarder-1.0.4.tgz
```

> 方式二安装后插件即生效(默认只开 WebSocket 通道)。包自带 `dsh.bundle.patch`(仓库根 `cordis.patch.yml`),profile 引用时自动合并默认配置;要打开 file / loki 或调整参数,按下面「2. 启用插件」粘贴覆盖配置即可。

### 2. 启用插件

> 方式一(源码目录链接)需在下面手动声明;方式二(`dsh plugin add`)会自动合并内置默认配置、开箱即用。下面这段用于**自定义通道参数**(如打开 file / loki、改端口),两种安装方式下直接粘贴均可,与默认配置合并、不会冲突。

编辑 profile 的补丁配置 `~/.dsh/profiles/desktop/cordis.patch.yml`,在 `- insert:` 列表中追加:

```yaml
- insert:
    - id: log-forwarder
      name: dsh-plugin-log-forwarder
      config:
        enable: true          # 插件总开关
        autoStart: true       # 加载后立即开始转发
        channels:
          websocket:
            enable: true      # WebSocket 通道
            port: 18765       # 绑定 127.0.0.1;被占用自动 +1(最多 5 次)
          file:
            enable: false     # 本地文件通道
            path: ''          # 路径模板;空 → ~/.deepseek-harness/logs/session-<id>.jsonl
            maxFileSizeBytes: 52428800
          loki:
            enable: false     # Loki 通道
            url: 'http://localhost:3100'
            tenantId: ''      # 多租户时必填(X-Scope-OrgID)
            token: ''         # 可选,Bearer Token
            bufferSize: 1000  # 内存缓冲上限,超出丢最旧
            maxConsecutiveFailures: 10
        filter:
          includeEventTypes: []   # 白名单,空 = 全部
          excludeEventTypes: []
        redaction:
          enable: true
          sensitiveFields: [api_key, apikey, password, token, secret, authorization]
```

只声明 `- id: / name:` 而不写 `config` 也可以,未配置项会用内置默认值(默认只开 WebSocket,其余通道默认关闭)。

### 3. 重启并验证

**重启 DSH Desktop / 重新加载插件**——通道只在插件加载时装配,配置没有热加载。

验证(任选其一):

```bash
# 浏览器打开内置状态页(实时事件流 + 暂停/恢复按钮)
start http://127.0.0.1:18765/

# 命令行实时观察事件流
npx wscat -c ws://127.0.0.1:18765
```

或直接对 Agent 说「查看日志转发状态」——插件会注册 4 个模型工具(见下文)。

---

## 三个通道怎么用

每个通道的详细配置、验证命令与进阶用法见 **[docs/usage.md](docs/usage.md)**(含可复制的 PowerShell / LogQL 命令),这里只给要点。

### WebSocket —— 实时调试 / 外部监控页

- 默认地址 `ws://127.0.0.1:18765`,多客户端广播;`http://127.0.0.1:18765/` 为内置状态页。
- 每条消息是一个标准化事件 JSON,例如:

```json
{
  "id": "evt_0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d",
  "timestamp": "2026-09-09T08:46:37.372Z",
  "sessionId": "session_1",
  "turnIndex": 4,
  "type": "tool_call",
  "payload": {
    "turn": 4,
    "step": 3,
    "callId": "call_1",
    "name": "shell",
    "arguments": { "command": "ls -la" }
  }
}
```

- REST 控制端点(暂停 / 恢复 / 清空统计等)与客户端接入示例见 [docs/api.md](docs/api.md)。

### File —— 本地 JSONL 归档

- `path` 含 `{sessionId}` 占位符则**按会话分文件**,不含则所有会话聚合写入同一文件。
- 默认目录:`~/.deepseek-harness/logs/session-<id>.jsonl`,每行一个事件 JSON。
- 提示:sessionId 本身已带 `session-` 前缀,模板请直接用 `{sessionId}.jsonl`,不要写成 `session-{sessionId}.jsonl`(会得到 `session-session-…` 双重前缀)。

### Loki —— 集中检索 + Grafana 可视化

- 通道向 `{url}/loki/api/v1/push` 批量推送(攒满 100 条或 200ms 触发),标签固定为 `source` / `session_id` / `event_type` / `turn_index`。
- 网络失败自动指数退避重试;**连续失败达 `maxConsecutiveFailures`(默认 10)** 后通道标记 `disconnected` 停止重试,需手动恢复(对 Agent 说「恢复日志转发」,即 `log_forwarder_resume`)。
- Grafana 查看示例:

```logql
{source="dsh-log-forwarder"}
{source="dsh-log-forwarder", session_id="session_1"}
{source="dsh-log-forwarder", event_type="tool_call"}
```

---

## 模型工具

插件向 Agent 注册以下工具,也可直接写在会话里让 Agent 代为执行:

| 工具 | 作用 |
|---|---|
| `log_forwarder_status` | 全局状态:是否运行、事件总数、各通道转发/失败/丢弃统计 |
| `log_forwarder_channel_status` | 单通道详情(`channel: websocket\|file\|loki`),含输出目标 |
| `log_forwarder_pause` | 暂停转发(停止采集,WebSocket Server 保持在线) |
| `log_forwarder_resume` | 恢复转发;同时重连断开的 Loki、重试启动失败的 WebSocket |

自然语言示例:「查看日志转发状态」「暂停日志转发」「恢复日志转发」。

## 事件类型

事件会被映射为 `session_start` / `user_input` / `turn_start` / `reasoning` / `model_output` / `tool_call` / `tool_result` / `tool_error` / `turn_end` / `session_end` / `error` 等标准类型;无法映射的原始事件按原类型名透传(容错不丢失)。完整映射表与 payload 字段见 [docs/api.md](docs/api.md)。

## 内置侧边面板(可选)

插件自带标准 Harness 客户端面板(`src/client/`,随包构建进 `lib/client.js`):在 Harness 设置的「日志转发器」分区展示实时事件与通道统计,并提供暂停 / 恢复 / 清空按钮。宿主侧无需额外改动即可显示;实时推送增强等开发细节见 [docs/api.md](docs/api.md)。

## 常见问题

| 现象 | 处理 |
|---|---|
| 改了配置但通道没变化 | 插件只在加载时读取配置,请重启 DSH / 重新加载插件 |
| Loki 通道 `disconnected` | 对 Agent 说「恢复日志转发」,或工具面板点「恢复转发」 |
| WebSocket 端口被占用 | 插件自动尝试 `+1`(最多 5 次),以状态页显示的端口为准 |
| 收到 `session-session-…` 文件名 | file 路径模板应为 `{sessionId}.jsonl`,不要带 `session-` 前缀 |
| 想筛选 / 脱敏 | 配置 `filter` 与 `redaction`(见「快速开始 §2」) |
| 需要更多可复制命令 | 详见 [docs/usage.md](docs/usage.md)(含 pause/resume 实测行为、Loki 验证、Grafana 操作) |
| 如何发布新版本 | 详见 [docs/RELEASING.md](docs/RELEASING.md)——推 `v*` tag 即自动 npm 发布 + GitHub Release |

## 开发与测试(贡献者)

```bash
npm install
npm run typecheck         # 宿主侧类型检查
npm run typecheck:client  # 客户端面板类型检查
npm run build             # 编译宿主侧到 lib/
npm run build:client      # 打包客户端面板 → lib/client.js
npm test                  # 独立验证脚本(18 项用例)
```

## 文档

- [docs/usage.md](docs/usage.md) — 通道使用指南(三通道配置 / 验证命令 / Grafana 查看 / FAQ)
- [docs/api.md](docs/api.md) — 接口文档(配置项、事件格式、HTTP 端点、模型工具)
- [docs/PRD.md](docs/PRD.md) — 产品需求文档(V1.0)
- [docs/RELEASING.md](docs/RELEASING.md) — 发布指南(维护者:tag 自动发布 / 手动兜底 / 排障)
- [CHANGELOG.md](CHANGELOG.md)

## 许可

MIT © 2026

Install

dsh plugin --profile web add github:zhaoxuejie/dsh-plugin-log-forwarder

Profile: web

  • This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source