跳转至

41 log-日志控制

作者:王世豪 | 最后修改:2026-09-22

一、概述

log 库用于在 LuatOS 中输出程序运行日志。它支持多种日志等级(包括调试、信息、警告、错误),帮助开发者在不同场景下精准定位问题,是开发和调试过程中不可或缺的工具。

1.1 日志的等级(日志输出函数)

日志的等级指的是日志输出函数本身的级别:

debug:调试内容输出,为日志输出优先级第 4 等级,优先级最低;

info:信息输出,为日志输出优先级第 3 等级,仅比 debug 级别高;

warn:警告输出,为日志输出优先级第 2 等级;

error:错误输出,为日志输出优先级第 1 等级,级别最高;

注:LuatOS 默认日志等级是 debug,可以输出 debug 及以上等级的日志;

如:log.debug(PROJECT, "debug message"),debug 为 log 模块的函数,使用小写英文字母;

1.2 日志输出等级(日志过滤级别)

日志输出等级指的是通过 log.setLevel() 设置的过滤级别,用于控制哪些级别的日志会被实际输出:

SILENT: 静默所有日志,即禁止日志有任何内容输出;

DEBUG: 输出 debug 及以上级别的日志;

INFO: 输出 info 及以上级别的日志;

WARN: 输出 warn 及以上级别的日志;

ERROR: 输出 error 级别的日志;

如:log.setLevel("INFO"),INFO 作为 setLevel 函数的参数存在,使用大写英文字母;

1.3 重要区别

debug(小写):指的是 log.debug() 函数,用于输出 debug 级别的日志内容;

DEBUG(大写):指的是 log.setLevel("DEBUG") 参数,用于设置输出 debug 及以上级别的日志;

其他级别(info/INFO、warn/WARN、error/ERROR)同理;

使用过程要注意大小写的区别,它们在不同的上下文中具有不同的作用;

1.4 使用关系

日志输出等级决定了哪些日志等级的日志会被实际输出:

当设置 log.setLevel("INFO") 时:

  • log.debug() 的日志不会被输出(因为 debug < info)

  • log.info()、log.warn()、log.error() 的日志会被输出

当设置 log.setLevel("ERROR") 时:

  • 只有 log.error() 的日志会被输出

  • log.debug()、log.info()、log.warn() 的日志不会被输出

二、核心示例

  1. 核心示例是指:使用本库文件提供的核心 API,开发的基础业务逻辑的演示代码;

  2. 核心示例的作用是:帮助开发者快速理解如何使用本库,所以核心示例的逻辑都比较简单;

  3. 更加完整和详细的 demo,请参考 LuatOS 仓库 中各个产品目录下的 demo/log;

--实验1:输出四个等级的日志,日志等级排序从低到高为 debug < info < warn < error
log.debug(PROJECT, "debug message")
log.info(PROJECT, "info message")
log.warn(PROJECT, "warn message")
log.error(PROJECT, "error message")

--实验2:输出info及更高级别日志,即debug日志不输出
log.setLevel("INFO")
print(log.getLevel())

-- 这条debug级别的日志不会输出
log.debug(PROJECT, "debug message")
log.info(PROJECT, "info message")
log.warn(PROJECT, "warn message")
log.error(PROJECT, "error message")

--实验3:通过日志输出变量内容
local myInteger = 42
log.info("Integer", myInteger)

三、常量详解

核心库常量,顾名思义是由合宙 LuatOS 内核固件中定义的、不可重新赋值或修改的固定值,在脚本代码中不需要声明,可直接调用;

每个常量对应的常量取值仅做日志打印时查询使用,不要将这个常量取值用做具体的业务逻辑判断,因为LuatOS内核固件可能会变更每个常量对应的常量取值;

如果用做具体的业务逻辑判断,一旦常量取值发生改变,业务逻辑就会出错;

3.1 log.LOG_SILENT

