11 #include "luat_msgbus.h"
12 #include "luat_zbuff.h"
14 #include "luat_rtos.h"
15 #define LUAT_LOG_TAG "log"
17 typedef struct luat_log_conf
23 #define LOG_STYLE_NORMAL 0
24 #define LOG_STYLE_DEBUG_INFO 1
25 #define LOG_STYLE_FULL 2
27 static luat_log_conf_t lconf
= {
31 static int add_debug_info(lua_State
*L
, uint8_t pos
, const char* LEVEL
) {
36 // while (lua_getstack(L, d, &ar) != 0) {
39 // // 防御一下, 不太可能直接d==0都失败
43 if (!lua_getstack(L
, 1, &ar
))
46 if (0 == lua_getinfo(L
, "Sl", &ar
))
49 if (ar
.source
== NULL
)
51 int line
= ar
.currentline
> 64*1024 ? 0 : ar
.currentline
;
52 // 推入文件名和行号, 注意: 源码路径的第一个字符是标识,需要跳过
54 lua_pushfstring(L
, "%s/%s:%d", LEVEL
, ar
.source
+ 1, line
);
56 lua_pushfstring(L
, "%s:%d", ar
.source
+ 1, line
);
57 if (lua_gettop(L
) > pos
)
64 @api log.setLevel(level)
65 @string level 日志级别,可用字符串或数值, 字符串为(SILENT,DEBUG,INFO,WARN,ERROR,FATAL), 数值为(0,1,2,3,4,5)
71 static int l_log_set_level(lua_State
*L
) {
73 if (lua_isinteger(L
, 1)) {
74 LOG_LEVEL
= lua_tointeger(L
, 1);
76 else if (lua_isstring(L
, 1)) {
77 const char* lv
= lua_tostring(L
, 1);
78 if (strcmp("SILENT", lv
) == 0) {
79 LOG_LEVEL
= LUAT_LOG_CLOSE
;
81 else if (strcmp("DEBUG", lv
) == 0) {
82 LOG_LEVEL
= LUAT_LOG_DEBUG
;
84 else if (strcmp("INFO", lv
) == 0) {
85 LOG_LEVEL
= LUAT_LOG_INFO
;
87 else if (strcmp("WARN", lv
) == 0) {
88 LOG_LEVEL
= LUAT_LOG_WARN
;
90 else if (strcmp("ERROR", lv
) == 0) {
91 LOG_LEVEL
= LUAT_LOG_ERROR
;
95 LOG_LEVEL
= LUAT_LOG_CLOSE
;
97 luat_log_set_level(LOG_LEVEL
);
104 @int 日志风格,默认为0, 不传就是获取当前值
107 -- 以 log.info("ABC", "DEF", 123) 为例, 假设该代码位于main.lua的12行
109 -- I/user.ABC DEF 123
111 -- I/main.lua:12 ABC DEF 123
112 -- 调试风格2, 添加额外的调试信息, 位置有所区别
113 -- I/user.ABC main.lua:12 DEF 123
115 log.style(0) -- 默认风格0
116 log.style(1) -- 调试风格1
117 log.style(2) -- 调试风格2
119 static int l_log_style(lua_State
*L
) {
120 if (lua_isinteger(L
, 1))
121 lconf
.style
= luaL_checkinteger(L
, 1);
122 lua_pushinteger(L
, lconf
.style
);
129 @return int 日志级别对应0,1,2,3,4,5
134 int l_log_get_level(lua_State
*L
) {
135 lua_pushinteger(L
, luat_log_get_level());
139 static int l_log_2_log(lua_State
*L
, const char* LEVEL
) {
141 int argc
= lua_gettop(L
);
146 if (lconf
.style
== LOG_STYLE_NORMAL
) {
147 lua_pushfstring(L
, "%s/user.%s", LEVEL
, lua_tostring(L
, 1));
148 lua_remove(L
, 1); // remove tag
151 else if (lconf
.style
== LOG_STYLE_DEBUG_INFO
) {
152 add_debug_info(L
, 1, LEVEL
);
154 else if (lconf
.style
== LOG_STYLE_FULL
) {
155 lua_pushfstring(L
, "%s/user.%s", LEVEL
, lua_tostring(L
, 1));
156 lua_remove(L
, 1); // remove tag
158 add_debug_info(L
, 2, NULL
);
160 lua_getglobal(L
, "print");
162 lua_call(L
, lua_gettop(L
) - 1, 0);
168 @api log.debug(tag, val, val2, val3, ...)
169 @string tag 日志标识,必须是字符串
173 -- 日志输出 D/onenet connect ok
174 log.debug("onenet", "connect ok")
176 static int l_log_debug(lua_State
*L
) {
177 if (luat_log_get_level() > LUAT_LOG_DEBUG
) return 0;
178 return l_log_2_log(L
, "D");
183 @api log.info(tag, val, val2, val3, ...)
184 @string tag 日志标识,必须是字符串
188 -- 日志输出 I/onenet connect ok
189 log.info("onenet", "connect ok")
191 static int l_log_info(lua_State
*L
) {
192 if (luat_log_get_level() > LUAT_LOG_INFO
) return 0;
193 return l_log_2_log(L
, "I");
198 @api log.warn(tag, val, val2, val3, ...)
199 @string tag 日志标识,必须是字符串
203 -- 日志输出 W/onenet connect ok
204 log.warn("onenet", "connect ok")
206 static int l_log_warn(lua_State
*L
) {
207 if (luat_log_get_level() > LUAT_LOG_WARN
) return 0;
208 return l_log_2_log(L
, "W");
213 @api log.error(tag, val, val2, val3, ...)
214 @string tag 日志标识,必须是字符串
218 -- 日志输出 E/onenet connect ok
219 log.error("onenet", "connect ok")
221 static int l_log_error(lua_State
*L
) {
222 if (luat_log_get_level() > LUAT_LOG_ERROR
) return 0;
223 return l_log_2_log(L
, "E");
226 #include "rotable2.h"
227 static const rotable_Reg_t reg_log
[] =
229 { "debug" , ROREG_FUNC(l_log_debug
)},
230 { "info" , ROREG_FUNC(l_log_info
)},
231 { "warn" , ROREG_FUNC(l_log_warn
)},
232 { "error" , ROREG_FUNC(l_log_error
)},
233 { "fatal" , ROREG_FUNC(l_log_error
)}, // 以error对待
234 { "setLevel" , ROREG_FUNC(l_log_set_level
)},
235 { "getLevel" , ROREG_FUNC(l_log_get_level
)},
236 { "style", ROREG_FUNC(l_log_style
)},
237 //{ "_log" , ROREG_FUNC(l_log_2_log)},
240 //@const LOG_SILENT number 无日志模式
241 { "LOG_SILENT", ROREG_INT(LUAT_LOG_CLOSE
)},
242 //@const LOG_DEBUG number debug日志模式
243 { "LOG_DEBUG", ROREG_INT(LUAT_LOG_DEBUG
)},
244 //@const LOG_INFO number info日志模式
245 { "LOG_INFO", ROREG_INT(LUAT_LOG_INFO
)},
246 //@const LOG_WARN number warning日志模式
247 { "LOG_WARN", ROREG_INT(LUAT_LOG_WARN
)},
248 //@const LOG_ERROR number error日志模式
249 { "LOG_ERROR", ROREG_INT(LUAT_LOG_ERROR
)},
250 { NULL
, ROREG_INT(0) }
253 LUAMOD_API
int luaopen_log( lua_State
*L
) {
254 luat_newlib2(L
, reg_log
);
258 void luat_log_dump(const char* tag
, void* ptr
, size_t len
) {
260 luat_log_log(LUAT_LOG_DEBUG
, tag
, "ptr is NULL");
264 luat_log_log(LUAT_LOG_DEBUG
, tag
, "ptr len is 0");
267 char buff
[256] = {0};
268 uint8_t* ptr2
= (uint8_t*)ptr
;
269 for (size_t i
= 0; i
< len
; i
++)
271 sprintf_(buff
+ strlen(buff
), "%02X ", ptr2
[i
]);
273 luat_log_log(LUAT_LOG_DEBUG
, tag
, "%s", buff
);
278 luat_log_log(LUAT_LOG_DEBUG
, tag
, "%s", buff
);