本文檔詳細介紹TUTK P2P SDK的日志配置與調(diào)試方法,包括SDK庫版本區(qū)分、日志參數(shù)配置、自定義回調(diào)輸出、常見問題排查及問題與日志模塊對應(yīng)關(guān)系,幫助開發(fā)者快速定位設(shè)備掉線、連接失敗、數(shù)據(jù)傳輸異常等問題。
一、概述
SDK 提供正式版本和調(diào)試版本兩類庫文件,調(diào)試版本(庫名帶'T')支持日志抓取功能,默認寫入設(shè)備本地存儲。各模塊均提供獨立的日志配置接口,可靈活設(shè)置日志路徑、級別、文件大小限制等參數(shù),用于排查設(shè)備掉線、連接失敗、數(shù)據(jù)傳輸異常等問題。
核心說明:
- 1. 僅調(diào)試版本(帶'T'庫)支持日志輸出,正式版本無日志功能;
- 2. 日志配置需在模塊初始化前調(diào)用,確保生效;
- 3. 不同模塊需調(diào)用對應(yīng)日志接口,用到哪些模塊則配置哪些;
- 4. 支持日志文件輸出和自定義回調(diào)輸出兩種方式。
二、SDK庫版本說明
SDK 庫文件分為正式版本和調(diào)試版本,通過庫名是否包含后綴 'T' 區(qū)分:
| 版本類型 | 庫名示例 | 功能說明 | 適用場景 |
|---|
| 正式版本 | libIOTCAPIs.so、libAVAPIs.a | 無日志輸出,體積更小、性能更優(yōu) | 生產(chǎn)環(huán)境部署 |
| 調(diào)試版本 | libIOTCAPIsT.so、libAVAPIsT.a | 支持日志輸出,可配置日志參數(shù) | 開發(fā)調(diào)試、問題排查 |
三、日志配置使用
日志配置需在對應(yīng)模塊初始化前調(diào)用,核心通過 LogAttr 結(jié)構(gòu)體設(shè)置參數(shù),各模塊提供統(tǒng)一命名規(guī)范的日志接口:{ModuleName}_Set_Log_Attr。
(一)核心參數(shù)結(jié)構(gòu)體(LogAttr)
| 字段名 | 類型 | 說明 | 取值示例 |
|---|
| path | const char* | 日志文件路徑(含文件名),NULL 表示關(guān)閉日志 | "./log_iotc.txt" |
| log_level | logLevel_t | 日志級別(由細到粗) | LEVEL_VERBOSE/LEVEL_DEBUG/LEVEL_INFO/LEVEL_WARNING/LEVEL_ERROR/LEVEL_SILENCE |
| file_max_size | uint32_t | 單個日志文件最大大?。ㄗ止?jié)),0 表示無限制 | 1024*1024(1MB) |
| file_max_count | uint32_t | 日志文件最大個數(shù),0 表示無限制(循環(huán)覆蓋) | 5(最多保留5個日志文件) |
(二)IOTCAPIs 模塊配置示例(核心模塊)
// 1. 定義日志屬性結(jié)構(gòu)體并初始化
LogAttr logAttr;
memset(&logAttr, 0, sizeof(logAttr));
// 2. 配置日志參數(shù)
logAttr.path = "./log_iotc.txt"; // 日志文件路徑(含文件名),NULL 關(guān)閉日志
logAttr.log_level = LEVEL_VERBOSE; // 日志級別:最詳細(可按需調(diào)整)
logAttr.file_max_size = 0; // 單個文件無大小限制(0=無限制)
logAttr.file_max_count = 0; // 文件個數(shù)無限制(0=無限制)
// 3. 調(diào)用 IOTCAPIs 日志配置接口(模塊初始化前調(diào)用)
IOTC_Set_Log_Attr(logAttr);
(三)其他模塊日志配置示例
其他模塊日志配置方式與 IOTCAPIs 一致,需根據(jù)使用的模塊調(diào)用對應(yīng)接口,建議同時開啟依賴模塊的日志(如下方示例):
LogAttr logAttr;
memset(&logAttr, 0, sizeof(logAttr));
logAttr.log_level = LEVEL_VERBOSE; // 日志級別(統(tǒng)一配置為最詳細)
logAttr.file_max_size = 0; // 無大小限制
logAttr.file_max_count = 0; // 無個數(shù)限制
// 1. Global 模塊日志(基礎(chǔ)模塊,建議必開)
logAttr.path = "./log_global.txt";
TUTK_Set_Log_Attr(logAttr);
// 2. RDTAPIs 模塊日志(使用 RDT 相關(guān)功能時配置,需同時開 IOTC/Global)
logAttr.path = "./log_rdt.txt";
RDT_Set_Log_Attr(logAttr);
// 3. AVAPIs 模塊日志(使用 AV 通道功能時配置,需同時開 IOTC/Global)
logAttr.path = "./log_av.txt";
AV_Set_Log_Attr(logAttr);
// 4. P2PTunnelAPIs 模塊日志(使用 P2P 隧道功能時配置,需同時開 IOTC/RDT/Global)
logAttr.path = "./log_tunnel.txt";
P2PTunnel_Set_Log_Attr(logAttr);
// 5. Nebula 模塊日志(使用 Nebula 相關(guān)功能時配置)
logAttr.path = "./log_nebula.txt";
Nebula_Set_Log_Attr(logAttr);
特別注意
iOS 平臺所有庫已封裝為一個整體,必須通過上述對應(yīng)模塊的 Set_Log_Attr 接口明確設(shè)置日志路徑,否則無法輸出日志。
四、日志回調(diào)(自定義輸出)
除日志文件輸出外,SDK 支持通過回調(diào)函數(shù)自定義日志輸出方式(如打印到控制臺、上傳至服務(wù)器等),核心通過 TUTK_Set_Log_Callback 注冊回調(diào)。
(一)配置步驟
1. 設(shè)置日志級別(回調(diào)生效需先配置級別)
LogAttr logAttr;
memset(&logAttr, 0, sizeof(logAttr));
logAttr.log_level = LEVEL_VERBOSE; // 回調(diào)僅輸出配置級別及以上的日志
// 為需要的模塊設(shè)置日志級別(示例:Global/IOTC/AV 模塊)
TUTK_Set_Log_Attr(logAttr);
IOTC_Set_Log_Attr(logAttr);
AV_Set_Log_Attr(logAttr);
2. 回調(diào)函數(shù)定義與注冊
/*************** 回調(diào)函數(shù)原型定義 ***************/
// typedef void(*LogFunc)(const char *domName, logLevel_t level, const char *str);
// 參數(shù)說明:
// domName: 輸出日志的模塊名稱(如 "IOTC", "AV", "RDT")
// level: 日志級別(對應(yīng) logLevel_t 枚舉)
// str: 日志內(nèi)容字符串
/***********************************************/
// 自定義日志輸出回調(diào)函數(shù)
void LogOutFunc(const char *domName, logLevel_t level, const char *str)
{
if (str == NULL || domName == NULL) {
return;
}
// 按日志級別自定義輸出格式(示例:區(qū)分級別打印)
switch (level) {
case LEVEL_ERROR:
printf("[ERROR] SDK-%s: %s\n", domName, str);
// print_ERROR("SDK, domName:%s, %s", domName, str); // 項目自定義錯誤打印接口
break;
case LEVEL_WARNING:
printf("[WARNING] SDK-%s: %s\n", domName, str);
// print_WARNING("SDK, domName:%s, %s", domName, str);
break;
case LEVEL_INFO:
printf("[INFO] SDK-%s: %s\n", domName, str);
// print_INFO("SDK, domName:%s, %s", domName, str);
break;
case LEVEL_DEBUG:
printf("[DEBUG] SDK-%s: %s\n", domName, str);
// print_DEBUG("SDK, domName:%s, %s", domName, str);
break;
case LEVEL_VERBOSE:
printf("[VERBOSE] SDK-%s: %s\n", domName, str);
// print_VERBOSE("SDK, domName:%s, %s", domName, str);
break;
case LEVEL_SILENCE:
break; // 靜默級別,不輸出任何日志
default:
printf("[UNKNOWN] SDK-%s: %s\n", domName, str);
break;
}
}
// 注冊日志回調(diào)函數(shù)(需在模塊初始化前調(diào)用)
TUTK_Set_Log_Callback(LogOutFunc);
五、FAQ(常見問題)
1. 帶'T'的調(diào)試版本庫能否用于正式環(huán)境?
可以。將日志級別設(shè)置為 LEVEL_SILENCE 即可關(guān)閉日志輸出,性能與正式版本基本一致;后續(xù)需要排查問題時,可重新調(diào)整日志級別開啟日志。
2. SDK 日志可用于排查哪些問題?
- ① 設(shè)備掉線問題:僅需設(shè)備端日志;
- ② APP 連線問題:一般需要 APP 端 + 設(shè)備端日志;
- ③ 數(shù)據(jù)傳輸不順暢問題:一般需要 APP 端 + 設(shè)備端日志;
- ④ 特殊 API 報錯:根據(jù)報錯模塊判斷所需日志;
- ⑤ 崩潰問題:僅需崩潰發(fā)生端的日志。
3. 配置日志后無輸出,可能原因有哪些?
- ① 未使用帶'T'的調(diào)試版本庫;
- ② 日志路徑無寫入權(quán)限(如 iOS 沙盒路徑錯誤);
- ③ 日志級別設(shè)置過高(如設(shè)置為 LEVEL_ERROR,僅輸出錯誤日志);
- ④ 日志配置接口調(diào)用時機晚于模塊初始化;
- ⑤ iOS 平臺未通過對應(yīng)模塊接口設(shè)置日志路徑。
六、問題與日志對應(yīng)表(IOTCAPIs+AVAPIs 場景)
下表列出常見問題所需的日志模塊(√ 表示需要,空白表示不需要):
| 問題類型 | 客戶端日志 | 設(shè)備端日志 |
|---|
| IOTCAPIs | AVAPIs | GlobalAPIs | IOTCAPIs | AVAPIs | GlobalAPIs |
|---|
| 設(shè)備掉線 |
|
|
| √ | √ | √ |
| 設(shè)備在線,IOTC 無法連接 | √ |
| √ | √ |
| √ |
| IOTC 連線成功,AV 通道創(chuàng)建失敗 | √ | √ | √ | √ | √ | √ |
| 排查客戶端端口占用 | √ | √ | √ |
|
|
|
| 排查設(shè)備端端口占用 |
|
|
| √ | √ | √ |