log-日志库
作者:王世豪
一、概述
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() 的日志不会被输出
二、核心示例
-
核心示例是指:使用本库文件提供的核心 API,开发的基础业务逻辑的演示代码;
-
核心示例的作用是:帮助开发者快速理解如何使用本库,所以核心示例的逻辑都比较简单;
-
更加完整和详细的 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;
常量取值:7;
注意事项:静默所有日志,即禁止日志有任何内容输出;
示例代码:log.setLevel(log.LOG_SILENT)
3.2 log.LOG_DEBUG
常量含义:debug日志模式;
数据类型:number;
常量取值:1;
注意事项:输出 debug 及以上级别的日志;
示例代码:log.setLevel(log.LOG_DEBUG)
3.3 log.LOG_INFO
常量含义:info日志模式;
数据类型:number;
常量取值:2;
注意事项:输出 info 及以上级别的日志;
示例代码:log.setLevel(log.LOG_INFO)
3.4 log.LOG_WARN
常量含义:warning日志模式;
数据类型:number;
常量取值:3;
注意事项:输出 warn 及以上级别的日志;
示例代码:log.setLevel(log.LOG_WARN)
3.5 log.LOG_ERROR
常量含义:error日志模式;
数据类型:number;
常量取值:4;
注意事项:输出 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)
五、产品支持说明
支持 LuatOS 开发的所有产品都支持 log 核心库。