常量含义:无日志模式;
数据类型:number;
注意事项:静默所有日志,即禁止日志有任何内容输出;
示例代码:log.setLevel(log.LOG_SILENT)

3.2 log.LOG_DEBUG

常量含义:debug日志模式;
数据类型:number;
注意事项:输出 debug 及以上级别的日志;
示例代码:log.setLevel(log.LOG_DEBUG)

3.3 log.LOG_INFO

常量含义:info日志模式;
数据类型:number;
注意事项:输出 info 及以上级别的日志;
示例代码:log.setLevel(log.LOG_INFO)

3.4 log.LOG_WARN

常量含义:warning日志模式;
数据类型:number;
注意事项:输出 warn 及以上级别的日志;
示例代码:log.setLevel(log.LOG_WARN)

3.5 log.LOG_ERROR

常量含义:error日志模式;
数据类型:number;
注意事项:输出 error 级别的日志;
示例代码:log.setLevel(log.LOG_ERROR)

四、函数详解

4.1 log.setLevel(level)

功能

设置日志输出的级别;

注意事项

设置后会影响所有后续的日志输出;

参数支持字符串、数字、常量,三者等价;

字符串参数必须使用大写英文字母;

参数

level

含义说明:日志输出级别;
        SILENT:静默所有日志,即禁止日志有任何内容输出;
        DEBUG: 输出 debug 及以上级别的日志;
        INFO:  输出 info 及以上级别的日志;
        WARN:  输出 warn 及以上级别的日志;
        ERROR: 输出 error 级别的日志;
数据类型:string/number;
取值范围:字符串:"SILENT", "DEBUG", "INFO", "WARN", "ERROR";
        数值:7(SILENT), 1(DEBUG), 2(INFO), 3(WARN), 4(ERROR);
        常量:log.LOG_SILENT, log.LOG_DEBUG, log.LOG_INFO, log.LOG_WARN, log.LOG_ERROR;
是否必选:否,不填参数默认是SILENT无日志模式;
注意事项:字符串,数值,常量三者都可以;
参数示例:-- 所有有效的参数示例:
        -- 字符串形式(必须大写)
        "SILENT"        -- 完全静默,无日志输出
        "DEBUG"         -- 输出所有级别日志
        "INFO"          -- 输出info及以上级别日志
        "WARN"          -- 输出warn及以上级别日志
        "ERROR"         -- 只输出error级别日志
        -- 数值形式
        7               -- 等同于 "SILENT"
        1               -- 等同于 "DEBUG"
        2               -- 等同于 "INFO"
        3               -- 等同于 "WARN"
        4               -- 等同于 "ERROR"
        -- 常量形式
        log.LOG_SILENT  -- 等同于7和"SILENT"
        log.LOG_DEBUG   -- 等同于1和"DEBUG"
        log.LOG_INFO    -- 等同于2和"INFO"
        log.LOG_WARN    -- 等同于3和"WARN"
        log.LOG_ERROR   -- 等同于4和"ERROR"

返回值

无

示例

-- 字符串形式
log.setLevel("INFO")      -- 只输出 info 及以上级别日志
log.setLevel("ERROR")     -- 只输出 error 级别日志
log.setLevel("SILENT")    -- 禁止所有日志输出
-- 数值形式
log.setLevel(1)           -- 等同于 "DEBUG"
log.setLevel(2)           -- 等同于 "INFO"
-- 常量形式
log.setLevel(log.LOG_DEBUG)   -- 等同于1和"DEBUG"

4.2 log.getLevel()

功能

获取日志输出的级别;

注意事项

无

参数

无

返回值

local result = log.getLevel()

result

含义说明:当前的日志输出级别;
         1: DEBUG级别,对应常量是log.LOG_DEBUG;
         2: INFO级别,对应常量是log.LOG_INFO;
         3: WARN级别,对应常量是log.LOG_WARN;   
         4: ERROR级别,对应常量是log.LOG_ERROR; 
         7: SILENT级别,对应常量是log.LOG_SILENT; 
