Compare commits
5 Commits
main
...
codex/wuyo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
82260e2517 | ||
|
|
ed7845be65 | ||
|
|
3c2320852b | ||
|
|
3e89996a49 | ||
|
|
0d12a94054 |
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
每台运行脚本的机器部署一份 Agent。Agent 只主动向产品平台发起 HTTP 请求,不需要为被监控机器开放入站端口。
|
每台运行脚本的机器部署一份 Agent。Agent 只主动向产品平台发起 HTTP 请求,不需要为被监控机器开放入站端口。
|
||||||
|
|
||||||
|
需要交给安装同事逐台执行时,请使用完整的
|
||||||
|
[《脚本监控 Agent 逐台接入操作手册》](../../docs/workflow/脚本监控Agent逐台接入操作手册.md)。
|
||||||
|
|
||||||
## 接入
|
## 接入
|
||||||
|
|
||||||
1. 在供应链中心的“脚本监控”页面点击“接入机器”,生成独立的 `agentId` 和 `agentToken`。
|
1. 在供应链中心的“脚本监控”页面点击“接入机器”,生成独立的 `agentId` 和 `agentToken`。
|
||||||
|
|||||||
963
furniture-3d-system/docs/workflow/脚本监控Agent逐台接入操作手册.md
Normal file
963
furniture-3d-system/docs/workflow/脚本监控Agent逐台接入操作手册.md
Normal file
@ -0,0 +1,963 @@
|
|||||||
|
# 脚本监控 Agent 逐台接入操作手册
|
||||||
|
|
||||||
|
适用对象:负责在各台脚本机器上安装、配置和验收监控 Agent 的同事。
|
||||||
|
|
||||||
|
适用版本:脚本监控 Agent `1.0.0`。
|
||||||
|
|
||||||
|
平台入口:供应链中心 → 脚本监控。
|
||||||
|
|
||||||
|
本文按“安装人员完全不了解产品平台代码和项目结构”编写。安装人员不需要取得产品平台源码、不需要理解 Git,也不需要登录代码仓库。
|
||||||
|
|
||||||
|
## 0. 开始前先确认
|
||||||
|
|
||||||
|
### 0.1 先选择一种接入方式
|
||||||
|
|
||||||
|
| 你的实际情况 | 选择 | 阅读范围 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 只需要监控普通脚本、Cron、PM2 或结果文件 | 标准 Agent | 按第 1~17 节操作,不需要阅读附录 A |
|
||||||
|
| 已经有影刀等专用采集程序,并且要由该程序直接推送应用和日志 | 自定义采集器 | 先读第 1~4 节,再由开发人员按附录 A 改造和验收 |
|
||||||
|
|
||||||
|
同一台机器、同一组 Agent 凭据只能有一个上报程序。禁止同时运行标准 `agent.mjs` 和自定义采集器,否则两个程序会互相覆盖脚本快照,页面数据会时有时无。
|
||||||
|
|
||||||
|
### 0.2 你应当拿到的资料
|
||||||
|
|
||||||
|
开始前必须具备:
|
||||||
|
|
||||||
|
1. 本手册;
|
||||||
|
2. 这台机器独立的 `agentId` 和 `agentToken`,或平台生成的完整配置;
|
||||||
|
3. 已确认的网络模式:内网、公网或自动;
|
||||||
|
4. 本机需要监控的脚本清单,至少包含脚本名称、用途、运行方式和计划;
|
||||||
|
5. 如果选择标准 Agent,能够在目标机器下载第 5 节的 4 个程序文件;
|
||||||
|
6. 如果选择自定义采集器,能够修改采集程序的开发人员和附录 A。
|
||||||
|
|
||||||
|
缺少独立凭据、脚本清单或网络信息时,不要自行猜测,也不要复制其他机器的配置,应联系平台负责人补齐后再开始。
|
||||||
|
|
||||||
|
### 0.3 本文中的称呼
|
||||||
|
|
||||||
|
- “平台”:`https://cp.jiansun.vip` 中的“供应链中心 → 脚本监控”;
|
||||||
|
- “平台负责人”:在平台创建机器、生成凭据并核对页面结果的人;
|
||||||
|
- “安装人员”:在目标 Windows 或 Linux 机器部署 Agent 的人;
|
||||||
|
- “Agent”:常驻在目标机器、主动向平台上报的程序;
|
||||||
|
- “脚本 key”:一个脚本在本机长期不变的唯一标识,不是脚本名称。
|
||||||
|
|
||||||
|
### 0.4 什么情况下算接入完成
|
||||||
|
|
||||||
|
标准 Agent 必须同时满足:前台启动明确显示上报成功、平台机器在线、平台脚本数量与本机清单一致、状态和最近结果符合实际、重启后 Agent 自动恢复。
|
||||||
|
|
||||||
|
自定义采集器必须同时满足:`/report` 返回 HTTP 200、平台显示全部脚本、至少一条真实 `/run` 记录可见、连续两个上报周期没有 400/401/403/404/405。只有业务明确要求平台手动运行时,才把 `/commands/claim` 作为完成条件。
|
||||||
|
|
||||||
|
## 1. 任务目标
|
||||||
|
|
||||||
|
每台运行脚本的机器都需要一个常驻上报进程:选择标准 Agent 时运行 `agent.mjs`,选择自定义采集器时由已有采集程序承担同一职责。上报进程主动向产品平台汇报:
|
||||||
|
|
||||||
|
- 机器是否在线,以及本次通过内网还是公网连接;
|
||||||
|
- 机器上配置或自动发现了哪些脚本、Cron、PM2 进程;
|
||||||
|
- 脚本最近一次运行状态、时间、耗时、退出码和结果摘要;
|
||||||
|
- 经明确授权的脚本,是否可以从平台点击“立即运行”。
|
||||||
|
|
||||||
|
Agent 只主动发起 HTTP 请求,目标机器不需要开放任何入站端口,也不需要把脚本文件上传到平台。
|
||||||
|
|
||||||
|
普通机器优先使用平台提供的 `agent.mjs`。影刀等工具如果使用自定义采集器直接调用平台 API,必须由能够修改采集程序的开发人员按附录 A 接入;不能沿用旧脚本监控项目的 WebSocket 或 `/api/agent/...` 接口。
|
||||||
|
|
||||||
|
## 2. 必须遵守的安全规则
|
||||||
|
|
||||||
|
1. 一台机器使用一套独立的 `agentId` 和 `agentToken`,禁止多台机器共用。
|
||||||
|
2. Token 由平台负责人单独发给安装人员,不得发到群聊、工单正文或普通文档。
|
||||||
|
3. `config.json` 不得提交到 Git;Linux 权限建议设为 `600`,Windows 只允许运行 Agent 的账号读取。
|
||||||
|
4. 配置中的 `command` 不得直接写密码、Token、数据库连接串等敏感信息,应从目标机器原有安全环境变量或私有配置读取。
|
||||||
|
5. 默认不要开启平台手动运行。只有已确认安全、可重复执行、不会等待人工输入的脚本,才允许设置 `"allowManualRun": true`。
|
||||||
|
6. 订单写入、库存调整、财务、删除、批量覆盖等高风险脚本,未经业务负责人书面确认,不得开放手动运行。
|
||||||
|
|
||||||
|
## 3. 平台负责人准备,安装人员只需核对
|
||||||
|
|
||||||
|
以下步骤由平台负责人执行,安装人员不需要登录平台管理页面。每接入一台机器,平台负责人都要单独执行一次:
|
||||||
|
|
||||||
|
1. 登录产品平台。
|
||||||
|
2. 打开“供应链中心 → 脚本监控”。
|
||||||
|
3. 点击“接入机器”。
|
||||||
|
4. 机器名称填写可识别名称,例如“杭州仓库脚本机 01”,不要只写“服务器”。
|
||||||
|
5. 选择网络模式:内网、互联网或自动。
|
||||||
|
6. 填写对应的平台地址。
|
||||||
|
7. 点击“生成 Agent 凭据”。
|
||||||
|
8. 立即复制完整配置,通过安全方式交给安装人员。
|
||||||
|
|
||||||
|
凭据只显示一次,关闭弹窗后不能再次查看当前 Token;遗失时应联系平台负责人重新生成,不能从数据库或日志中找回明文 Token。
|
||||||
|
|
||||||
|
安装人员收到配置后只核对三项:机器名称是否是本机、网络模式是否符合本机、`agentId`/`agentToken` 是否为非空占位符以外的真实值。不要把完整 Token 截图或转发到群聊。
|
||||||
|
|
||||||
|
## 4. 选择内网还是公网
|
||||||
|
|
||||||
|
| 机器网络情况 | `connectionMode` | `centerUrls` | 说明 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| 固定在公司/仓库内网,并能访问平台内网地址 | `intranet` | 只填 `intranet` | 推荐,所有上报只走内网 |
|
||||||
|
| 只能访问互联网 | `internet` | 只填 `internet` | 公网生产地址必须使用 HTTPS |
|
||||||
|
| 网络会在内外网之间切换 | `auto` | 内外网都填 | 优先内网,失败后再尝试公网 |
|
||||||
|
|
||||||
|
公网生产地址:
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://cp.jiansun.vip
|
||||||
|
```
|
||||||
|
|
||||||
|
内网地址由平台运维负责人提供,文档中的 `<平台内网地址>` 只是占位符,不能照抄。
|
||||||
|
|
||||||
|
已知机器长期只处于一种网络时,优先选择固定的 `intranet` 或 `internet`,避免 `auto` 每次先等待不可达地址超时。
|
||||||
|
|
||||||
|
公网机器在安装前先验证基础连通性。Windows PowerShell:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Invoke-RestMethod -Uri 'https://cp.jiansun.vip/api/health' -Method Get -TimeoutSec 15
|
||||||
|
```
|
||||||
|
|
||||||
|
Linux:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -fsS --max-time 15 https://cp.jiansun.vip/api/health
|
||||||
|
```
|
||||||
|
|
||||||
|
响应中应包含 `"success": true` 和 `"status": "healthy"`。这只证明机器能访问平台,不代表 Agent 凭据或上报数据已经正确;最终仍以第 10 节验收为准。内网机器的测试地址和端口由平台运维负责人提供。
|
||||||
|
|
||||||
|
不要在浏览器地址栏直接打开 `/api/internal/script-monitor/report` 判断接口是否正常:浏览器发送的是 GET,而上报接口只接受 POST,看到 405 属于测试方法错误。
|
||||||
|
|
||||||
|
## 5. 下载每台机器需要的文件
|
||||||
|
|
||||||
|
平台页面目前没有 Agent 安装包下载按钮。安装人员不需要取得整个产品平台项目,也不需要登录代码仓库;直接执行本节与你操作系统对应的下载命令即可。
|
||||||
|
|
||||||
|
当前受支持版本:`Agent 1.0.0`。
|
||||||
|
|
||||||
|
| 文件 | 固定下载地址 |
|
||||||
|
| --- | --- |
|
||||||
|
| `agent.mjs` | `http://git.1080p.hk/WuYongJie/furniture-3d-system-Wu/raw/commit/dc16d2b75c41a5009354ba56caf4c1517d77ccce/furniture-3d-system/agents/script-monitor/agent.mjs` |
|
||||||
|
| `run-script.mjs` | `http://git.1080p.hk/WuYongJie/furniture-3d-system-Wu/raw/commit/dc16d2b75c41a5009354ba56caf4c1517d77ccce/furniture-3d-system/agents/script-monitor/run-script.mjs` |
|
||||||
|
| `ecosystem.config.cjs` | `http://git.1080p.hk/WuYongJie/furniture-3d-system-Wu/raw/commit/dc16d2b75c41a5009354ba56caf4c1517d77ccce/furniture-3d-system/agents/script-monitor/ecosystem.config.cjs` |
|
||||||
|
| `config.example.json` | `http://git.1080p.hk/WuYongJie/furniture-3d-system-Wu/raw/commit/dc16d2b75c41a5009354ba56caf4c1517d77ccce/furniture-3d-system/agents/script-monitor/config.example.json` |
|
||||||
|
|
||||||
|
这些地址中的文件内容固定不变。下载服务当前只提供 HTTP,因此必须按下面的命令自动核对 SHA256;校验不通过时禁止运行文件。安装人员不需要理解地址中的项目和版本信息。
|
||||||
|
|
||||||
|
### 5.1 Windows PowerShell 一次下载并校验
|
||||||
|
|
||||||
|
以 PowerShell 打开目标机器,完整执行:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$agentDir = 'C:\furniture-script-monitor'
|
||||||
|
$baseUrl = 'http://git.1080p.hk/WuYongJie/furniture-3d-system-Wu/raw/commit/dc16d2b75c41a5009354ba56caf4c1517d77ccce/furniture-3d-system/agents/script-monitor'
|
||||||
|
$expectedHashes = @{
|
||||||
|
'agent.mjs' = '2C67D765F0BCFFE64B4BD1838A046D12DCCAFECDD51FAE7C92379C9DC19E0889'
|
||||||
|
'run-script.mjs' = '7168F227ED63E5EC6B05EF4D849709F3CB6BC6B89B9CB2186439F92ACE333207'
|
||||||
|
'ecosystem.config.cjs' = '1D03D8D15C39B358E5BF819B7C124FB9804FEFFB9CB239AB73561607E339F6D7'
|
||||||
|
'config.example.json' = '689D6A36180DACF5E63059B6FFE7BBD5F7CAF53AC3E8954776FA67B0F5410B5C'
|
||||||
|
}
|
||||||
|
|
||||||
|
New-Item -ItemType Directory -Path $agentDir -Force | Out-Null
|
||||||
|
foreach ($fileName in $expectedHashes.Keys) {
|
||||||
|
$targetPath = Join-Path $agentDir $fileName
|
||||||
|
Invoke-WebRequest -UseBasicParsing -Uri "$baseUrl/$fileName" -OutFile $targetPath
|
||||||
|
$actualHash = (Get-FileHash -Algorithm SHA256 -LiteralPath $targetPath).Hash
|
||||||
|
if ($actualHash -ne $expectedHashes[$fileName]) {
|
||||||
|
Remove-Item -LiteralPath $targetPath -Force
|
||||||
|
throw "$fileName 下载校验失败,已删除,请停止安装并联系平台负责人"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Copy-Item -LiteralPath "$agentDir\config.example.json" -Destination "$agentDir\config.json" -Force
|
||||||
|
Get-ChildItem -LiteralPath $agentDir
|
||||||
|
```
|
||||||
|
|
||||||
|
看到 5 个文件(包括复制出来的 `config.json`)且没有红色报错,才可以继续第 7 节填写配置。
|
||||||
|
|
||||||
|
### 5.2 Linux 一次下载并校验
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo mkdir -p /opt/furniture-script-monitor
|
||||||
|
sudo chown -R "$(id -un):$(id -gn)" /opt/furniture-script-monitor
|
||||||
|
cd /opt/furniture-script-monitor
|
||||||
|
|
||||||
|
base_url='http://git.1080p.hk/WuYongJie/furniture-3d-system-Wu/raw/commit/dc16d2b75c41a5009354ba56caf4c1517d77ccce/furniture-3d-system/agents/script-monitor'
|
||||||
|
curl -fL "$base_url/agent.mjs" -o agent.mjs
|
||||||
|
curl -fL "$base_url/run-script.mjs" -o run-script.mjs
|
||||||
|
curl -fL "$base_url/ecosystem.config.cjs" -o ecosystem.config.cjs
|
||||||
|
curl -fL "$base_url/config.example.json" -o config.example.json
|
||||||
|
|
||||||
|
sha256sum -c <<'EOF'
|
||||||
|
2c67d765f0bcffe64b4bd1838a046d12dccafecdd51fae7c92379c9dc19e0889 agent.mjs
|
||||||
|
7168f227ed63e5ec6b05ef4d849709f3cb6bc6b89b9cb2186439f92ace333207 run-script.mjs
|
||||||
|
1d03d8d15c39b358e5bf819b7c124fb9804feffb9cb239ab73561607e339f6d7 ecosystem.config.cjs
|
||||||
|
689d6a36180dacf5e63059b6ffe7bbd5f7caf53ac3e8954776fa67b0f5410b5c config.example.json
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cp config.example.json config.json
|
||||||
|
chmod 600 config.json
|
||||||
|
```
|
||||||
|
|
||||||
|
四行都显示 `OK` 才能继续安装。若目标机器不能访问 `git.1080p.hk`,停止下载并联系平台负责人通过公司文件传输渠道发送同版本文件;安装人员不需要自行寻找其他下载网站。负责人提供的压缩包不得包含任何机器已经填写过的 `config.json`。
|
||||||
|
|
||||||
|
需要的文件清单:
|
||||||
|
|
||||||
|
```text
|
||||||
|
agent.mjs
|
||||||
|
run-script.mjs
|
||||||
|
ecosystem.config.cjs
|
||||||
|
config.example.json
|
||||||
|
```
|
||||||
|
|
||||||
|
不要复制其他机器的 `config.json`。
|
||||||
|
|
||||||
|
运行环境要求:
|
||||||
|
|
||||||
|
- Node.js 20 或 22 LTS,最低不得低于 Node.js 18;
|
||||||
|
- Linux 建议安装 PM2 作为常驻进程管理器;
|
||||||
|
- Windows 建议使用任务计划程序在开机时启动 Agent;
|
||||||
|
- 目标机器需要能够主动访问所选平台地址。
|
||||||
|
|
||||||
|
下载完成后先检查 Node.js。Windows PowerShell:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
node --version
|
||||||
|
(Get-Command node).Source
|
||||||
|
```
|
||||||
|
|
||||||
|
Linux:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
node --version
|
||||||
|
command -v node
|
||||||
|
```
|
||||||
|
|
||||||
|
版本低于 18 或提示找不到 `node` 时,停止安装并联系本机管理员安装 Node.js 20/22 LTS;不要从不明网站下载运行环境。
|
||||||
|
|
||||||
|
## 6. 安装目录
|
||||||
|
|
||||||
|
推荐目录:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Linux: /opt/furniture-script-monitor
|
||||||
|
Windows: C:\furniture-script-monitor
|
||||||
|
```
|
||||||
|
|
||||||
|
Linux 示例:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo mkdir -p /opt/furniture-script-monitor
|
||||||
|
sudo chown -R <运行账号>:<运行账号组> /opt/furniture-script-monitor
|
||||||
|
chmod 700 /opt/furniture-script-monitor
|
||||||
|
```
|
||||||
|
|
||||||
|
Windows 请确认运行 Agent 的账号对安装目录、被监控脚本目录和结果文件有读取权限;需要手动运行时,还必须有执行权限。
|
||||||
|
|
||||||
|
## 7. 编写 `config.json`
|
||||||
|
|
||||||
|
将 `config.example.json` 复制为同目录的 `config.json`,再填入本机配置。
|
||||||
|
|
||||||
|
如果平台负责人已经发来本机完整配置,就用该内容覆盖新建的 `config.json`;不要把配置内容粘贴进 Word、聊天软件富文本或 Markdown 链接后再复制回来。`centerUrls` 必须是普通 URL,Token 中的下划线 `_` 必须原样保留,不能写成 `\_`。
|
||||||
|
|
||||||
|
平台生成的初始配置可能是 `"scripts": []`。这只代表机器凭据已经创建,不代表系统能够自动知道本机的全部脚本:
|
||||||
|
|
||||||
|
- Windows 不会自动发现任务计划程序或影刀应用,标准 Agent 必须在 `scripts` 数组中逐项配置;
|
||||||
|
- Linux 只能自动发现当前运行账号的 Crontab,以及该账号可见的 PM2 进程;
|
||||||
|
- 影刀自定义采集器按附录 A 直接生成 `scripts` 快照,不要同时启动标准 Agent;
|
||||||
|
- 未列入配置或未被自动发现的脚本不会出现在平台页面。
|
||||||
|
|
||||||
|
### 7.1 公网 Windows 示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"agentId": "由平台生成,禁止照抄",
|
||||||
|
"agentToken": "由平台生成,禁止照抄",
|
||||||
|
"agentName": "财务脚本机 01",
|
||||||
|
"connectionMode": "internet",
|
||||||
|
"centerUrls": {
|
||||||
|
"internet": "https://cp.jiansun.vip"
|
||||||
|
},
|
||||||
|
"reportIntervalSec": 60,
|
||||||
|
"commandPollIntervalSec": 5,
|
||||||
|
"requestTimeoutMs": 10000,
|
||||||
|
"autoDiscover": {
|
||||||
|
"cron": false,
|
||||||
|
"pm2": true
|
||||||
|
},
|
||||||
|
"scripts": [
|
||||||
|
{
|
||||||
|
"key": "daily-finance-export",
|
||||||
|
"name": "每日财务导出",
|
||||||
|
"taskDescription": "生成每日财务导出文件",
|
||||||
|
"jobType": "OTHER",
|
||||||
|
"schedule": "Windows 任务计划:每天 02:00",
|
||||||
|
"expectedIntervalSec": 86400,
|
||||||
|
"allowManualRun": false,
|
||||||
|
"command": "C:\\Python311\\python.exe D:\\scripts\\daily_finance_export.py",
|
||||||
|
"cwd": "D:\\scripts",
|
||||||
|
"resultCheck": {
|
||||||
|
"type": "file",
|
||||||
|
"path": "D:\\scripts\\output\\latest.xlsx",
|
||||||
|
"maxAgeSec": 90000,
|
||||||
|
"minBytes": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
JSON 中的 Windows 路径必须使用双反斜杠,例如 `D:\\scripts`。
|
||||||
|
|
||||||
|
### 7.2 内网 Linux 示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"agentId": "由平台生成,禁止照抄",
|
||||||
|
"agentToken": "由平台生成,禁止照抄",
|
||||||
|
"agentName": "仓库脚本机 01",
|
||||||
|
"connectionMode": "intranet",
|
||||||
|
"centerUrls": {
|
||||||
|
"intranet": "<平台内网地址>"
|
||||||
|
},
|
||||||
|
"reportIntervalSec": 60,
|
||||||
|
"commandPollIntervalSec": 5,
|
||||||
|
"requestTimeoutMs": 5000,
|
||||||
|
"autoDiscover": {
|
||||||
|
"cron": true,
|
||||||
|
"pm2": true
|
||||||
|
},
|
||||||
|
"scripts": [
|
||||||
|
{
|
||||||
|
"key": "warehouse-stock-sync",
|
||||||
|
"name": "仓库库存同步",
|
||||||
|
"taskDescription": "同步仓库库存到业务系统",
|
||||||
|
"jobType": "CRON",
|
||||||
|
"schedule": "*/15 * * * *",
|
||||||
|
"expectedIntervalSec": 900,
|
||||||
|
"allowManualRun": true,
|
||||||
|
"command": "/usr/bin/bash /opt/scripts/warehouse-stock-sync.sh",
|
||||||
|
"cwd": "/opt/scripts",
|
||||||
|
"resultCheck": {
|
||||||
|
"type": "file",
|
||||||
|
"path": "/var/log/warehouse-stock-sync/latest.log",
|
||||||
|
"maxAgeSec": 1800,
|
||||||
|
"minBytes": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
配置完成后,Linux 执行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chmod 600 /opt/furniture-script-monitor/config.json
|
||||||
|
```
|
||||||
|
|
||||||
|
## 8. 脚本字段怎么填
|
||||||
|
|
||||||
|
| 字段 | 必填 | 填写要求 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `key` | 是 | 本机唯一且长期不变,只用英文、数字、短横线,后续不要随意改 |
|
||||||
|
| `name` | 是 | 页面显示名称,要让非开发人员看得懂 |
|
||||||
|
| `taskDescription` | 建议 | 说明脚本做什么、处理什么数据 |
|
||||||
|
| `jobType` | 是 | 只能是 `CRON`、`PM2`、`SYSTEMD`、`MANUAL`、`OTHER` |
|
||||||
|
| `schedule` | 否 | Cron 表达式或“Windows 任务计划:每天 02:00”等说明 |
|
||||||
|
| `expectedIntervalSec` | 否 | 预期运行间隔,单位秒;配合运行结果上报判断静默/超时 |
|
||||||
|
| `command` | 需要执行时 | 使用绝对路径,必须是本机已经验证过的真实命令 |
|
||||||
|
| `cwd` | 建议 | 命令工作目录,使用绝对路径 |
|
||||||
|
| `allowManualRun` | 是 | 默认 `false`;只有审核通过后才改为 `true` |
|
||||||
|
| `resultCheck` | 建议 | Agent 定期判断当前结果是否有效 |
|
||||||
|
|
||||||
|
同一台机器内不得配置重复 `key`。显式配置的脚本会覆盖相同 key 的自动发现结果。
|
||||||
|
|
||||||
|
## 9. 三种接入深度
|
||||||
|
|
||||||
|
### 9.1 只查看“机器上有哪些任务”
|
||||||
|
|
||||||
|
开启自动发现:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"autoDiscover": {
|
||||||
|
"cron": true,
|
||||||
|
"pm2": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- Linux 可以发现当前运行账号的 Crontab;
|
||||||
|
- 安装 PM2 的机器可以发现 PM2 进程;
|
||||||
|
- Windows 不会自动发现任务计划程序;Windows 脚本必须写入 `scripts`;
|
||||||
|
- 自动发现的 Cron 通常只能显示任务和计划,不能凭空知道真实执行结果;
|
||||||
|
- 自动发现任务不允许平台手动运行。
|
||||||
|
|
||||||
|
### 9.2 定期检查当前结果
|
||||||
|
|
||||||
|
在脚本中配置 `resultCheck`。
|
||||||
|
|
||||||
|
检查文件:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"resultCheck": {
|
||||||
|
"type": "file",
|
||||||
|
"path": "/absolute/path/to/result.log",
|
||||||
|
"maxAgeSec": 1800,
|
||||||
|
"minBytes": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
检查进程:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"resultCheck": {
|
||||||
|
"type": "process",
|
||||||
|
"name": "python"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
检查 Linux systemd 服务:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"resultCheck": {
|
||||||
|
"type": "systemd",
|
||||||
|
"service": "warehouse-sync.service"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Agent 的运行账号必须有权读取目标文件或查询目标进程/服务,否则页面会显示检查失败。
|
||||||
|
|
||||||
|
### 9.3 记录每次运行的真实结果
|
||||||
|
|
||||||
|
如果要记录开始时间、结束时间、耗时、退出码、标准输出和错误输出,应让原定时任务调用 `run-script.mjs`,由包装器再执行 `config.json` 中的真实 `command`。
|
||||||
|
|
||||||
|
Linux 示例:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
/usr/bin/node /opt/furniture-script-monitor/run-script.mjs warehouse-stock-sync
|
||||||
|
```
|
||||||
|
|
||||||
|
Windows 任务计划程序:
|
||||||
|
|
||||||
|
```text
|
||||||
|
程序:C:\Program Files\nodejs\node.exe
|
||||||
|
参数:C:\furniture-script-monitor\run-script.mjs daily-finance-export
|
||||||
|
起始于:C:\furniture-script-monitor
|
||||||
|
```
|
||||||
|
|
||||||
|
改造定时任务后,必须确认原命令没有继续单独运行,否则会造成同一个脚本重复执行。
|
||||||
|
|
||||||
|
包装器上报失败时不会擅自把原脚本改成成功;原脚本退出码仍会原样保留。
|
||||||
|
|
||||||
|
## 10. 首次前台启动和验收
|
||||||
|
|
||||||
|
先不要配置开机自启,必须前台运行一次。
|
||||||
|
|
||||||
|
Linux:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /opt/furniture-script-monitor
|
||||||
|
node agent.mjs
|
||||||
|
```
|
||||||
|
|
||||||
|
Windows PowerShell:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Set-Location C:\furniture-script-monitor
|
||||||
|
node .\agent.mjs
|
||||||
|
```
|
||||||
|
|
||||||
|
正确输出示例:
|
||||||
|
|
||||||
|
```text
|
||||||
|
[script-monitor] 已通过内网上报 3 个脚本
|
||||||
|
```
|
||||||
|
|
||||||
|
或:
|
||||||
|
|
||||||
|
```text
|
||||||
|
[script-monitor] 已通过公网上报 3 个脚本
|
||||||
|
```
|
||||||
|
|
||||||
|
然后在平台检查:
|
||||||
|
|
||||||
|
1. 机器从“待接入”变为“在线 · 内网”或“在线 · 公网”。
|
||||||
|
2. 顶部“在线/已接入”分母增加;从未上报的机器不会计入已接入分母。
|
||||||
|
3. 页面脚本数量与本机配置一致。
|
||||||
|
4. 每个脚本名称、计划和任务说明正确。
|
||||||
|
5. `resultCheck` 状态符合本机实际情况。
|
||||||
|
6. 关闭前台 Agent 后,等待至少 3 分钟,页面应显示“Agent 离线”。
|
||||||
|
|
||||||
|
Agent 在线判断时间为“至少 3 分钟,或 3 倍上报间隔,取较大值”。例如 `reportIntervalSec` 为 60 秒时,超过约 3 分钟未上报会显示离线。
|
||||||
|
|
||||||
|
安装人员没有平台账号时,不需要索要账号或密码。请把前台成功输出、机器名称、预期脚本数量和验收时间发给平台负责人,由负责人完成以上页面核对并明确回复“通过”或具体差异。
|
||||||
|
|
||||||
|
## 11. 配置常驻运行
|
||||||
|
|
||||||
|
### 11.1 Linux 使用 PM2
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /opt/furniture-script-monitor
|
||||||
|
npm install -g pm2
|
||||||
|
pm2 start ecosystem.config.cjs
|
||||||
|
pm2 save
|
||||||
|
pm2 startup
|
||||||
|
```
|
||||||
|
|
||||||
|
`pm2 startup` 会输出一条需要使用管理员权限执行的命令,按它的提示执行一次,然后再次运行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pm2 save
|
||||||
|
pm2 status furniture-script-monitor-agent
|
||||||
|
pm2 logs furniture-script-monitor-agent --lines 50
|
||||||
|
```
|
||||||
|
|
||||||
|
### 11.2 Windows 使用任务计划程序
|
||||||
|
|
||||||
|
先在 PowerShell 执行:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
(Get-Command node).Source
|
||||||
|
```
|
||||||
|
|
||||||
|
把输出的真实 `node.exe` 路径填到下面的“程序”中,不要在实际路径不同时照抄示例。
|
||||||
|
|
||||||
|
打开 Windows“任务计划程序”,创建任务:
|
||||||
|
|
||||||
|
- 名称:`Furniture Script Monitor Agent`;
|
||||||
|
- 触发器:启动时;
|
||||||
|
- 程序:上一步查到的真实 `node.exe` 路径,例如 `C:\Program Files\nodejs\node.exe`;
|
||||||
|
- 参数:`C:\furniture-script-monitor\agent.mjs`;
|
||||||
|
- 起始于:`C:\furniture-script-monitor`;
|
||||||
|
- 选择“不管用户是否登录都要运行”;
|
||||||
|
- 勾选“使用最高权限运行”;
|
||||||
|
- 失败后每 1 分钟重启,至少重试 3 次;
|
||||||
|
- 不要设置短于脚本运行时间的自动停止时限。
|
||||||
|
|
||||||
|
任务使用哪个 Windows 账号运行,该账号就必须能读取 `config.json`、脚本目录和结果文件,并有权执行已开放的命令。
|
||||||
|
|
||||||
|
## 12. 平台手动运行
|
||||||
|
|
||||||
|
手动运行只有同时满足以下条件才可点击:
|
||||||
|
|
||||||
|
1. 当前用户有脚本监控编辑权限;
|
||||||
|
2. Agent 在线;
|
||||||
|
3. 本机脚本配置了 `command`;
|
||||||
|
4. 本机明确设置 `"allowManualRun": true`;
|
||||||
|
5. 当前没有等待或正在执行的同一任务。
|
||||||
|
|
||||||
|
平台不会下发任意命令,只下发脚本 `key`。Agent 收到 key 后,只执行本机 `config.json` 中预先保存的 `command`。
|
||||||
|
|
||||||
|
开放手动运行前逐项确认:
|
||||||
|
|
||||||
|
- 命令不需要人工输入;
|
||||||
|
- 重复执行不会产生重复订单、重复扣减或覆盖数据;
|
||||||
|
- 脚本自身有锁,避免与原定时任务同时执行;
|
||||||
|
- 运行账号权限最小化;
|
||||||
|
- 已在目标机器直接执行并确认退出码为 0;
|
||||||
|
- 失败时能够从输出和错误日志定位原因。
|
||||||
|
|
||||||
|
手动运行请求约 5 分钟未被 Agent 领取会过期。Agent 默认每 5 秒主动领取一次,无需开放入站端口。
|
||||||
|
|
||||||
|
## 13. 重启验收
|
||||||
|
|
||||||
|
每台机器安装结束前必须重启一次或模拟一次开机启动:
|
||||||
|
|
||||||
|
1. 重启机器或停止并重新启动常驻任务。
|
||||||
|
2. 确认 Agent 进程自动恢复。
|
||||||
|
3. 等待一个上报周期。
|
||||||
|
4. 在平台确认机器重新显示在线。
|
||||||
|
5. 查看 Agent 日志,确认没有持续 401、超时或配置错误。
|
||||||
|
|
||||||
|
未完成重启验收,不算安装完成。
|
||||||
|
|
||||||
|
## 14. 常见故障
|
||||||
|
|
||||||
|
出现错误时先保留当前窗口,不要反复改 Token、改接口路径或换请求体。按本节定位一次,并按第 14.11 节的模板反馈。
|
||||||
|
|
||||||
|
### 14.1 提示找不到 `node`
|
||||||
|
|
||||||
|
说明 Node.js 未安装、版本不符合要求或不在当前账号的 PATH 中。把 `node --version` 和 `(Get-Command node).Source`(Windows)或 `command -v node`(Linux)的输出发给本机管理员;不要继续配置开机自启。
|
||||||
|
|
||||||
|
### 14.2 提示“配置文件不存在”
|
||||||
|
|
||||||
|
确认 `config.json` 与 `agent.mjs` 位于同一目录,或通过环境变量指定:
|
||||||
|
|
||||||
|
```text
|
||||||
|
SCRIPT_MONITOR_CONFIG=/absolute/path/config.json
|
||||||
|
```
|
||||||
|
|
||||||
|
### 14.3 返回 HTTP 401
|
||||||
|
|
||||||
|
通常是 `agentId` 和 `agentToken` 不匹配、Token 被复制不完整,或使用了其他机器的凭据。不要反复猜 Token,联系平台负责人重新生成。
|
||||||
|
|
||||||
|
如果凭据曾经粘贴到群聊、公开文档或其他非授权位置,应在平台删除原机器接入记录并重新生成,旧 Token 不再继续使用。
|
||||||
|
|
||||||
|
### 14.4 内网能通但 Agent 走了公网
|
||||||
|
|
||||||
|
检查 `connectionMode`、`centerUrls.intranet` 和内网 DNS/端口。`auto` 会先尝试内网,内网失败后才走公网。
|
||||||
|
|
||||||
|
### 14.5 机器在线但没有脚本
|
||||||
|
|
||||||
|
检查:
|
||||||
|
|
||||||
|
- `scripts` 是否为 JSON 数组;
|
||||||
|
- 每一项是否都有唯一的 `key` 和非空 `name`;
|
||||||
|
- `jobType` 是否使用支持的枚举值;
|
||||||
|
- Windows 是否误以为能自动发现任务计划程序;
|
||||||
|
- Agent 日志是否出现 HTTP 400 或 JSON 解析错误。
|
||||||
|
|
||||||
|
Windows 机器的 `scripts: []` 不会自动变成任务计划程序或影刀应用列表。影刀场景必须选择附录 A 的自定义采集器,或由负责人把每个应用人工配置为标准 Agent 脚本。
|
||||||
|
|
||||||
|
### 14.6 “立即运行”按钮不可用
|
||||||
|
|
||||||
|
页面会给出具体原因。重点检查 Agent 是否在线、脚本是否有 `command`,以及是否明确设置了 `"allowManualRun": true`。
|
||||||
|
|
||||||
|
### 14.7 结果文件明明存在,但页面显示失败
|
||||||
|
|
||||||
|
使用运行 Agent 的同一个系统账号检查文件权限、路径、更新时间和大小。相对路径容易受启动目录影响,`resultCheck.path` 必须使用绝对路径。
|
||||||
|
|
||||||
|
### 14.8 页面显示“最近成功”,但 Agent 离线
|
||||||
|
|
||||||
|
“最近成功”表示脚本历史上的最后一次结果;“Agent 离线”表示机器当前没有继续上报,两者含义不同。先恢复 Agent,再判断脚本是否仍在正常执行。
|
||||||
|
|
||||||
|
### 14.9 返回 HTTP 400、403、404 或 405
|
||||||
|
|
||||||
|
- `400 / VALIDATION_003`:请求体格式错误;标准 Agent 检查 `config.json` 中的枚举、数字和 JSON 语法,自定义采集器按附录 A 对照;
|
||||||
|
- `403`:请求被安全策略拒绝,保留完整响应正文和请求 ID 后联系平台负责人;
|
||||||
|
- `404`:请求地址错误,自定义程序通常仍在使用旧接口;标准 Agent 不应自行修改接口路径;
|
||||||
|
- `405`:实际请求方法不是 `POST`,浏览器地址栏直接打开接口得到 405 不能证明上报程序的 POST 请求正确。
|
||||||
|
|
||||||
|
### 14.10 JSON 配置无法读取
|
||||||
|
|
||||||
|
常见原因是 Windows 路径只写了一个反斜杠、复制了 Markdown 链接、Token 中出现 `\_`、末尾多逗号或使用了中文引号。使用文本编辑器保存为 UTF-8 JSON;不要使用 Word 编辑。可以在 Agent 目录执行以下命令验证 JSON 语法:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Get-Content -LiteralPath '.\config.json' -Raw | ConvertFrom-Json | Out-Null
|
||||||
|
Write-Host 'config.json 语法正确'
|
||||||
|
```
|
||||||
|
|
||||||
|
### 14.11 统一故障反馈模板
|
||||||
|
|
||||||
|
安装人员反馈问题时一次提供以下内容,避免只说“失败了”:
|
||||||
|
|
||||||
|
```text
|
||||||
|
机器名称:
|
||||||
|
操作系统及版本:
|
||||||
|
选择的接入方式:标准 Agent / 自定义采集器
|
||||||
|
Node.js 版本:
|
||||||
|
网络模式:intranet / internet / auto
|
||||||
|
执行时间(含时区):
|
||||||
|
执行的命令:
|
||||||
|
预期脚本数量:
|
||||||
|
Agent 实际发现/上报数量:
|
||||||
|
最终 HTTP 方法和 URL(自定义采集器必填):
|
||||||
|
HTTP 状态码:
|
||||||
|
完整响应正文或报错:
|
||||||
|
最近 30 行 Agent 日志:
|
||||||
|
```
|
||||||
|
|
||||||
|
反馈中禁止包含完整 `agentToken`、完整 `Authorization` 请求头或未脱敏的 `config.json`。如果必须说明凭据是否一致,只保留 Agent ID,Token 最多保留前后各 2 位并遮盖中间内容。
|
||||||
|
|
||||||
|
## 15. 升级 Agent
|
||||||
|
|
||||||
|
只有平台负责人明确通知新版本时才升级,不要自行使用不明来源文件。升级时只替换这些程序文件:
|
||||||
|
|
||||||
|
```text
|
||||||
|
agent.mjs
|
||||||
|
run-script.mjs
|
||||||
|
ecosystem.config.cjs
|
||||||
|
```
|
||||||
|
|
||||||
|
不要覆盖目标机器的 `config.json`。
|
||||||
|
|
||||||
|
Linux:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pm2 restart furniture-script-monitor-agent
|
||||||
|
pm2 logs furniture-script-monitor-agent --lines 50
|
||||||
|
```
|
||||||
|
|
||||||
|
Windows:结束并重新运行对应任务计划,然后在平台确认一个上报周期内恢复在线。
|
||||||
|
|
||||||
|
## 16. 每台机器交接记录
|
||||||
|
|
||||||
|
安装人员每完成一台机器,填写一行;严禁在表格中记录 Token。
|
||||||
|
|
||||||
|
| 机器名称 | 操作系统 | 平台机器名称 | 网络模式 | 平台地址 | 安装目录 | 常驻方式 | 脚本数量 | 允许手动运行的脚本 | 负责人 | 安装时间 | 重启验收 |
|
||||||
|
| --- | --- | --- | --- | --- | --- | --- | ---: | --- | --- | --- | --- |
|
||||||
|
| 示例:仓库脚本机 01 | Ubuntu 24.04 | 杭州仓库脚本机 01 | intranet | 由运维提供 | `/opt/furniture-script-monitor` | PM2 | 3 | warehouse-stock-sync | 张三 | 2026-08-28 | 通过 |
|
||||||
|
|
||||||
|
## 17. 单机完成清单
|
||||||
|
|
||||||
|
- [ ] 已明确选择标准 Agent 或自定义采集器,未使用同一凭据同时运行两种上报程序;
|
||||||
|
- [ ] 平台为本机生成了独立凭据;
|
||||||
|
- [ ] 已拿到本机脚本清单,实际脚本数量有明确依据;
|
||||||
|
- [ ] `config.json` 未使用示例 Token,文件权限已收紧;
|
||||||
|
- [ ] 网络模式和平台地址与机器实际网络一致;
|
||||||
|
- [ ] 所有脚本都有唯一 key、清晰名称和正确工作目录;
|
||||||
|
- [ ] 高风险脚本未开放手动运行;
|
||||||
|
- [ ] 前台启动成功并显示内网或公网上报;
|
||||||
|
- [ ] 平台机器由待接入变为在线;
|
||||||
|
- [ ] 平台脚本数量与本机一致;
|
||||||
|
- [ ] 至少一个脚本的结果检查或包装器运行已验证;
|
||||||
|
- [ ] 常驻进程或任务计划已配置;
|
||||||
|
- [ ] 重启后 Agent 能自动恢复;
|
||||||
|
- [ ] 已填写单机交接记录,记录中不含 Token。
|
||||||
|
|
||||||
|
## 附录 A:自定义采集器 HTTP API 契约
|
||||||
|
|
||||||
|
本附录适用于影刀等已有采集程序直接向平台推送数据的场景,执行人必须能够修改并调试采集程序。普通安装人员如果只能安装软件、不能修改代码,应停止在本附录继续尝试,改用标准 Agent 或把本附录交给采集程序开发人员。
|
||||||
|
|
||||||
|
使用官方 `agent.mjs` 时,不需要手工拼接这些请求;只需填写第 7 节的 `config.json`,Agent 会自动补全接口路径和 `connectionKind`。自定义采集器投入运行后,不得再使用同一组凭据启动官方 Agent。
|
||||||
|
|
||||||
|
### A.0 按顺序完成联调
|
||||||
|
|
||||||
|
不要一开始同时推送 16 个应用、17 条日志和手动运行。按以下顺序逐项验收,前一步未达到预期时不要进入下一步:
|
||||||
|
|
||||||
|
1. 使用 1 个真实影刀应用调用 `/report`,确认 HTTP 200,平台显示 1 个脚本;
|
||||||
|
2. 改为上报全部 16 个应用,确认平台数量为 16,13 个有可靠成功记录的任务为 `SUCCESS`,其余为 `UNKNOWN`;
|
||||||
|
3. 使用 1 条真实任务日志调用 `/run`,确认页面出现运行记录;
|
||||||
|
4. 再补传其余日志,每条使用稳定唯一的 `externalRunId`;
|
||||||
|
5. 最后才实现 `/commands/claim` 和平台手动运行;不需要手动运行时保持 `canManualRun: false`。
|
||||||
|
|
||||||
|
每一步都必须记录最终请求方法、最终 URL、HTTP 状态码和完整响应正文。只记录程序内部的 `success=False` 不算有效验收证据。
|
||||||
|
|
||||||
|
### A.1 接口和认证头
|
||||||
|
|
||||||
|
公网平台基础地址只能写纯文本:
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://cp.jiansun.vip
|
||||||
|
```
|
||||||
|
|
||||||
|
禁止写成 Markdown 链接 `[https://cp.jiansun.vip](https://cp.jiansun.vip)`,也不要把 `/api/internal/script-monitor/report` 重复写进 `centerUrls.internet`。
|
||||||
|
|
||||||
|
当前接口如下:
|
||||||
|
|
||||||
|
| 用途 | 方法和完整路径 |
|
||||||
|
| --- | --- |
|
||||||
|
| 上报机器和脚本当前快照 | `POST https://cp.jiansun.vip/api/internal/script-monitor/report` |
|
||||||
|
| 上报脚本的一次运行记录 | `POST https://cp.jiansun.vip/api/internal/script-monitor/run` |
|
||||||
|
| 领取平台“立即运行”命令 | `POST https://cp.jiansun.vip/api/internal/script-monitor/commands/claim` |
|
||||||
|
|
||||||
|
三个接口都使用同一组请求头:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Content-Type: application/json
|
||||||
|
Authorization: Bearer <本机 Agent Token>
|
||||||
|
x-script-monitor-agent-id: <本机 Agent ID>
|
||||||
|
```
|
||||||
|
|
||||||
|
`agentId` 和 `agentToken` 只放请求头,不得再放入 JSON 请求体。Token 不要经过 Markdown 转义;Token 中如果有下划线 `_`,原样保留,不能写成 `\_`。
|
||||||
|
|
||||||
|
### A.2 `/report` 完整合法 JSON
|
||||||
|
|
||||||
|
下面是已按当前平台校验规则整理的完整示例。影刀应用统一使用 `jobType: "OTHER"`;所有枚举值必须大写。
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"hostname": "cloud-pc-01",
|
||||||
|
"os": "Windows 11",
|
||||||
|
"agentVersion": "yingdao-collector-1.0.0",
|
||||||
|
"connectionKind": "INTERNET",
|
||||||
|
"reportIntervalSec": 60,
|
||||||
|
"scripts": [
|
||||||
|
{
|
||||||
|
"key": "yingdao-app-10001",
|
||||||
|
"name": "订单数据同步",
|
||||||
|
"taskDescription": "影刀应用:同步订单数据",
|
||||||
|
"jobType": "OTHER",
|
||||||
|
"schedule": "影刀调度:每天 08:00",
|
||||||
|
"commandPreview": null,
|
||||||
|
"expectedIntervalSec": 86400,
|
||||||
|
"status": "SUCCESS",
|
||||||
|
"isEnabled": true,
|
||||||
|
"canManualRun": false,
|
||||||
|
"lastStartedAt": "2026-08-28T08:00:00+08:00",
|
||||||
|
"lastFinishedAt": "2026-08-28T08:02:09+08:00",
|
||||||
|
"lastDurationMs": 129000,
|
||||||
|
"lastExitCode": 0,
|
||||||
|
"lastResultSummary": "本次运行成功;今日已触发 3 次",
|
||||||
|
"lastOutputTail": "处理 125 条记录",
|
||||||
|
"lastErrorTail": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "yingdao-app-10002",
|
||||||
|
"name": "库存检查",
|
||||||
|
"taskDescription": "影刀应用:检查库存异常",
|
||||||
|
"jobType": "OTHER",
|
||||||
|
"schedule": null,
|
||||||
|
"commandPreview": null,
|
||||||
|
"expectedIntervalSec": null,
|
||||||
|
"status": "UNKNOWN",
|
||||||
|
"isEnabled": true,
|
||||||
|
"canManualRun": false,
|
||||||
|
"lastStartedAt": null,
|
||||||
|
"lastFinishedAt": null,
|
||||||
|
"lastDurationMs": null,
|
||||||
|
"lastExitCode": null,
|
||||||
|
"lastResultSummary": "已发现应用,暂未取得运行结果",
|
||||||
|
"lastOutputTail": null,
|
||||||
|
"lastErrorTail": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`scripts` 是当前机器的完整快照,不是只放本次发生变化的脚本。若发现 16 个影刀应用,应上报 16 项:有可靠成功记录的 13 项填 `SUCCESS`,其余 3 项填 `UNKNOWN`,不能把没有结果的应用也推断为成功。
|
||||||
|
|
||||||
|
### A.3 `/report` 字段限制
|
||||||
|
|
||||||
|
平台使用严格校验:请求体顶层和每个 `scripts[]` 对象都不能出现未定义字段。多一个字段、枚举大小写错误、数字写成字符串或时间格式错误,都会返回 `VALIDATION_003`。
|
||||||
|
|
||||||
|
顶层只允许以下字段:
|
||||||
|
|
||||||
|
| 字段 | 必填 | 类型和限制 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `hostname` | 否 | 字符串或 `null`,最多 160 字符 |
|
||||||
|
| `os` | 否 | 字符串或 `null`,最多 240 字符 |
|
||||||
|
| `agentVersion` | 否 | 字符串或 `null`,最多 40 字符 |
|
||||||
|
| `connectionKind` | 是 | 只能是 `INTRANET` 或 `INTERNET` |
|
||||||
|
| `reportIntervalSec` | 否 | 15~3600 的整数,默认 60;不能写成字符串 `"60"` |
|
||||||
|
| `scripts` | 是 | 数组,最多 1000 项 |
|
||||||
|
|
||||||
|
每个 `scripts[]` 对象只允许以下字段:
|
||||||
|
|
||||||
|
| 字段 | 必填 | 类型和限制 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `key` | 是 | 稳定且本机唯一的字符串,1~240 字符;优先使用影刀应用 ID 生成 |
|
||||||
|
| `name` | 是 | 字符串,1~180 字符 |
|
||||||
|
| `taskDescription` | 否 | 字符串,最多 2000 字符,默认空字符串 |
|
||||||
|
| `jobType` | 是 | `CRON`、`PM2`、`SYSTEMD`、`MANUAL`、`OTHER` 之一 |
|
||||||
|
| `schedule` | 否 | 字符串或 `null`,最多 240 字符 |
|
||||||
|
| `commandPreview` | 否 | 字符串或 `null`,最多 2000 字符;不得包含凭据 |
|
||||||
|
| `expectedIntervalSec` | 否 | 15~31536000 的整数或 `null` |
|
||||||
|
| `status` | 否 | `UNKNOWN`、`RUNNING`、`SUCCESS`、`FAILED`、`SILENT`、`DISABLED` 之一,默认 `UNKNOWN` |
|
||||||
|
| `isEnabled` | 否 | 布尔值,默认 `true` |
|
||||||
|
| `canManualRun` | 否 | 布尔值,默认 `false` |
|
||||||
|
| `lastStartedAt` | 否 | 带时区的 ISO 8601 字符串或 `null` |
|
||||||
|
| `lastFinishedAt` | 否 | 带时区的 ISO 8601 字符串或 `null` |
|
||||||
|
| `lastDurationMs` | 否 | 0~2147483647 的整数或 `null`,单位毫秒 |
|
||||||
|
| `lastExitCode` | 否 | -2147483648~2147483647 的整数或 `null` |
|
||||||
|
| `lastResultSummary` | 否 | 字符串或 `null`,最多 4000 字符 |
|
||||||
|
| `lastOutputTail` | 否 | 字符串或 `null`,最多 12000 字符,只保留末尾内容 |
|
||||||
|
| `lastErrorTail` | 否 | 字符串或 `null`,最多 12000 字符,只保留末尾内容 |
|
||||||
|
|
||||||
|
没有值时应省略字段或传 `null`,不要给日期、数字、布尔字段传空字符串。日期必须包含 `Z` 或时区偏移,例如 `2026-08-28T08:02:09+08:00`;`2026-08-28 08:02:09` 不合法。
|
||||||
|
|
||||||
|
以下字段不能放入 `/report` 请求体:`agentId`、`agentToken`、`agentName`、`success`、`todayTriggers`、`taskLogs`、`apps`。需要展示“今日 57 次调度”等统计时,把各脚本自己的统计写入对应的 `lastResultSummary`;真实的每次任务日志使用 `/run` 上报。
|
||||||
|
|
||||||
|
### A.4 影刀字段映射
|
||||||
|
|
||||||
|
| 影刀采集结果 | 平台字段 |
|
||||||
|
| --- | --- |
|
||||||
|
| 影刀应用唯一 ID | `scripts[].key`,例如 `yingdao-app-<ID>` |
|
||||||
|
| 影刀应用名称 | `scripts[].name` |
|
||||||
|
| 应用/任务说明 | `scripts[].taskDescription` |
|
||||||
|
| 调度计划文字 | `scripts[].schedule` |
|
||||||
|
| 影刀任务正在执行 | `scripts[].status = "RUNNING"` |
|
||||||
|
| 影刀任务成功 | `scripts[].status = "SUCCESS"` |
|
||||||
|
| 影刀任务失败 | `scripts[].status = "FAILED"` |
|
||||||
|
| 已发现但没有可靠结果 | `scripts[].status = "UNKNOWN"` |
|
||||||
|
| 被停用 | `scripts[].status = "DISABLED"`,同时 `isEnabled = false` |
|
||||||
|
| 开始/完成时间 | `lastStartedAt` / `lastFinishedAt`,转为带时区 ISO 8601 |
|
||||||
|
| 耗时 | `lastDurationMs`,单位毫秒整数 |
|
||||||
|
| 结果摘要 | `lastResultSummary` |
|
||||||
|
| 日志末尾 | `lastOutputTail` / `lastErrorTail` |
|
||||||
|
|
||||||
|
采集程序内部即使使用小写 `success`,发给平台前也必须映射成大写 `SUCCESS`。影刀不是平台枚举中的任务类型,因此 `jobType` 必须固定为 `OTHER`,不能传 `YINGDAO`。
|
||||||
|
|
||||||
|
### A.5 `/run` 上报每次任务日志
|
||||||
|
|
||||||
|
发现的 17 条任务日志不应作为 `taskLogs` 塞进 `/report`,而应逐条调用 `/run`。完整合法示例:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"commandId": null,
|
||||||
|
"scriptKey": "yingdao-app-10001",
|
||||||
|
"scriptName": "订单数据同步",
|
||||||
|
"taskDescription": "影刀应用:同步订单数据",
|
||||||
|
"jobType": "OTHER",
|
||||||
|
"externalRunId": "yingdao-run-20260828-000123",
|
||||||
|
"status": "SUCCESS",
|
||||||
|
"trigger": "YINGDAO_SCHEDULE",
|
||||||
|
"startedAt": "2026-08-28T08:00:00+08:00",
|
||||||
|
"finishedAt": "2026-08-28T08:02:09+08:00",
|
||||||
|
"durationMs": 129000,
|
||||||
|
"exitCode": 0,
|
||||||
|
"resultSummary": "运行成功,处理 125 条记录",
|
||||||
|
"outputTail": "处理完成",
|
||||||
|
"errorTail": null
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`/run` 的必填字段是 `scriptKey`、`scriptName`、`jobType`、`externalRunId`、`status`、`startedAt`。其中:
|
||||||
|
|
||||||
|
- `status` 只能是 `RUNNING`、`SUCCESS`、`FAILED`;
|
||||||
|
- `externalRunId` 必须是这台机器内一次运行的稳定唯一 ID,最长 240 字符;重复发送相同 ID 会更新同一条记录,不会重复新增;
|
||||||
|
- `startedAt` 必须是带时区 ISO 8601;
|
||||||
|
- `commandId` 只有响应平台手动运行命令时才填写,否则传 `null` 或省略;
|
||||||
|
- 每条历史日志都只上报自身的实际状态,不能把汇总状态代替单次运行状态。
|
||||||
|
|
||||||
|
### A.6 Windows PowerShell 最小联调命令
|
||||||
|
|
||||||
|
先把 A.2 的 JSON 保存为 `report-test.json`。在 PowerShell 临时设置凭据,执行完成后关闭窗口;不要把真实 Token 写进脚本或提交到 Git:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$env:SCRIPT_MONITOR_AGENT_ID = '<本机 Agent ID>'
|
||||||
|
$env:SCRIPT_MONITOR_AGENT_TOKEN = '<本机 Agent Token>'
|
||||||
|
|
||||||
|
$headers = @{
|
||||||
|
Authorization = "Bearer $env:SCRIPT_MONITOR_AGENT_TOKEN"
|
||||||
|
'x-script-monitor-agent-id' = $env:SCRIPT_MONITOR_AGENT_ID
|
||||||
|
}
|
||||||
|
|
||||||
|
Invoke-RestMethod `
|
||||||
|
-Uri 'https://cp.jiansun.vip/api/internal/script-monitor/report' `
|
||||||
|
-Method Post `
|
||||||
|
-ContentType 'application/json; charset=utf-8' `
|
||||||
|
-Headers $headers `
|
||||||
|
-InFile '.\report-test.json'
|
||||||
|
```
|
||||||
|
|
||||||
|
成功响应中应看到 `success: true`,并返回 `scriptCount`。随后刷新平台页面,机器应在线且显示 JSON 中的脚本。
|
||||||
|
|
||||||
|
Python 自定义采集器应按以下方式调用;`payload` 就是 A.2 的对象:
|
||||||
|
|
||||||
|
```python
|
||||||
|
response = requests.post(
|
||||||
|
"https://cp.jiansun.vip/api/internal/script-monitor/report",
|
||||||
|
headers={
|
||||||
|
"Authorization": f"Bearer {agent_token}",
|
||||||
|
"x-script-monitor-agent-id": agent_id,
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
json=payload,
|
||||||
|
timeout=10,
|
||||||
|
)
|
||||||
|
print(response.status_code, response.text)
|
||||||
|
response.raise_for_status()
|
||||||
|
```
|
||||||
|
|
||||||
|
### A.7 一次定位错误
|
||||||
|
|
||||||
|
| HTTP/错误 | 含义和处理 |
|
||||||
|
| --- | --- |
|
||||||
|
| `404` | 路径错误,通常仍在使用旧的 `/api/agent/...` 或漏写 `/api/internal/script-monitor` |
|
||||||
|
| `405` | 实际到达服务器的请求方法不是 `POST`,或请求被调用工具/代理改成了 `GET`;记录最终 URL 和最终方法再排查 |
|
||||||
|
| `400 / VALIDATION_003` | JSON 未通过 A.3 的严格校验;优先检查额外字段、枚举大小写、数字字符串和无时区日期 |
|
||||||
|
| `401 / AUTH_002` | JSON 格式已通过,但 Agent ID/Token 缺失、无效或不匹配 |
|
||||||
|
| `403` | 请求被平台安全策略拒绝;保存响应正文和请求 ID,联系平台负责人 |
|
||||||
|
| `200` | 上报成功;仍需在页面核对脚本数量和状态是否符合真实数据 |
|
||||||
|
|
||||||
|
排错时必须让采集器打印以下四项,凭据只保留前后各 2 位并遮盖中间内容:最终请求方法、最终 URL、HTTP 状态码、完整响应正文。不要只打印 `success=False`,否则无法区分路径、校验、认证和安全策略。
|
||||||
|
|
||||||
|
### A.8 自定义采集器支持平台手动运行的额外要求
|
||||||
|
|
||||||
|
只实现 `/report` 和 `/run`,可以显示机器、脚本、状态和结果,但不能响应平台“立即运行”。如果需要手动触发,自定义采集器还必须:
|
||||||
|
|
||||||
|
1. 每 5 秒 `POST /api/internal/script-monitor/commands/claim`,请求体为 `{}`;
|
||||||
|
2. 收到命令后,只按 `scriptKey` 查找本机预先配置的安全命令,禁止执行平台传来的任意命令文本;
|
||||||
|
3. 开始和结束时调用 `/run`,并把领取结果中的命令 ID 放入 `commandId`;
|
||||||
|
4. 在 `/report` 对应脚本中设置 `canManualRun: true`;
|
||||||
|
5. 对高风险任务默认保持 `canManualRun: false`。
|
||||||
|
|
||||||
|
旧项目使用的 WebSocket、`/api/agent/...` 和旧消息格式与当前产品平台不兼容,不能直接复用。可以复用影刀数据采集逻辑,但上报层必须按本附录改造。
|
||||||
Loading…
x
Reference in New Issue
Block a user