软件产品的开发,测试和长期运维,离不开日志系统。uLog在AliOS Things中承担各个组件的日志记录和输出,主要特性如下: A. 遵循至简模式(默认)和syslog协议,日志记录包含下列要素:

  • 日志生成时间
  • 日志优先级
  • 日志产生源(子系统标识)
  • 日志Tag(模块名及在模块中的行号)
  • 日志内容

B. 日志的优先级可以按需选择静态编译包含或者动态控制(支持API CLI,服务端运维通道(3.1版本后)),方便在调试,测试,以及发布的产品现场Trouble-Shooting 时push出较多日志(低优先级日志准出),产品release时push较少日志避免影响系统功能(高优先级日志准出)

C. 日志抛出方式多样式,可以进行动态切换通道,也可以通道组合,每个通道的日志优先级独立可控:

  • 默认输出(嵌入式产品一般默认定向到串口)
  • syslog udp发送至监听设备
  • 具备文件回滚方式记录至文件系统
  • 经由云端通道上行至阿里云物联网运维服务控制台(AliOS Things3.1后)

D. 异步日志功能 uLog可选异步日志功能,则负责抛出日志控制的逻辑以低于其他任务(仅比idle任务高1个级别)在后台运行,避免影响应用任务运行。

API列表

ulog() 记录日志通用方法
LOG() 以Emergency级别记录日志的简要接口
LOGF() 以Fatal级别记录日志的简要接口
LOGE() 以Error级别记录日志的简要接口
LOGW() 以Warning级别记录日志的简要接口
LOGI() 以Info级别记录日志的简要接口
LOGD() 以Debug级别记录日志的简要接口
aos_set_log_level() 获取某个加密的键的值
ulog_man() 获取某个加密的键的值
aos_get_ulog_list() 获取某个加密的键的值

使用

添加该组件

ulog是AliOS Things 默认添加的组件,开发者无需再手动添加

包含头文件

#include "ulog/ulog.h"

使用示例

 LOGI("APP", "You are No. %d developer to use AliOS Things", user_number);

API详情

uLog的应用层API说明请参考include/dm/ulog/ulog.h。

ulog()

通用的记录日志方式,一般被下述简要日志记录API替代

函数原型

int ulog(const unsigned char s, const char *mod, const char *f, const unsigned long l, const char *fmt, ...)

输入参数

const unsigned char s 记录日志级别 LOG_ERR, 其它选值参见见include/ulog/ulog.h文件
const char *mod 记录日志产生时的模块名 "app"
const char *f 记录日志产生文件名,或者用户自己选择其他字符 __FILE__
const unsigned long l 记录日志产生在文件名的行数,或者用户自己选择使用其他32位数据 __LINE__
const char *fmt 可变参数格式化,结尾不用加回车换行,抛出日志时会自动添加 "Day %d"
... 可变参数 54

返回参数

-1 一般入参出错
其它>0的值 调用成功

调用示例

ulog(LOG_INFO, "APP", __FILE__, __LINE__, "Helloworld");

LOG()

简要的以Emergency级别记录日志方式,由于mod固定,一般用的地方较少

函数原型

LOG(...)

输入参数

... 可变参数,类似于printf,结尾不用加回车换行,抛出日志时会自动添加 "task exit"

返回参数

和ulog()返回参数一致

调用示例

LOG("Tom is %d years old", tom_age);

LOGF()

简要的以Fatal级别记录日志方式,一般用在严重错误,影响到产品正常且不可恢复的场景

函数原型

LOGF(mod, ...)

输入参数

const char *mod 记录日志产生时的模块名 "app"
... 可变参数,类似于printf,结尾不用加回车换行,抛出日志时会自动添加 "task exit"

返回参数

和ulog()返回参数一致

调用示例

LOGF("APP", "App Task Exit as unknown reason");

LOGE()

简要的以Error级别记录日志方式,一般用在产生一般错误,影响产品部分功能的场景

函数原型

LOGE(mod, ...)

输入参数

const char *mod 记录日志产生时的模块名 "app"
... 可变参数,类似于printf,结尾不用加回车换行,抛出日志时会自动添加 "task exit"

返回参数

和ulog()返回参数一致

调用示例

LOGE("BLE", "Network Disconnect");

LOGW()

简要的以Warning级别记录日志方式,一般用在产生可能会带来影响产品功能的场景

函数原型

LOGW(mod, ...)

输入参数