数据类型:number;
取值范围:1/2/3/4/7;
注意事项:无;
返回示例:使用log.setLevel("INFO")设置日志输出级别为INFO后;
        调用log.getLevel() ,返回结果为:2

示例

-- 获取当前日志级别
local currentLevel = log.getLevel()
print("当前日志级别:", currentLevel)

4.3 log.style(val)

功能

设置日志风格;

注意事项

不同的日志风格会影响日志信息的显示内容和格式;

参数

val

含义说明:日志风格;
        以 log.info("ABC", "DEF", 123) 为例, 假设该代码位于main.lua的12行
        默认风格0: I/user.ABC DEF 123
        调试风格1: I/main.lua:12 ABC DEF 123(在开头添加文件位置信息)
        调试风格2: I/user.ABC main.lua:12 DEF 123(在消息中间添加文件位置信息)
数据类型:number;
取值范围:0/1/2
是否必选:是;
注意事项:必须传入0、1、2中的一个有效值;
参数示例:log.style(0)

返回值

local result = log.style(val)

result

含义说明:当前的日志风格;
数据类型:number;
取值范围:0/1/2;
注意事项:无;
返回示例:设置log.style(0),返回:0

示例

-- 以 log.info("ABC", "DEF", 123) 为例, 假设该代码位于main.lua的12行
-- 默认日志0
-- 效果:I/user.ABC DEF 123
log.style(0) -- 默认风格0

-- 调试风格1, 添加额外的调试信息
-- 效果:I/main.lua:12 ABC DEF 123
log.style(1) -- 调试风格1

-- 调试风格2, 添加额外的调试信息, 位置有所区别
-- 效果:I/user.ABC main.lua:12 DEF 123
log.style(2) -- 调试风格2

-- 获取当前日志风格
local currentStyle = log.style(1)
print("当前日志风格:", currentStyle) -- 输出: 当前日志风格: 1

4.4 log.debug(tag, val, val2, val3, ...)

功能

输出 debug 级别的日志;

注意事项

只有当前日志输出级别设置为 DEBUG 时,才会显示此日志;

可以接受多个参数,所有参数会被自动转换为字符串并拼接;

输出的日志前缀为"D/"表示 debug 级别;

参数

tag

含义说明:tag 日志标识;
数据类型:string;
取值范围:无特别限制;
是否必选:是;
注意事项:建议使用有意义的标识符,便于日志分析;
         第一个参数必须是字符串类型,其他值不保证正常输出;
参数示例:"mqtt"

val, val2, val3, ...

含义说明:要输出的日志内容,可以是任意类型;
数据类型:任意(会自动转换为字符串打印输出);
取值范围:无特别限制;
是否必选:否;
注意事项:可以传入多个参数,它们会被自动拼接;
参数示例:"connect ok", 123, true

返回值

无

示例

-- 基本用法:输出调试日志
-- 输出:D/user.mqtt connect ok
log.debug("mqtt", "connect ok")

-- 多参数用法:自动拼接多个参数
-- 输出:D/user.network status: connected port: 8080
log.debug("network", "status:", "connected", "port:", 8080)

-- 包含变量和表达式
-- 输出:D/user.abc result: 0 status: success
local ret = 0
log.debug("abc", "result:", ret, "status:", ret == 0 and "success" or "fail")

-- 调试对象状态
-- 输出:D/user.device name: sensor status: online
local device = {name = "sensor", status = "online"}
log.debug("device", "name:", device.name, "status:", device.status)

4.5 log.info(tag, val, val2, val3, ...)

功能

输出 info 级别的日志;

注意事项

只有当前日志输出级别设置为 DEBUG 或 INFO 时,才会显示此日志;

可以接受多个参数,所有参数会被自动转换为字符串并拼接;

输出的日志前缀为"I/"表示 info 级别;

参数

tag

含义说明:tag 日志标识;
数据类型:string;
取值范围:无特别限制;
是否必选:是;
注意事项:建议使用有意义的标识符,便于日志分析;
         第一个参数必须是字符串类型,其他值不保证正常输出;
