节点在线、应用在线、配置在线使用令牌查询
|
# DEPLOY-3 å‰ç«¯ — 节点应用文件日志(需求说明)
> 版本:v1.0 | 日期:2026-11-03
> å…³è”åŽç«¯ï¼š[DEPLOY-1-节点应用日志.md](/NewLife/Stardust/Blob/master/Doc/DEPLOY-1-节点应用日志.md)ã€[DEPLOY-2-本地应用日志è”调环境.md](/NewLife/Stardust/Blob/master/Doc/DEPLOY-2-本地应用日志è”调环境.md)
> ç›®æ ‡è¯»è€…ï¼šStardust.Web.Vue(Console / StardustLayout2)å‰ç«¯å¼€å‘ã€æµ‹è¯•ã€éªŒæ”¶
> 状æ€ï¼š**P1 MVP 已在 Layout2 有å‚考实现**;新控制å°é¡µé¢éœ€æŒ‰æœ¬æ–‡å¯¹é½æˆ–è¿ç§»
---
## 1. 产å“定ä½
### 1.1 è¦è§£å†³ä»€ä¹ˆé—®é¢˜
è¿ç»´åœ¨æŽ§åˆ¶å°æŸ¥çœ‹**部署在物ç†èŠ‚ç‚¹ä¸Šçš„åº”ç”¨**写在**本地ç£ç›˜**的日志文件(如 `app.log`ï¼‰ï¼Œè€Œä¸æ˜¯ï¼š
| 能力 | 路径 / åç§° | 与本需求关系 |
|------|-------------|--------------|
| **SDK 上报日志** | 应用工作å°é¡µç¾ã€Œæ—¥å¿—ã€â†’ `AppLog.vue` → `/Registry/AppClientLog` | **䏿˜¯**æœ¬éœ€æ±‚ï¼›æ— æ–‡ä»¶è·¯å¾„ã€æ— tail 节点ç£ç›˜ |
| **StarAgent 自身日志** | 节点详情「抓日志ã€ç‰ | **䏿˜¯**业务应用目录 |
| **å‘布ä¸å¿ƒã€ŒæŸ¥çœ‹æ—¥å¿—ã€** | `ReleaseCenter.vue` ç‰ | 多为**构建/æµæ°´çº¿**日志,当å‰å¤šä¸ºã€Œå¾…接入ã€ï¼›**䏿˜¯**部署节点文件日志 |
| **SSH / bash tail** | 节点远程命令 | 应急手段;**日常入å£å¿…é¡»æ˜¯æŽ§åˆ¶å° + API** |
本需求在文案上统一称为:**节点文件日志** / **部署节点本地文件日志**ã€‚æŠ½å±‰æ ‡é¢˜ç¤ºä¾‹ï¼š**节点文件日志**。
### 1.2 用户价值(P1)
1. 在**部署节点**行上一点「查看日志ã€ï¼Œåˆ—出匹é…规则的日志文件并阅读**文件尾部**内容。
2. 在**部署节点编辑**里é…置日志目录与匹é…规则(å¯è¦†ç›–部署集默认)。
3. 失败时看到**å¯è¡ŒåЍ**的错误(未é…置目录ã€èŠ‚ç‚¹ç¦»çº¿ã€Agent 未å‡çº§ã€æ— æƒæ“作ç‰ï¼‰ï¼Œè€Œä¸æ˜¯ç©ºç™½æˆ–凿ˆåŠŸã€‚
### 1.3 分期(å‰ç«¯è§†è§’)
| 阶段 | å‰ç«¯èŒƒå›´ | ä¸åœ¨èŒƒå›´ |
|------|----------|----------|
| **P1 MVP** | å…¥å£ + 抽屉 + é…ç½®å—æ®µ + 手动刷新 + 错误é€ä¼ | 自动轮询 tailã€å‘上翻页ã€ä¸‹è½½ã€K8s Pod 日志 |
| **P2(2026-11-04 已交付)** | 抽屉自动轮询开关 + 1~5 ç§’é—´éš”ä¸‹æ‹‰ï¼ˆè½®è¯¢èµ°å¢žé‡ offset);é…套 MCP å·¥å…·è§ DEPLOY-1 §11 | å‘上翻页ã€ä¸‹è½½ã€K8s Pod 日志 |
| **P3(2026-11-04 已交付)** | 准实时 tail:轮询增é‡è¿½æ–°ï¼ˆoffset=上次 fileSize,内容å°é¡¶ 1MBï¼Œå¤±è´¥è‡ªåŠ¨åœæ¢å¹¶æç¤ºï¼‰ | SSE/WebSocket(留作åŽç»å¯é€‰å¢žå¼ºï¼‰ |
---
## 2. ä¿¡æ¯æž¶æž„与入å£
### 2.1 主入å£ï¼ˆå¿…须)
| 场景 | 路由 / 容器 | 用户æ“作 | 打开组件 |
|------|-------------|----------|----------|
| **åº”ç”¨å·¥ä½œå° Â· 部署 · 节点** | **`/app/overview/:appId`**(新 Console 契约;页内二级区切到「部署ã€â†’「部署节点ã€ï¼‰ | `App.vue` → `ShipPanel` → è¡¨æ ¼è¡Œ **查看日志** | `DeployLogDrawer` |
| **åŒèƒ½åŠ›å…¶å®ƒ tab 深链** | `/app/:tab/:id`(如 `ship`/`history` ç‰ï¼Œä»¥ `App.vue` + `workbench.logic` 为准) | 部署区ä»åµŒ `ShipPanel` æ—¶åŒä¸Š | åŒä¸Š |
| **全局部署页(若有)** | `/ship` ç‰ï¼ˆè‹¥ä»æ³¨å†Œï¼‰ | åŒä¸Šï¼Œå…±ç”¨ `ShipPanel` | åŒä¸Š |
**行级数æ®è¦æ±‚**ï¼šç‚¹å‡»æ—¶ä¼ å…¥ **`AppDeployNode.Id`**ï¼ˆéƒ¨ç½²èŠ‚ç‚¹ä¸»é”®ï¼Œéž `NodeId`ã€éžåº”用 `AppId`)。å‚考:`ShipPanel.openDeployLogs(n)` 使用 `n.id` 作为 `deployNodeId`。
**å¹¶å‘**:节点行æ£åœ¨ä¸‹å‘ install/start/stop ç‰ï¼ˆ`busyKey` éžç©ºï¼‰æ—¶ï¼Œã€ŒæŸ¥çœ‹æ—¥å¿—ã€åº”ç¦ç”¨æˆ–忽略点击(与现网 `ShipPanel` 一致)。
### 2.2 é…置入å£ï¼ˆå¿…须)
| 场景 | 组件 | å—æ®µ |
|------|------|------|
| 新增/编辑**部署节点** | `NodeFormDrawer`,`kind === 'deploy'` | `logDirectory`ã€`logFilePattern` |
| **部署集**级默认(åŽç«¯å·²æ”¯æŒï¼‰ | 建议在 `DeployEditDrawer` **è¡¥å—æ®µ**(当å‰å‚考实现未暴露) | `logDirectory`ã€`logFilePattern` |
åˆå¹¶è§„则(与åŽç«¯ä¸€è‡´ï¼Œæ–‡æ¡ˆå¯å±•ç¤ºåœ¨è¡¨å• hint):
- 节点 `logDirectory` éžç©º → 用节点值;å¦åˆ™ç”¨éƒ¨ç½²é›† `LogDirectory`。
- 节点 `logFilePattern` éžç©º → 用节点值;å¦åˆ™ç”¨éƒ¨ç½²é›†ï¼›éƒ½ç©º → `*.log`。
- 相对路径与 **EffectiveWorkingDirectory** 组åˆï¼ˆè§ DEPLOY-1)。
### 2.3 明确ä¸åšä¸º P1 å…¥å£
- åº”ç”¨å·¥ä½œå° **「日志ã€é¡µç¾**(`AppLog`ï¼‰ï¼šä¿æŒ SDK 日志,ä¸åœ¨æ¤é¡µå𿖇件 tail。
- 应用列表 / 应用详情顶æ 「查看日志ã€ï¼šè‹¥æœªç»‘定部署节点,**ä¸è¦**与本能力混用;需è¦å•独产å“决ç–åŽå†åšæ·±é“¾ã€‚
- 编译节点(`kind === 'build'`ï¼‰ï¼šæ— æ–‡ä»¶æ—¥å¿—èƒ½åŠ›ï¼Œæ— ã€ŒæŸ¥çœ‹æ—¥å¿—ã€æŒ‰é’®ã€‚
---
## 3. 交互与界é¢è§„æ ¼ï¼ˆP1)
### 3.1 抽屉 `DeployLogDrawer`
**Props**
| 属性 | 类型 | 说明 |
|------|------|------|
| `open` | boolean | æ˜¯å¦æ˜¾ç¤º |
| `deployNodeId` | number | `AppDeployNode.Id` |
| `nodeName` | string | 展示用,如物ç†èŠ‚ç‚¹å |
**布局(自上而下)**
1. **æ ‡é¢˜**:节点文件日志
2. **å‰¯æ ‡é¢˜**:`{nodeName} · 部署节点 #{deployNodeId}`
3. **说明文案**(固定一段,11–12px 次è¦è‰²ï¼‰ï¼š
- è¯´æ˜Žæ•°æ®æ¥è‡ª StarAgent 读å–节点ç£ç›˜ï¼›
- 与「应用日志ã€é¡µç¾ï¼ˆSDK 上报)ä¸åŒï¼›
- 未é…置目录请到部署节点编辑填写。
4. **工具行**
- 下拉:**日志文件**(展示 `name (å‹å¥½å¤§å°)`,如 `app.log (1.5 MB)`ï¼›æ— æ–‡ä»¶æ—¶å ä½ã€Œæ— åŒ¹é…æ–‡ä»¶ã€/ã€ŒåŠ è½½æ–‡ä»¶åˆ—è¡¨â€¦ã€ï¼‰
- 按钮:**刷新**ï¼ˆåŒæ—¶é‡æ‹‰åˆ—è¡¨ï¼›è‹¥å·²é€‰æ–‡ä»¶åˆ™å† tail)
- 按钮:**自动刷新**(P2,`data-spec="deploy-log-auto-toggle"`;开å¯åŽå˜ primary å¹¶æ˜¾ç¤ºã€Œè‡ªåŠ¨åˆ·æ–°ä¸ Â· æ¯ Nsã€ï¼Œå†ç‚¹åœæ¢ï¼‰
- 下拉:**é—´éš”**(P2,`data-spec="deploy-log-interval"`ï¼›1~5 秒,默认 2s;未开å¯è‡ªåŠ¨åˆ·æ–°æ—¶ç¦ç”¨ï¼Œtitle è¯´æ˜ŽåŽŸå› ï¼‰
- 按钮:**åŠ è½½æ›´æ—©**(P2,`data-spec="deploy-log-earlier"`;读当å‰çª—å£ä¹‹å‰ä¸€é¡µï¼ˆ256KB)并è£é½å‰ç½®æ‹¼æŽ¥ï¼›è‡ªåŠ¨åˆ·æ–°å¼€å¯/请求ä¸/已到窗å£èµ·ç‚¹/累计超 2MB æ—¶ç¦ç”¨ï¼ŒåŽŸå› è§ title 与æç¤ºè¡Œï¼‰
- 按钮:**下载**(P2,`data-spec="deploy-log-download"`;导出当å‰çª—å£å†…容为 `{文件å}.{时间戳}.log`;内容为空时ç¦ç”¨ï¼‰
5. **错误区**:`message` 全文,å±é™©è‰²ï¼Œå¸¦ `data-spec="deploy-log-error"`
6. **æˆªæ–æç¤º**(仅当 `truncated === true`):说明当å‰ä»…为尾部片段,更大范围åŽç»ç‰ˆæœ¬æ”¯æŒ
7. **内容区**:`<pre>` ç‰å®½ã€å¯æ»šåŠ¨ï¼ˆå»ºè®® max-height ~420px)ã€`whitespace-pre-wrap`,显示 tail æ–‡æœ¬ï¼›åŠ è½½ä¸æ˜¾ç¤ºã€Œè¯»å–ä¸â€¦ã€ï¼Œæ— 内容显示「—ã€
**行为**
| 事件 | 行为 |
|------|------|
| 打开抽屉 | æ¸…ç©ºä¸Šæ¬¡é€‰ä¸æ–‡ä»¶ä¸Žå†…容;调用 `LogFiles`;若有文件则默认选第一项并自动 `LogTail` |
| åˆ‡æ¢æ–‡ä»¶ | 自动 `LogTail`(é‡ç½®å¢žé‡åŸºçº¿ï¼‰ |
| 点击刷新 | 釿–° `LogFiles` + å¿…è¦æ—¶ `LogTail`(整体替æ¢ï¼Œä¸å¢žé‡ï¼‰ |
| å¼€å¯è‡ªåŠ¨åˆ·æ–° | ç«‹å³æ‹‰ä¸€æ¬¡ç»™åé¦ˆï¼Œç„¶åŽæŒ‰é—´éš”定时轮询;轮询带 `offset=上次 file_size`ï¼Œç» `applyTailSnapshot` åˆå¹¶ï¼ˆoffset 接ç»ä¸”æ–‡ä»¶æœªå›žå· â†’ è¿½åŠ æ–°å¢žï¼Œå¦åˆ™æ•´ä½“替æ¢ï¼‰ï¼›è¿›è¡Œä¸è·³è¿‡ä¸‹ä¸€æ‹ï¼Œé˜²è¯·æ±‚å †ç§¯ |
| 轮询失败 | **è‡ªåŠ¨åœæ¢**轮询,错误区显示 `{message}ï¼ˆè‡ªåŠ¨åˆ·æ–°å·²åœæ¢ï¼‰` |
| 调整间隔 | ç«‹å³æŒ‰æ–°é—´éš”é‡å¯å®šæ—¶å™¨ï¼ˆä¸é‡ç½®å†…容) |
| åŠ è½½æ›´æ—© | 以 `offset=max(1, 窗å£èµ·ç‚¹-256KB)` 读一页,与当å‰çª—å£å–交集è£é½åŽå‰ç½®æ‹¼æŽ¥ï¼ˆ`prependTailPage`);窗å£èµ·ç‚¹æ›´æ–°ä¸ºæœ¬é¡µ offset。**è‡ªåŠ¨åˆ·æ–°å¼€å¯æ—¶ç¦ç”¨**(轮询的替æ¢è¯ä¹‰ä¼šå†²æŽ‰å›žçœ‹å†…容);Agent offset=0 è¯ä¹‰æ˜¯ã€Œè¯»å°¾éƒ¨ã€ï¼Œæ•…文件开头 0 å—节窗å£ä¸å¯è¾¾ï¼ˆwindowStart≤1 æ—¶ç¦ç”¨å¹¶æç¤ºï¼‰ |
| 下载 | 导出当å‰çª—å£å†…容(Blob + a.download,`{文件å}.{yyyyMMddHHmmss}.log`);Agent 啿¬¡æœ€å¤š 512KBï¼Œå¯¼å‡ºçš„æ˜¯æŠ½å±‰å·²åŠ è½½å†…å®¹è€Œéžæ•´æ–‡ä»¶ |
| 关闿н屉 / 组件å¸è½½ | åœæ¢å®šæ—¶å™¨ï¼›é‡å¼€æŠ½å±‰è‹¥å¼€å…³ä»å¼€å¯åˆ™ç»§ç»è½®è¯¢ |
**Loading**
- 列表请求ä¸ï¼šç¦ç”¨ä¸‹æ‹‰ä¸Žåˆ·æ–°ï¼Œæˆ–å±•ç¤ºã€ŒåŠ è½½ä¸â€¦ã€
- Tail 请求ä¸ï¼šåˆ·æ–°æŒ‰é’®å¯æ˜¾ç¤ºã€ŒåŠ è½½ä¸â€¦ã€ï¼›å†…å®¹åŒºå¯æ˜¾ç¤ºã€Œè¯»å–ä¸â€¦ã€
### 3.2 部署节点表å•å—æ®µ
在 `NodeFormDrawer`(deploy)ä¸å·²æœ‰è§„æ ¼ï¼Œæ–°é¡µé¢éœ€ä¿æŒä¸€è‡´ï¼š
| å—æ®µ | 控件 | å ä½ / 说明 |
|------|------|-------------|
| 日志目录 | å•行文本 | placeholder:`如 logs 或 D:/app/logs`ï¼›hint:空=è·Ÿéšéƒ¨ç½²é›†ï¼›ç›¸å¯¹è·¯å¾„基于工作目录 |
| æ—¥å¿—æ–‡ä»¶åŒ¹é… | å•行文本 | 默认展示/å ä½ `*.log` |
ä¿å˜ï¼šèµ°çŽ°æœ‰éƒ¨ç½²èŠ‚ç‚¹ PUT/POST API(`deploy.logic` çš„ `deployNodePutBody` å·²å« `logDirectory` / `logFilePattern`)。
### 3.3 部署集级默认(建议 P1 è¡¥é½ï¼‰
åŽç«¯ `AppDeploy` 已有 `LogDirectory`ã€`LogFilePattern`。å‰ç«¯ **DeployEditDrawer / DeployEditModel** 当剿œªæ˜ 射,建议在 P1 一并补上,é¿å…åªèƒ½é€èŠ‚ç‚¹é…置:
- `toDeployEditModel` / `deployPutBody` å¢žåŠ ä¸¤å—æ®µ
- 表å•å¢žåŠ ä¸ŽèŠ‚ç‚¹è¡¨å•相åŒè¯ä¹‰çš„两行输入
若本è¿ä»£ä¸åšï¼Œéœ€åœ¨éƒ¨ç½²èŠ‚ç‚¹è¯´æ˜Žä¸å†™æ¸…「部署集默认请在旧版 MVC 或数æ®åº“é…ç½®ã€ï¼Œå¹¶åœ¨ã€Œæœªé…ç½®ã€é”™è¯¯ä¸é“¾åˆ°ç¼–辑抽屉。
---
## 4. 接å£å¥‘约(WebApi)
基础路径:与现有 Console ä¸€è‡´ï¼Œç» `@newlifex/cube-vue` çš„ `request`,å‰ç¼€ä¸€èˆ¬ä¸º **`/api`**(以项目 `request` å°è£…为准)。
### 4.1 列表文件
```http
GET /Deployment/AppDeployNode/LogFiles?id={deployNodeId}
```
**æƒé™**:`AppDeployNode` **Detail**(与 Cube æƒé™ä½“系一致)。
**æˆåŠŸ**(`code === 0`,`data` 为列表结果):
```json
{
"files": [
{ "name": "app.log", "size": 12345, "lastWriteUtc": "2026-11-03T02:00:00Z" }
]
}
```
åŽç«¯ C# å¯èƒ½åºåˆ—化为 PascalCaseï¼›å‰ç«¯ **å¿…é¡»** åŒæ—¶å…¼å®¹ `Name`/`name`ã€`Size`/`size`ã€`LastWriteUtc`/`lastWriteUtc`ï¼ˆè§ `deployLog.logic.ts` çš„ `pick`)。
**失败**(`code !== 0` 或 HTTP 异常):
- 典型:`Log directory is not configured for this deploy node...`(未é…置目录)
- 典型:`Timed out waiting for the node...`(节点离线 / Agent 未å“应)
- 典型:`æ— æƒæ“作`(StarWebApi 应用 `AllowControlNodes`)
- 典型:`[{id}]ä¸å˜åœ¨`ï¼ˆæ— æ•ˆ deployNodeId)
å‰ç«¯ï¼š**åŽŸæ ·å±•ç¤º** `message`ï¼ˆç» `okRes` è§£æžï¼‰ï¼Œä¸è¦åžæŽ‰ã€‚
### 4.2 读å–尾部
```http
GET /Deployment/AppDeployNode/LogTail?id={deployNodeId}&file={fileName}&offset=0&maxBytes=262144
```
| 傿•° | 说明 |
|------|------|
| `file` | **仅文件å**ï¼Œæ— è·¯å¾„ã€æ— `..` |
| `offset` | P1 å›ºå®šä¼ `0`(读尾部逻辑在 Agentï¼›P2 å†åšå‘上翻页) |
| `maxBytes` | 默认 `262144`(256KB),与åŽç«¯é»˜è®¤ä¸€è‡´ï¼›ä¸Šé™ 512KB |
**æˆåŠŸ** `data`:
```json
{
"content": "....",
"offset": 0,
"fileSize": 999999,
"truncated": false
}
```
åŒæ ·å…¼å®¹ PascalCase。`truncated === true` æ—¶å±•ç¤ºæˆªæ–æç¤ºã€‚
**失败**:
- æœªä¼ `file`:`请指定日志文件å`
- 其它åŒåˆ—表接å£
### 4.3 ä¿¡å°è§£æž
统一使用 `okRes(res)`(`appsModel.ts`):
- æˆåŠŸï¼š`code === 0 | 200 | 1` 或 `success === true`
- 失败:展示 `message`,**ä¸è¦**把 `code !== 0` 当æˆåŠŸ
业务逻辑层建议独立在 **`deployLog.logic.ts`**(便于 Vitest),组件åªè´Ÿè´£ UI 状æ€ã€‚
---
## 5. 状æ€ä¸Žæ–‡æ¡ˆ
### 5.1 å‰ç«¯æœ¬åœ°æ ¡éªŒï¼ˆlogic 层)
| æ¡ä»¶ | 文案 |
|------|------|
| `deployNodeId <= 0` | ç¼ºå°‘éƒ¨ç½²èŠ‚ç‚¹ç¼–å· |
| tail 时 file 为空 | 请选择日志文件 |
### 5.2 åŽç«¯/网络错误(展示 message,å¯è¡¥å……æ“作指引)
| 用户å¯è§å…³é”®è¯ | å»ºè®®ç•Œé¢æç¤ºï¼ˆå¯é€‰ç¬¬äºŒè¡Œï¼‰ |
|----------------|----------------------------|
| Log directory / 未é…ç½® | 请在部署节点(或部署集)编辑ä¸å¡«å†™æ—¥å¿—目录 |
| Timed out / è¶…æ—¶ | 检查节点是å¦åœ¨çº¿ã€StarAgent 是å¦å·²å‡çº§åˆ°å« deploy/log 的版本 |
| æ— æƒæ“作 | è”系管ç†å‘˜é…ç½® StarWebApi çš„ AllowControlNodes |
| 节点失败 / Empty response | 展示原文;æç¤ºæŸ¥çœ‹èŠ‚ç‚¹ Agent 日志 |
### 5.3 空数æ®
| 情况 | 展示 |
|------|------|
| `files.length === 0` 且æˆåŠŸ | ä¸‹æ‹‰ã€Œæ— åŒ¹é…æ–‡ä»¶ã€ï¼›å†…容区「—〠|
| 目录å˜åœ¨ä½† pattern æ— åŒ¹é… | åŒä¸Š |
---
## 6. æƒé™ä¸Žå®‰å…¨
- 仅登录且具备 **部署节点 Detail** 的用户å¯è°ƒç”¨ LogFiles/LogTail。
- å‰ç«¯ä¸æ‹¼æŽ¥ shellã€ä¸é€šè¿‡ bash 读文件。
- 文件åä»…æ¥è‡ªä¸‹æ‹‰é€‰é¡¹ï¼ˆAgent 列表结果),ä¸è®©ç”¨æˆ·è‡ªç”±è¾“入路径(防 `../`)。
- P1 ä¸åœ¨æµè§ˆå™¨æŒä¹…化日志内容。
---
## 7. 与 Vue 釿ž„çš„è½åœ°æ˜ å°„
仓库 **Stardust.Web.Vue** 内已有 P1 å‚考实现,新 Console å¼€å‘应**è¿ç§»æˆ–å¤ç”¨**,é¿å…é‡å¤é€ è½®å:
| èŒè´£ | 路径 |
|------|------|
| API + è§£æž | `src/layouts/StardustLayout2/deployLog.logic.ts` |
| 啿µ‹ | `src/layouts/StardustLayout2/deployLog.logic.test.ts` |
| 抽屉 UI | `src/layouts/StardustLayout2/DeployLogDrawer.vue` |
| è¡¨æ ¼ã€ŒæŸ¥çœ‹æ—¥å¿—ã€ | `src/layouts/StardustLayout2/DeployNodes.vue`(`data-spec="ship-node-logs"`) |
| 容器接线 | `apps/stardust/src/views/Console/ShipPanel.vue` |
| 节点é…ç½® | `src/layouts/StardustLayout2/NodeFormDrawer.vue`(`data-spec="node-form-logdir"`) |
| 节点 CRUD å—æ®µæ˜ å°„ | `src/layouts/StardustLayout2/deploy.logic.ts` |
**设计系统**:使用 StardustLayout2 现有 `Drawer`ã€`Btn`ã€CSS å˜é‡ï¼ˆ`--el-*`),与 `ShipPanel` / 部署节点表一致。
**组件测试 / E2E**:为关键 DOM ä¿ç•™ `data-spec`:
- `deploy-log-drawer`
- `deploy-log-file-select`
- `deploy-log-refresh`
- `deploy-log-error`
- `deploy-log-content`
---
## 8. éªŒæ”¶æ ‡å‡†ï¼ˆP1)
### 8.1 功能
- [ ] åœ¨åº”ç”¨å·¥ä½œå° â†’ 部署 → 部署节点,æ¯è¡Œå¯ç‚¹ã€ŒæŸ¥çœ‹æ—¥å¿—ã€ï¼Œæ‰“开抽屉。
- [ ] å·²é…置日志目录且节点在线ã€Agent å·²å‡çº§ï¼šåˆ—出文件,默认选ä¸ç¬¬ä¸€ä¸ªï¼Œå±•示 tail 内容。
- [ ] åˆ‡æ¢æ–‡ä»¶åŽå†…容更新。
- [ ] 点击刷新åŽåˆ—表与内容更新。
- [ ] 未é…置目录:抽屉内展示明确错误,且ä¸å‡è£…æˆåŠŸã€‚
- [ ] 节点离线或超时:展示超时类错误。
- [ ] 部署节点编辑å¯ä¿å˜ `logDirectory` / `logFilePattern`,ä¿å˜åŽå†æ¬¡æ‰“开日志生效(需åŽç«¯ä¸Ž Agent é…åˆï¼‰ã€‚
### 8.2 éžåŠŸèƒ½
- [ ] `deployLog.logic.test.ts` 全部通过。
- [ ] 与 `AppLog` é¡µç¾æ–‡æ¡ˆ/æ ‡é¢˜åŒºåˆ†æ¸…æ™°ï¼Œç”¨æˆ·ä¸ä¼šè¯¯ä»¥ä¸ºæ˜¯åŒä¸€æ•°æ®æºã€‚
- [ ] æ— æƒé™æ—¶é”™è¯¯å¯è§ã€‚
### 8.3 è”è°ƒ
- åŽç«¯/automationï¼šè§ DEPLOY-1 §9(L0/L1/L2ï¼‰ï¼›å…¨é“¾è·¯æœ¬æœºè§ DEPLOY-2 L3。
- å‰ç«¯ logic 啿µ‹ä¸ä¾èµ–真实 Agent。
---
## 9. 测试用例摘è¦ï¼ˆå‰ç«¯ï¼‰
| ç¼–å· | 场景 | 预期 |
|------|------|------|
| F-01 | `fetchDeployLogFiles(id=0)` | ok=falseï¼Œç¼ºå°‘éƒ¨ç½²èŠ‚ç‚¹ç¼–å· |
| F-02 | LogFiles 返回 code≠0 | message é€ä¼ ,files=[] |
| F-03 | LogFiles 返回 PascalCase files | æ˜ å°„ä¸º name/size/lastWriteUtc |
| F-04 | tail 空文件å | ok=false,请选择日志文件 |
| F-05 | tail æˆåŠŸ truncated | UI æ˜¾ç¤ºæˆªæ–æç¤º |
| F-06 | 打开抽屉 | 自动请求 LogFiles + 首文件 LogTail |
| F-07 | deploy.logic 节点 body | å« logDirectoryã€logFilePattern |
| F-08 | `applyTailSnapshot` 首读(上次 file_size=0) | 整体替æ¢ï¼Œéžè¿½åŠ |
| F-09 | offset 接ç»ä¸Šæ¬¡ file_size 且文件增长 | è¿½åŠ æ–°å¢žå†…å®¹ |
| F-10 | offset 䏿ޥç»ï¼ˆæ— 新增回读尾部 / 回å·å˜å°ï¼‰ | 整体替æ¢ï¼Œä¸é‡å¤æ‹¼æŽ¥ |
| F-11 | è¿½åŠ è¶…è¿‡ 1MB ä¸Šé™ | 从头截æ–到 `MAX_TAIL_KEEP` |
| F-12 | 轮询请求失败 | 自动刷新关é—,错误区å«ã€Œè‡ªåŠ¨åˆ·æ–°å·²åœæ¢ã€ |
| F-13 | 文件大å°å‹å¥½æ ¼å¼ | 0 B / 999 B / 1.0 KB / 1.5 MB(`formatFileSize`) |
| F-14 | å‘上翻页 | `earlierOffset` 最å°ä¸º 1ï¼›`canLoadEarlier`:windowStart>1 且累计 <2MBï¼›`prependTailPage` 与窗å£äº¤é›†è£é½å‰ç½®æ‹¼æŽ¥ã€é‡å ä¸é‡å¤ |
| F-15 | 下载 | 当å‰çª—å£å†…容导出 `.log`;内容为空时按钮ç¦ç”¨ |
ï¼ˆå®žçŽ°è§ `deployLog.logic.test.ts`(20 用例)ã€`deploy.logic.test.ts`。MCP å·¥å…·é›†æˆæµ‹è¯•è§ DEPLOY-1 §9。)
---
## 10. ä¾èµ–与å‘布说明
| ä¾èµ– | 说明 |
|------|------|
| StarWebApi | LogFiles / LogTail å·²å‘布 |
| StarServer | Node/SendCommand é€šé“ |
| StarAgent | éœ€å« `deploy/log/list|tail`(与 WebApi åŒæ‰¹æ¬¡æˆ–æ›´æ—©å‡çº§èŠ‚ç‚¹ï¼‰ |
| é…ç½® | StarWebApi `AllowControlNodes`ã€AppDeployNode 日志目录 |
å‰ç«¯é™æ€èµ„æºå•独å‘布时,**ä»…å‘å‰ç«¯ä¸ä¼šç”Ÿæ•ˆ**,必须ä¿è¯ API 与 Agent 能力已上线。
---
## 11. 附录:与应用工作å°é¡µç¾å¯¹ç…§
| é¡µç¾ | 组件 | æ•°æ®æº | 本需求 |
|------|------|--------|--------|
| 日志 | `AppLog.vue` | AppClientLog 分表 | å¦ |
| 部署 → 节点 | `DeployLogDrawer` | 节点ç£ç›˜æ–‡ä»¶ | **是** |
äº§å“æ–‡æ¡ˆå»ºè®®ï¼š
- 页ç¾ã€Œæ—¥å¿—ã€â†’ **应用日志(SDK 上报)**
- 抽屉「节点文件日志ã€â†’ **节点本地文件**
---
## 12. å˜æ›´è®°å½•
| 日期 | 说明 |
|------|------|
| 2026-11-03 | åˆç‰ˆï¼šå¯¹é½ DEPLOY-1ã€Stardust.Web.Vue å‚考实现与 Console ShipPanel 接线 |
| 2026-11-04 | P2/P3 交付:自动轮询开关 + 1~5s 间隔下拉;`applyTailSnapshot` 增é‡åˆå¹¶ï¼ˆ1MB å°é¡¶ï¼‰ï¼›å¤±è´¥è‡ªåŠ¨åœæ¢ã€‚测试 F-08~F-12 |
| 2026-11-04(二) | P2 é—留交付:å‘上翻页(256KB/页ã€ç´¯è®¡ 2MB 上é™ã€ä¸Žè‡ªåŠ¨åˆ·æ–°äº’æ–¥ï¼‰ã€ä¸‹è½½å½“å‰çª—å£ã€æ–‡ä»¶å¤§å°å‹å¥½æ ¼å¼ã€‚测试 F-13~F-15 |
|