const char *mod 记录日志产生时的模块名 "app"
... 可变参数,类似于printf,结尾不用加回车换行,抛出日志时会自动添加 "task exit"

返回参数

和ulog()返回参数一致

调用示例

LOGW("APP", "Unknown Telegram 0x%x recvd", telegram_type);

LOGI()

简要的以Info级别记录日志方式,一般用在普通日志的场景

函数原型

LOGI(mod, ...)

输入参数

const char *mod 记录日志产生时的模块名 "app"
... 可变参数,类似于printf,结尾不用加回车换行,抛出日志时会自动添加 "task exit"

返回参数

和ulog()返回参数一致

调用示例

LOGI("APP", "Recv Operation command from host");

LOGD()

简要的以Debug级别记录日志方式,一般用在记录仅在研发时需要的日志。如果编译系统不含'DEBUG'开关编译,则此类日志不会被编译出固件

函数原型

LOGD(mod, ...)

输入参数

const char *mod 记录日志产生时的模块名 "app"
... 可变参数,类似于printf,结尾不用加回车换行,抛出日志时会自动添加 "task exit"

返回参数

和ulog()返回参数一致

调用示例

LOGD("APP", "Driver Mount Sucessfully");

aos_set_log_level()

修改默认定向日志输出级别

函数原型

int aos_set_log_level(aos_log_level_t log_level)

输入参数

aos_log_level_t log_level 准出日志级别 LOG_ERR

返回参数

0 设置成功
-22 由于入参不合法造成设置失败

调用示例

aos_set_log_level(LOG_ERR);

ulog_man()

一套简易的服务机制进行ulog功能控制,完成诸如使能通过udp 发送至remote syslog 监听工具,修改监听工具IP,暂停或继续日志记录在文件系统的功能。这些功能的控制通过该字符串控制,比如ulog_man("tcpip on=1")则通知ulog使能udp输出日志功能 。

函数原型

int ulog_man(const char *cmd_str)

输入参数

const char *cmd_str 控制命令字符 "tcpip on=1"

返回参数

0 设置成功
负值 由于入参不合法造成设置失败

调用示例

ulog_man("tcpip on=1");

aos_get_ulog_list()

获取文件系统记录日志文件列表

函数原型

int aos_get_ulog_list(char *buf, const unsigned short len)

输入参数

char *buf 用以记录结果的buffer buffer
len buffer长度 256

返回参数

0 设置成功
负值 由于入参不合法造成设置失败

调用示例

char buf[256];
memset(buf, 0, sizeof(buf));
aos_get_ulog_list(buf, sizeof(buf));

配置说明

在AliOS Things 源码里面输入aos make menuconfig命令即可进入到menuconfig配置界面中,依次选择Middlware Configurations -> uLog Configuration即可进入到uLog组件的配置界面:

配置项说明

--- uLog Configuration
(6)   Level Stop Filter of Default Direction(UART for RTOS)             # 默认定向日志过滤优先级,默认6
(256) Max Length of Log Text   # 日志内容长度限制,默认256
[]  Support syslog Time Format when Log         # 使用syslog时间格式记录日志,默认不开启
[] Enable Rich Details for Log                            #记录更多细节如日志产生文件及行号,默认不开启
[] Switch on Pop Out Log to Cloud                    #日志抛出到云端运维控制台,默认不开启
[] Switch on Pop Out Log Into File System         #日志抛出到文件系统,默认不开启
[] Switch on Pop Out Log via Syslog UDP             #日志抛出到udp syslog服务器,默认不开启
[] Using Async Mode to Log on Default Direct   #对默认定向日志抛出仍使用异步机制,默认不开启

其它

syslog日志优先级

优先级遵循syslog协议定义,其中LOG_NONE用于控制日志输出,值越低相应优先级越高。

#define LOG_EMERG   0 /* system is unusable */
#define LOG_ALERT   1 /* action must be taken immediately */
#define LOG_CRIT    2 /* critical conditions */
#define LOG_ERR     3 /* error conditions */
#define LOG_WARNING 4 /* warning conditions */
#define LOG_NOTICE  5 /* normal, but significant, condition */
#define LOG_INFO    6 /* informational message */
#define LOG_DEBUG   7 /* debug-level message */
#define LOG_NONE    8 /* used in stop filter, all log will pop out */

当前设备主要使用其中的Alert, Critical, Error, Warning, Info, Debug这6个优先级(对应API参见API介绍--客户使用API)