参数示例:"mqtt"

val, val2, val3, ...

含义说明:要输出的日志内容,可以是任意类型;
数据类型:任意(会自动转换为字符串打印输出);
取值范围:无特别限制;
是否必选:否;
注意事项:可以传入多个参数,它们会被自动拼接;
参数示例:"connect ok", 123, true

返回值

无

示例

-- 基本用法:输出调试日志
-- 输出:I/user.mqtt connect ok
log.info("mqtt", "connect ok")

-- 多参数用法:自动拼接多个参数
-- 输出:I/user.network status: connected port: 8080
log.info("network", "status:", "connected", "port:", 8080)

-- 包含变量和表达式
-- 输出:I/user.abc result: 0 status: success
local ret = 0
log.info("abc", "result:", ret, "status:", ret == 0 and "success" or "fail")

-- 调试对象状态
-- 输出:I/user.device name: sensor status: online
local device = {name = "sensor", status = "online"}
log.info("device", "name:", device.name, "status:", device.status)

4.6 log.warn(tag, val, val2, val3, ...)

功能

输出 warn 级别的日志;

注意事项

只有当前日志输出级别设置为 DEBUG、INFO 或 WARN 时,才会显示此日志;

可以接受多个参数,所有参数会被自动转换为字符串并拼接;

输出的日志前缀为"W/"表示 warn 级别;

参数

tag

含义说明:tag 日志标识;
数据类型:string;
取值范围:无特别限制;
是否必选:是;
注意事项:建议使用有意义的标识符,便于日志分析;
         第一个参数必须是字符串类型,其他值不保证正常输出;
参数示例:"mqtt"

val, val2, val3, ...

含义说明:要输出的日志内容,可以是任意类型;
数据类型:任意(会自动转换为字符串打印输出);
取值范围:无特别限制;
是否必选:否;
注意事项:可以传入多个参数,它们会被自动拼接;
参数示例:"connect ok", 123, true

返回值

无

示例

-- 基本用法:输出调试日志
-- 输出:W/user.mqtt connect ok
log.warn("mqtt", "connect ok")

-- 多参数用法:自动拼接多个参数
-- 输出:W/user.network status: connected port: 8080
log.warn("network", "status:", "connected", "port:", 8080)

-- 包含变量和表达式
-- 输出:W/user.abc result: 0 status: success
local ret = 0
log.warn("abc", "result:", ret, "status:", ret == 0 and "success" or "fail")

-- 调试对象状态
-- 输出:W/user.device name: sensor status: online
local device = {name = "sensor", status = "online"}
log.warn("device", "name:", device.name, "status:", device.status)

4.7 log.error(tag, val, val2, val3, ...)

功能

输出 error 级别的日志;

注意事项

只有当前日志输出级别设置为 DEBUG、INFO、WARN 或 ERROR 时,才会显示此日志;

可以接受多个参数,所有参数会被自动转换为字符串并拼接;

输出的日志前缀为"E/"表示 error 级别;

参数

tag

含义说明:tag 日志标识;
数据类型:string;
取值范围:无特别限制;
是否必选:是;
注意事项:建议使用有意义的标识符,便于日志分析;
         第一个参数必须是字符串类型,其他值不保证正常输出;
参数示例:"mqtt"

val, val2, val3, ...

含义说明:要输出的日志内容,可以是任意类型;
数据类型:任意(会自动转换为字符串打印输出);
取值范围:无特别限制;
是否必选:否;
注意事项:可以传入多个参数,它们会被自动拼接;
参数示例:"connect ok", 123, true

返回值

无

示例

-- 基本用法:输出调试日志
-- 输出:E/user.mqtt connect ok
log.error("mqtt", "connect ok")

-- 多参数用法:自动拼接多个参数
-- 输出:E/user.network status: connected port: 8080
log.error("network", "status:", "connected", "port:", 8080)

