Add ZIP compression details to Dump Controller Log analysis
This commit is contained in:
@@ -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();
|
||||||
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user