Add ZIP compression details to Dump Controller Log analysis

This commit is contained in:
accusys
2026-03-29 00:48:44 +08:00
parent adcceb874d
commit c74f5a7001
+158
View File
@@ -159,3 +159,161 @@ dumpEventLog(Cdb)
→ parse status & data → parse status & data
→ close() → close()
``` ```
---
## ZIP 壓縮處理細節
### 輸出檔案
**dlgDumpLog.java (舊型號)**
```
./Log/{SN}_ControllerLog_{YYYY}_{M}_{D}_{H}_{m}_{s}.zip
```
**dlgDumpLog2.java (新型號)**
```
Primary: ./Log/Primary_{SN}_ControllerLog.zip
Secondary: ./Log/Secondary_{SN}_ControllerLog.zip
合併: ./Log/{PrimarySN}_{SecondarySN}_ControllerLog_{YYYY}_{M}_{D}_{H}_{m}_{s}.zip
```
### 壓縮前的暫存檔
| Page Code | 檔案名稱 | 說明 |
|-----------|----------|------|
| 0x60 | EventPage.bin | Event Log |
| 0x61 | DebugPage.bin | Debug Log |
| 0x62 | DiskMetadataPage.bin | Disk Metadata |
| 0x63 | SpecialLogPage.bin | Special Log |
| 0x64 | TelMesPages.log | Telemetry Messages |
### compressLog() 流程 (dlgDumpLog.java)
```java
public void compressLog() {
File[] logs = new File[5];
for(int i=0; i<=4; i++) {
logs[i] = getFile((byte)(i+0x60)); // 取得 5 個暫存檔
}
// 建立 ZIP 檔案
Calendar rightNow = Calendar.getInstance();
String filename = "./Log/" + PageDataDB.sSN.trim() + "_ControllerLog_"
+ rightNow.get(Calendar.YEAR) + "_"
+ (rightNow.get(Calendar.MONTH)+1) + "_"
+ rightNow.get(Calendar.DAY_OF_MONTH) + "_"
+ rightNow.get(Calendar.HOUR) + "_"
+ rightNow.get(Calendar.MINUTE) + "_"
+ rightNow.get(Calendar.SECOND) + ".zip";
FileOutputStream fout = new FileOutputStream(filename);
ZipOutputStream zout = new ZipOutputStream(fout);
zout.setLevel(5); // 壓縮等級 0-9
// 逐一壓縮每個檔案
for (byte i = 0; i <= 4; i++) {
if(logs[i].exists()) {
ZipEntry ze = new ZipEntry(logs[i].getName());
FileInputStream fin = new FileInputStream(logs[i]);
zout.putNextEntry(ze);
// 特殊處理 Page 0x64 (TelMesPages.log)
if(i != 0x4) {
// 一般檔案:直接複製
for(int c = fin.read(); c != -1; c = fin.read()) {
zout.write(c);
}
} else {
// TelMesPages.log: 每 40 bytes 為一筆記錄
// 移除空字元 (0x00),只保留有效資料
byte data;
boolean skipNull = false;
for(int j=0; j < logs[i].length()/40; j++) {
skipNull = false;
for(int k=0; k<40; k++) {
data = (byte)fin.read();
if(data == 0x0a || skipNull == true) {
skipNull = true;
} else {
zout.write(data);
}
}
zout.write(0x0a); // 加上換行符
}
}
zout.closeEntry();
fin.close();
logs[i].delete(); // 刪除暫存檔
}
}
zout.close();
}
```
### compressLog() 流程 (dlgDumpLog2.java)
```java
// 單一控制器壓縮
public void compressLog(String sSN) {
String prefix = sSN.equals(PageDataDB.sSN) ? "Primary" : "Secondary";
String filename = "./Log/" + prefix + "_" + sSN.trim() + "_ControllerLog.zip";
// ... 同上邏輯
}
// 雙控制器合併壓縮
public void compressLog2() {
File[] logs = new File[2];
logs[0] = new File(sMaterFileNamePatch); // Primary
logs[1] = new File(sSlaveFileNamePatch); // Secondary
// 合併成單一 ZIP,內含兩個 ZIP 檔
String filename = "./Log/" + PageDataDB.sSN.trim() + "_"
+ PageDataDB.sSlaveSN.trim() + "_ControllerLog_{timestamp}.zip";
// ...
}
```
### ZIP 結構
```
Archive: {SN}_ControllerLog_2024_3_29_10_30_45.zip
├── EventPage.bin (512 bytes/block)
├── DebugPage.bin (512 bytes/block)
├── DiskMetadataPage.bin (512 bytes/block)
├── SpecialLogPage.bin (512 bytes/block)
└── TelMesPages.log (40 bytes/record, 去除 null)
```
### 特殊處理:TelMesPages.log (Page 0x64)
```java
// 原始資料: 40 bytes/record,包含 null (0x00) 字元
// 處理邏輯:
// 1. 讀取每 40 bytes
// 2. 跳過開頭的 null 字元
// 3. 遇到換行符 (0x0a) 後,後續全部視為有效資料
// 4. 輸出時每筆記錄加上換行符
// Example:
// Input: [0x00, 0x00, 0x00, 0x31, 0x32, ..., 0x00, 0x00]
// Output: "12...data\n"
```
### Java 類別使用
```java
import java.util.zip.ZipOutputStream;
import java.util.zip.ZipEntry;
import java.util.Calendar;
// 關鍵類別
ZipOutputStream zout = new ZipOutputStream(fout);
zout.setLevel(5); // 壓縮等級 (0=儲存, 9=最大壓縮)
ZipEntry ze = new ZipEntry(filename);
zout.putNextEntry(ze);
zout.write(byte[] data);
zout.closeEntry();
zout.close();
```