-- 包含变量和表达式
-- 输出:E/user.abc result: 0 status: success
local ret = 0
log.error("abc", "result:", ret, "status:", ret == 0 and "success" or "fail")

-- 调试对象状态
-- 输出:E/user.device name: sensor status: online
local device = {name = "sensor", status = "online"}
log.error("device", "name:", device.name, "status:", device.status)

4.8 log.set_usercmd_cb(cb)

功能

注册日志口用户自定义指令的回调函数,用于接收日志口发来的用户指令帧;

注意事项

1、只有固件开启了宏 LUAT_USE_LOG_USER_CMD 时才有此接口,未开启时 log.set_usercmd_cb 为 nil;截至 2026-09-22,仅 Air1601/Air1602 固件开启了该宏;

2、传入 nil 表示注销已经注册的回调函数;

3、回调函数在日志口收到用户指令帧时被调用,签名固定为 function(cmd, data);

4、cmd 为指令帧中的用户指令号(即 A5 帧的 address 字段),data 为指令携带的数据;

5、LuatOS 的日志口 adb 扩展库 hzadb 就是基于本接口实现的,常规使用直接调用 hzadb 即可,不需要自己调用本接口;

参数

cb

含义说明:日志口用户指令的回调函数,传 nil 表示注销;
数据类型:function 或者 nil;
取值范围:无特别限制;
是否必选:是;
注意事项:回调函数是在 task 之外的业务逻辑中被执行的;
          在回调函数内部无法使用 sys.wait()、sys.waitUntil() 等必须用在 task 中的函数;
参数示例:

    log.set_usercmd_cb(function(cmd, data)
        log.info("usercmd", cmd, data)
    end)

返回值

无

示例

-- 注册日志口用户指令回调
log.set_usercmd_cb(function(cmd, data)
    log.info("usercmd", "cmd:", cmd, "len:", #data)
end)

-- 注销回调
-- log.set_usercmd_cb(nil)

4.9 log.usercmd_write(data, len, offset)

功能

通过日志口发送 usercmd 协议帧,走独占命令帧通道,不占用日志显示(不会被当成普通日志行打印出来);

注意事项

1、只有固件开启了宏 LUAT_USE_LOG_USER_CMD 时才有此接口,未开启时 log.usercmd_write 为 nil;截至 2026-09-22,仅 Air1601/Air1602 固件开启了该宏;

2、底层是弱符号实现,未实现独占命令帧通道的平台会退化为普通文本日志输出(内容仍会发出,但会占用日志流);

3、len 与 offset 只对 zbuff 类型生效;传入 string 时总是发送整个字符串;

4、offset 大于等于数据长度时,不会发送任何数据;

5、LuatOS 的日志口 adb 扩展库 hzadb 使用本接口回发协议帧;一般业务不需要直接调用本接口;

参数

data

含义说明:待写入的数据;
数据类型:string 或者 zbuff;
取值范围:无特别限制;
是否必选:是;
注意事项:无;
参数示例:"hello"

len

含义说明:写入长度;
数据类型:number 或者 nil;
取值范围:0 到数据长度之间;
是否必选:否,默认为 zbuff:used;
注意事项:超过剩余长度时按剩余长度处理;传入 string 时本参数无效;
参数示例:10

offset

含义说明:起始偏移;
数据类型:number 或者 nil;
取值范围:0 到数据长度之间;
是否必选:否,默认为 0;
注意事项:仅对 zbuff 类型生效;传入 string 时本参数无效;
参数示例:5

返回值

无

示例

-- 发送整个字符串
log.usercmd_write("hello")

-- 发送 zbuff 的全部内容
-- log.usercmd_write(buff)

-- 发送 zbuff 前 10 字节
-- log.usercmd_write(buff, 10)

-- 发送 zbuff 从第 5 字节起的 10 字节
-- log.usercmd_write(buff, 10, 5)

五、产品支持说明

支持 LuatOS 开发的所有产品都支持 log 核心库。

搜索