update: 更新aliyun库及其demo
[LuatOS.git] / luat / modules / luat_lib_log.c
blobcbcb7c22444f70e0310c80d783baf135c1f19532
2 /*
3 @module log
4 @summary 日志库
5 @version 1.0
6 @date 2020.03.30
7 @tag LUAT_CONF_BSP
8 */
9 #include "luat_base.h"
10 #include "luat_sys.h"
11 #include "luat_msgbus.h"
12 #include "luat_zbuff.h"
13 #include "ldebug.h"
14 #include "luat_rtos.h"
15 #define LUAT_LOG_TAG "log"
16 #include "luat_log.h"
17 typedef struct luat_log_conf
19 uint8_t style;
21 }luat_log_conf_t;
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 = {
28 .style=0
31 static int add_debug_info(lua_State *L, uint8_t pos, const char* LEVEL) {
32 lua_Debug ar;
33 // int arg;
34 // int d = 0;
35 // // 查找当前stack的深度
36 // while (lua_getstack(L, d, &ar) != 0) {
37 // d++;
38 // }
39 // // 防御一下, 不太可能直接d==0都失败
40 // if (d == 0)
41 // return 0;
42 // 获取真正的stack位置信息
43 if (!lua_getstack(L, 1, &ar))
44 return 0;
45 // S包含源码, l包含当前行号
46 if (0 == lua_getinfo(L, "Sl", &ar))
47 return 0;
48 // 没有调试信息就跳过了
49 if (ar.source == NULL)
50 return 0;
51 int line = ar.currentline > 64*1024 ? 0 : ar.currentline;
52 // 推入文件名和行号, 注意: 源码路径的第一个字符是标识,需要跳过
53 if (LEVEL)
54 lua_pushfstring(L, "%s/%s:%d", LEVEL, ar.source + 1, line);
55 else
56 lua_pushfstring(L, "%s:%d", ar.source + 1, line);
57 if (lua_gettop(L) > pos)
58 lua_insert(L, pos);
59 return 1;
63 设置日志级别
64 @api log.setLevel(level)
65 @string level 日志级别,可用字符串或数值, 字符串为(SILENT,DEBUG,INFO,WARN,ERROR,FATAL), 数值为(0,1,2,3,4,5)
66 @return nil 无返回值
67 @usage
68 -- 设置日志级别为INFO
69 log.setLevel("INFO")
71 static int l_log_set_level(lua_State *L) {
72 int LOG_LEVEL = 0;
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;
94 if (LOG_LEVEL == 0) {
95 LOG_LEVEL = LUAT_LOG_CLOSE;
97 luat_log_set_level(LOG_LEVEL);
98 return 0;
102 设置日志风格
103 @api log.style(val)
104 @int 日志风格,默认为0, 不传就是获取当前值
105 @return int 当前的日志风格
106 @usage
107 -- 以 log.info("ABC", "DEF", 123) 为例, 假设该代码位于main.lua的12行
108 -- 默认日志0
109 -- I/user.ABC DEF 123
110 -- 调试风格1, 添加额外的调试信息
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);
123 return 1;
127 获取日志级别
128 @api log.getLevel()
129 @return int 日志级别对应0,1,2,3,4,5
130 @usage
131 -- 得到日志级别
132 log.getLevel()
134 int l_log_get_level(lua_State *L) {
135 lua_pushinteger(L, luat_log_get_level());
136 return 1;
139 static int l_log_2_log(lua_State *L, const char* LEVEL) {
140 // 是不是什么都不传呀?
141 int argc = lua_gettop(L);
142 if (argc < 1) {
143 // 最起码传1个参数
144 return 0;
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
149 lua_insert(L, 1);
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
157 lua_insert(L, 1);
158 add_debug_info(L, 2, NULL);
160 lua_getglobal(L, "print");
161 lua_insert(L, 1);
162 lua_call(L, lua_gettop(L) - 1, 0);
163 return 0;
167 输出日志,级别debug
168 @api log.debug(tag, val, val2, val3, ...)
169 @string tag 日志标识,必须是字符串
170 @... 需打印的参数
171 @return nil 无返回值
172 @usage
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");
182 输出日志,级别info
183 @api log.info(tag, val, val2, val3, ...)
184 @string tag 日志标识,必须是字符串
185 @... 需打印的参数
186 @return nil 无返回值
187 @usage
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");
197 输出日志,级别warn
198 @api log.warn(tag, val, val2, val3, ...)
199 @string tag 日志标识,必须是字符串
200 @... 需打印的参数
201 @return nil 无返回值
202 @usage
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");
212 输出日志,级别error
213 @api log.error(tag, val, val2, val3, ...)
214 @string tag 日志标识,必须是字符串
215 @... 需打印的参数
216 @return nil 无返回值
217 @usage
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);
255 return 1;
258 void luat_log_dump(const char* tag, void* ptr, size_t len) {
259 if (ptr == NULL) {
260 luat_log_log(LUAT_LOG_DEBUG, tag, "ptr is NULL");
261 return;
263 if (len == 0) {
264 luat_log_log(LUAT_LOG_DEBUG, tag, "ptr len is 0");
265 return;
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]);
272 if (i % 8 == 7) {
273 luat_log_log(LUAT_LOG_DEBUG, tag, "%s", buff);
274 buff[0] = 0;
277 if (strlen(buff)) {
278 luat_log_log(LUAT_LOG_DEBUG, tag, "%s", buff);