Files
rust_raidguardx/GC_DumpControllerLog.md
T
2026-03-29 00:41:29 +08:00

162 lines
4.8 KiB
Markdown

# Dump Controller Log 實現分析
## 流程架構
```
┌─────────────────────────────────────────────────────────────┐
│ frmMain.jmDumpEventLog_actionPerformed() │
│ (根據型號選擇使用 dlgDumpLog 或 dlgDumpLog2) │
└──────────────────────────┬──────────────────────────────────┘
┌───────────────┴───────────────┐
▼ ▼
┌──────────────┐ ┌──────────────┐
│ dlgDumpLog │ │ dlgDumpLog2 │
│ (舊型號) │ │ (新型號) │
└──────────────┘ └──────────────┘
│ │
└───────────┬───────────────────┘
┌──────────────────────────┐
│ dumpEventLog() │
│ TCP 連線 Port 8922 │
└───────────┬──────────────┘
┌──────────────────────────┐
│ OpCode: 0x01 │
│ SubOp: 0x03 │
│ Page: 0x60 ~ 0x64 │
└───────────┬──────────────┘
┌──────────────────────────┐
│ 寫入 ./Log 目錄 │
│ 壓縮為 ZIP 檔 │
└──────────────────────────┘
```
## 通訊協定
### Request
```
Head: [0x01, 0x17, 0x00, 0x00, 0x00] (23 bytes)
Data: [0x02, 0x01, SN(16 bytes), CDB(5 bytes)]
```
### CDB 結構
| Offset | 值 | 說明 |
|--------|-----|------|
| 0 | 0x01 | OpCode - GET_PAGE |
| 1 | 0x03 | SubOp |
| 2 | 0x60-0x64 | Page Code (Log Type) |
| 3 | LSB | Block Index |
| 4 | MSB | Block Index |
### Log Types
| Page | 說明 |
|------|------|
| 0x60 | System Log |
| 0x61 | Event Log |
| 0x62 | I/O Error Log |
| 0x63 | Dump Log |
| 0x64 | Reserved |
## 實現細節
### dlgDumpLog.java
```java
// 1. 連線到控制器
theSocket.connect(new InetSocketAddress(PageDataDB.GuiSrvIpAddr, Port), 10000);
// 2. 發送请求 (OpCode 0x01, SubOp 0x03)
Cdb[0] = 0x01; // GET_PAGE
Cdb[1] = 0x03; // SubOp
Cdb[2] = 0x60; // Log type (0x60-0x64)
Cdb[3] = BlockIndexLSB;
Cdb[4] = BlockIndexMSB;
// 3. 解析回應
arg[0] = reply[9]; // Status (0x50 = Success)
arg[1] = reply[12]; // Page code
arg[2] = startBlock;
arg[3] = totalBlocks;
// 4. 寫入檔案 (./Log 目錄)
File file = getFile((byte)arg[1]);
fileOut.write(reply, 15, 512); // 寫入 512 bytes
// 5. 壓縮成 ZIP
compressLog(); // 打包成 Log_YYYYMMDD_HHMMSS.zip
```
### 迴圈邏輯
```java
// 遍历 5 種 log 類型
for (byte i = 0x60; i <= 0x64; i++) {
// 取得該類型的 log 總量
arg1 = dumpEventLog(Cdb);
// 遍历每個 block
for (int j = arg1[2]; j < arg1[3]; j++) {
Cdb[3] = (byte)(j & 0xFF); // LSB
Cdb[4] = (byte)((j >> 8) & 0xFF); // MSB
arg2 = dumpEventLog(Cdb);
// 寫入單個 block
fileOut.write(reply, 15, 512);
}
}
```
## 輸出檔案
- **目錄**: `./Log/`
- **格式**: `Log_YYYYMMDD_HHMMSS.zip`
- **內容**: 5 個 log 類型的原始資料 (各 512 bytes/block)
## 關鍵類
| 類別 | 檔案 | 功能 |
|------|------|------|
| `frmMain` | frmMain.java:4136 | 入口,選擇 dialog 版本 |
| `dlgDumpLog` | dlgDumpLog.java | 舊型號使用 (單一控制器) |
| `dlgDumpLog2` | dlgDumpLog2.java | 新型號使用 (支援多控制器) |
| `SendCmd` | InBandAPI/SendCmd.java | TCP 通訊底層 |
## Code Flow
### 1. Menu 點擊
```
frmMain.jmDumpControllerLog (MenuItem)
→ frmMain.jmDumpEventLog_actionPerformed()
→ 檢查型號選擇 dlgDumpLog 或 dlgDumpLog2
```
### 2. Dump 執行
```
dlgDumpLog.run()
→ for (0x60 ~ 0x64) {
dumpEventLog() 取得總量
for (每個 block) {
dumpEventLog() 取得資料
寫入檔案
}
}
→ compressLog() 壓縮
→ dispose()
```
### 3. Socket 通訊
```
dumpEventLog(Cdb)
→ connect(Port 8922)
→ send(Head + SN + CDB)
→ read(reply)
→ parse status & data
→ close()
```