日志管理

更新时间:2023-09-06 10:40:14下载pdf

TuyaOS 提供分级别的日志记录功能,您可以自由选择输出媒介(串口、文件、终端、网络等)。同时,涂鸦运营平台支持远程获取设备本地日志,遇到线上问题可以通过分析设备本地日志来排查问题。

设备本地日志功能是 IoT 网关产品的一个关键功能,日志记录了异常的现场,为分析问题提供关键线索,建议您在网关产品上使用该功能。

日志管理

适配日志接口

TuyaOS 只负责日志输出的消息格式化,提供了 TuyaOS Kernel 标准接口 tkl_output.h,由应用来实现通过具体的媒介输出日志的内容。

TuyaOS 的默认输出终端是调用 tkl_log_output 接口,应用需要在该接口中实现日志输出功能。

例如:

  • 把日志打印到终端:

    VOID_T tkl_log_output(IN CONST CHAR_T *str, ...)
    {
    	printf("%s", str);
    	fflush(stdout);
    	return;
    }
    
  • 把日志保存到文件:

    VOID_T tkl_log_output(IN CONST CHAR_T *str, ...)
    {
    	uFILE * fp = NULL;
    
    	// 打开文件
    	fp = ufopen("log.txt", "w+");
    	if(NULL == fp) {
    		return ;
    	}
    
    	// 写入文件
    	uiWriteCnt = ufwrite(fp, str, strlen(str));
    	if(uiWriteCnt != strlen(str)) {
    		TAL_PR_ERR("log uf file write data error!");
    		return ;
    	}
    
    	// 关闭文件
    	ufclose(fp);
    
    	return;
    }
    

设置输出等级

运行 TuyaOS 之后,您可以调用 tal_log_set_manage_attr 接口设置日志输出阈值,小于或等于设置的阈值都会被输出,输出等级定义如下:

宏定义 说明
TAL_LOG_LEVEL_ERR 输出阈值为错误日志
TAL_LOG_LEVEL_WARN 输出阈值为警告日志
TAL_LOG_LEVEL_NOTICE 输出阈值为通知日志
TAL_LOG_LEVEL_INFO 输出阈值为信息日志
TAL_LOG_LEVEL_DEBUG 输出阈值为调试日志
TAL_LOG_LEVEL_TRACE 输出阈值为跟踪日志

使用示例:

#include "tal_log.h"

int main(int argc, char **argv)
{
	OPERATE_RET rt = OPRT_OK;

	// 初始化 TuyaOS
	TUYA_CALL_ERR_RETURN(tuya_iot_init("./"));

	// 日志等级设置为调试
	tal_log_set_manage_attr(TAL_LOG_LEVEL_DEBUG);

	// ...

	return 0;
}

日志输出宏

TuyaOS 提供了日志输出接口,您可以调用日志输出接口输出应用的日志,以便统一管理输出日志。

宏定义 说明
PR_DEBUG 输出调试日志
PR_DEBUG_RAW 输出调试日志(未格式化的 RAW 消息)
PR_ERR 输出错误日志
PR_WARN 输出警告日志
PR_INFO 输出信息日志
PR_TRACE 输出跟踪日志

使用示例:

VOID test_log(VOID)
{
	BYTE_T test_buf[8] = {0};

	tal_log_set_manage_attr(TAL_LOG_LEVEL_TRACE);
	PR_TRACE("This is a trace message");

	tal_log_set_manage_attr(TAL_LOG_LEVEL_DEBUG);
	PR_DEBUG("This is a debug message");
	PR_ERR("This is an error message");
	PR_WARN("This is a warning message");
	PR_INFO("This is an info message");

	PR_DEBUG("PR_DEBUG_RAW:");
	for (INT_T i = 0; i < sizeof(test_buf); i++) {
		PR_DEBUG_RAW("%02x ", test_buf[i]);
	}
	PR_DEBUG_RAW("\r\n");

    return;
}

本地日志

本地日志是指通过涂鸦运营平台获取设备本地日志,您需要把日志输出保存到文件中,通过远程拉取本地日志时,把日志文件上传到云端。

设备本地日志是一个非常重要的功能,因为它能为排查线上问题提供非常重要的线索,为了能够记录详细的信息,建议日志等级设置成调试。

如果把所有日志都保存到文件,那么随时间推移文件会越来越大,最终导致设备存储空间不足。

通常的实现方法是,设备预留一定的空间(如 2 MB 持久化存储区)来备份日志,日志输出保存到内存中,当内存中的文件超过一定大小(如 128 KB / 256 KB 等)则把日志文件压缩转存到持久化存储区,以当前时间作为文件名称。定期地检查持久化存储区,当超过设置的阈值,则把最旧的备份文件删除,腾出空间存储新日志。

实现设备本地日志功能很简单,只需要注册拉取本地日志回调,在回调中把最新的日志以及持久化存储区的备份日志压缩到一个文件,并把该日志文件给到 SDK,由 SDK 上传到云端。

使用示例:

STATIC VOID __gw_log_path_cb(OUT CHAR_T *path, IN CONST INT_T len)
{
	CHAR_T cmd[128] = {0};
	snprintf(cmd, SIZEOF(cmd), "cp -fr /tmp/tuya.log ./log_dir/; tar zcvf /tmp/tuya_log.tgz ./log_dir/*");
	system(cmd);

	strncpy(path, "/tmp/tuya_log.tgz", len);
}

VOID test_get_log_file(VOID)
{
	TY_GW_APP_CBS_S __gw_app_cbs = {
		.gw_log_path_cb = __gw_log_path_cb,
	};
	tuya_iot_reg_gw_app_cb(&__gw_app_cbs);
}