跳转至

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() 的日志不会被输出

二、核心示例

  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
常量取值: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
是否必选:是;
注意事项:必须传入012中的一个有效值;
参数示例: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 核心库。