alienwalker 3 лет назад
Родитель
Сommit
fc27e7c245
3 измененных файлов с 565 добавлено и 5 удалено
  1. 5 0
      luat/include/luat_log.h
  2. 557 5
      luat/modules/luat_lib_log.c
  3. 3 0
      luat/modules/luat_main.c

+ 5 - 0
luat/include/luat_log.h

@@ -19,6 +19,11 @@ uint8_t luat_log_get_uart_port(void);
 void luat_log_set_level(int level);
 int luat_log_get_level(void);
 
+#ifdef LUAT_USE_ERR_DUMP
+void luat_log_save_file(const uint8_t *data, uint32_t len);
+void luat_log_record_init(uint8_t enable, uint32_t upload_period);
+#endif
+
 #ifdef LUAT_USE_LOG2
 
 #define LLOGE(format, ...) luat_log_printf(LUAT_LOG_ERROR, "E/" LUAT_LOG_TAG " " format "\n", ##__VA_ARGS__)

+ 557 - 5
luat/modules/luat_lib_log.c

@@ -9,15 +9,49 @@
 #include "luat_base.h"
 #include "luat_sys.h"
 #include "luat_msgbus.h"
-
+#include "luat_zbuff.h"
 #include "ldebug.h"
-
+#include "luat_network_adapter.h"
+#include "luat_rtos.h"
+#include "luat_mobile.h"
 #define LUAT_LOG_TAG "log"
 #include "luat_log.h"
+#define ERR_DUMP_LEN_MAX	(4096)
+#define LUAT_ERRDUMP_PORT	(12425)
+const char luat_errdump_domain[] = "dev_msg1.openluat.com";
+enum
+{
+	LUAT_LOG_RECORD_TYPE_SYS,
+	LUAT_LOG_RECORD_TYPE_USR,
+	LUAT_LOG_RECORD_TYPE_NONE,
+
+	LUAT_ERRDUMP_CONNECT = 0,
+	LUAT_ERRDUMP_TX,
+	LUAT_ERRDUMP_RX,
+	LUAT_ERRDUMP_CLOSE,
+};
 
+static const char sys_error_log_file_path[] = {'/',0xaa,'s','e','r','r',0};
+static const char user_error_log_file_path[] = {'/',0xaa,'u','e','r','r',0};
 typedef struct luat_log_conf
 {
+#ifdef LUAT_USE_ERR_DUMP
+	Buffer_Struct tx_buf;
+	network_ctrl_t *netc;
+	char *user_string;
+	uint32_t upload_period;
+	uint32_t sys_error_r_cnt;
+	uint32_t sys_error_w_cnt;
+	uint32_t user_error_r_cnt;
+	uint32_t user_error_w_cnt;
+	luat_rtos_timer_t upload_timer;
+	luat_rtos_timer_t network_timer;
+	uint8_t is_uploading;
+	uint8_t error_dump_enable;
+	uint8_t upload_poweron_reason_done;
+#endif
     uint8_t style;
+
 }luat_log_conf_t;
 
 #define LOG_STYLE_NORMAL        0
@@ -112,9 +146,9 @@ static int l_log_set_level(lua_State *L) {
 -- 调试风格2, 添加额外的调试信息, 位置有所区别
 -- I/user.ABC main.lua:12 DEF 123
 
-log.setLevel("DEBUG", 0) -- 默认风格0
-log.setLevel("DEBUG", 1) -- 调试风格1
-log.setLevel("DEBUG", 2) -- 调试风格2
+log.style(0) -- 默认风格0
+log.style(1) -- 调试风格1
+log.style(2) -- 调试风格2
  */
 static int l_log_style(lua_State *L) {
     if (lua_isinteger(L, 1))
@@ -223,6 +257,519 @@ static int l_log_error(lua_State *L) {
     return l_log_2_log(L, "E");
 }
 
+#ifdef LUAT_USE_ERR_DUMP
+static void luat_log_load(const char *path, Buffer_Struct *buffer);
+static void luat_log_clear(const char *path);
+static int32_t l_errdump_callback(lua_State *L, void* ptr);
+static LUAT_RT_RET_TYPE luat_errdump_timer_callback(LUAT_RT_CB_PARAM);
+static LUAT_RT_RET_TYPE luat_errdump_rx_timer_callback(LUAT_RT_CB_PARAM);
+static int luat_errdump_network_callback(void *data, void *param)
+{
+	OS_EVENT *event = (OS_EVENT *)data;
+	int ret = 0;
+	rtos_msg_t msg = {0};
+	if (event->Param1)
+	{
+		LLOGE("errdump fail, after %d second retry", lconf.upload_period);
+		lconf.is_uploading = 0;
+		msg.handler = l_errdump_callback,
+		msg.arg1 = LUAT_ERRDUMP_CLOSE,
+		luat_msgbus_put(&msg, 0);
+		luat_rtos_timer_start(lconf.upload_timer, lconf.upload_period * 1000, 0, luat_errdump_timer_callback, NULL);
+		OS_DeInitBuffer(&lconf.tx_buf);
+	}
+	switch(event->ID)
+	{
+	case EV_NW_RESULT_CONNECT:
+		msg.handler = l_errdump_callback,
+		msg.arg1 = LUAT_ERRDUMP_TX,
+		luat_msgbus_put(&msg, 0);
+		break;
+	case EV_NW_RESULT_EVENT:
+		msg.handler = l_errdump_callback,
+		msg.arg1 = LUAT_ERRDUMP_RX,
+		luat_msgbus_put(&msg, 0);
+		break;
+	case EV_NW_RESULT_CLOSE:
+		break;
+	}
+	return 0;
+}
+
+static void luat_errdump_make_data(lua_State *L)
+{
+	const char *project = "unkonw";
+	const char *version = "";
+	char imei[16] = {0};
+	char *sn = version;
+	FILE* fd;
+	size_t len;
+	luat_mobile_get_imei(0, imei, 15);
+    lua_getglobal(L, "PROJECT");
+    size_t version_len, project_len;
+    if (LUA_TSTRING == lua_type(L, -1))
+    {
+    	project = luaL_tolstring(L, -1, &project_len);
+    }
+    lua_getglobal(L, "VERSION");
+    if (LUA_TSTRING == lua_type(L, -1))
+    {
+    	version = luaL_tolstring(L, -1, &version_len);
+    }
+    int32_t file_len[LUAT_LOG_RECORD_TYPE_NONE];
+    lconf.sys_error_r_cnt = lconf.sys_error_w_cnt;
+    file_len[LUAT_LOG_RECORD_TYPE_SYS] = luat_fs_fsize(sys_error_log_file_path);
+    lconf.user_error_r_cnt = lconf.user_error_w_cnt;
+    file_len[LUAT_LOG_RECORD_TYPE_USR] = luat_fs_fsize(user_error_log_file_path);
+    if (file_len[LUAT_LOG_RECORD_TYPE_SYS] < 0)
+    {
+    	file_len[LUAT_LOG_RECORD_TYPE_SYS] = 0;
+    }
+    if (file_len[LUAT_LOG_RECORD_TYPE_USR] < 0)
+    {
+    	file_len[LUAT_LOG_RECORD_TYPE_USR] = 0;
+    }
+    if (lconf.user_string)
+    {
+    	sn = lconf.user_string;
+    }
+    OS_ReInitBuffer(&lconf.tx_buf, file_len[LUAT_LOG_RECORD_TYPE_USR] + file_len[LUAT_LOG_RECORD_TYPE_SYS] + 128);
+    lconf.tx_buf.Pos = sprintf_(lconf.tx_buf.Data, "%s_LuatOS-SoC_%s_%s,%s,%s,%s,\r\n", project, luat_version_str(), luat_os_bsp(), version, imei, sn);
+    if (!lconf.upload_poweron_reason_done)
+    {
+    	lconf.tx_buf.Pos += sprintf_(lconf.tx_buf.Data + lconf.tx_buf.Pos, "poweron reason:%d\r\n", luat_pm_get_poweron_reason());
+    }
+    if (file_len[LUAT_LOG_RECORD_TYPE_SYS] > 0)
+    {
+    	fd = luat_fs_fopen(sys_error_log_file_path, "r");
+    	len = luat_fs_fread(lconf.tx_buf.Data + lconf.tx_buf.Pos, file_len[LUAT_LOG_RECORD_TYPE_SYS], 1, fd);
+    	if (len > 0)
+    	{
+    		lconf.tx_buf.Pos += len;
+    		lconf.tx_buf.Data[lconf.tx_buf.Pos] = '\r';
+    		lconf.tx_buf.Data[lconf.tx_buf.Pos + 1] = '\n';
+    		lconf.tx_buf.Pos += 2;
+    	}
+    	luat_fs_fclose(fd);
+    }
+    if (file_len[LUAT_LOG_RECORD_TYPE_USR] > 0)
+    {
+    	fd = luat_fs_fopen(user_error_log_file_path, "r");
+    	len = luat_fs_fread(lconf.tx_buf.Data + lconf.tx_buf.Pos, file_len[LUAT_LOG_RECORD_TYPE_USR], 1, fd);
+    	if (len > 0)
+    	{
+    		lconf.tx_buf.Pos += len;
+    		lconf.tx_buf.Data[lconf.tx_buf.Pos] = '\r';
+    		lconf.tx_buf.Data[lconf.tx_buf.Pos + 1] = '\n';
+    		lconf.tx_buf.Pos += 2;
+    	}
+    	luat_fs_fclose(fd);
+    }
+}
+
+static int32_t l_errdump_callback(lua_State *L, void* ptr)
+{
+	uint32_t dummy_len;
+    rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
+    switch(msg->arg1)
+    {
+    case LUAT_ERRDUMP_CONNECT:
+    	lconf.netc = network_alloc_ctrl(network_get_last_register_adapter());
+    	if (!lconf.netc)
+    	{
+    		LLOGE("no socket, errdump fail, after %d second retry", lconf.upload_period);
+    		lconf.is_uploading = 0;
+    		luat_rtos_timer_start(lconf.upload_timer, lconf.upload_period * 1000, 0, luat_errdump_timer_callback, NULL);
+    		OS_DeInitBuffer(&lconf.tx_buf);
+
+    	}
+    	else
+    	{
+    		network_init_ctrl(lconf.netc, NULL, luat_errdump_network_callback, NULL);
+    		network_set_base_mode(lconf.netc, 0, 0, 0, 0, 0, 0);
+    		network_set_local_port(lconf.netc, 0);
+    		luat_rtos_timer_start(lconf.network_timer, 30000, 0, luat_errdump_rx_timer_callback, NULL);
+    		network_connect(lconf.netc, luat_errdump_domain, sizeof(luat_errdump_domain), NULL, LUAT_ERRDUMP_PORT, 0);
+    	}
+    	break;
+    case LUAT_ERRDUMP_TX:
+    	if (!lconf.tx_buf.Data)
+    	{
+    		luat_errdump_make_data(L);
+    	}
+    	else
+    	{
+    		if (lconf.sys_error_r_cnt != lconf.sys_error_w_cnt || lconf.user_error_r_cnt != lconf.user_error_w_cnt)
+    		{
+    			msg->arg2 = 0;
+    			luat_errdump_make_data(L);
+    		}
+    	}
+
+    	if (network_tx(lconf.netc, lconf.tx_buf.Data, lconf.tx_buf.Pos, 0, NULL, 0, &dummy_len, 0))
+    	{
+    		LLOGE("socket tx error, errdump fail, after %d second retry", lconf.upload_period);
+    		luat_rtos_timer_start(lconf.upload_timer, lconf.upload_period * 1000, 0, luat_errdump_timer_callback, NULL);
+			goto SOCKET_CLOSE;
+    	}
+    	luat_rtos_timer_start(lconf.network_timer, 10000, 0, luat_errdump_rx_timer_callback, (void *)(msg->arg2 + 1));
+    	break;
+    case LUAT_ERRDUMP_RX:
+    	uint8_t response[16];
+    	luat_ip_addr_t remote_ip;
+    	uint16_t remote_port;
+    	if (network_rx(lconf.netc, response, 16, 0, &remote_ip, &remote_port, &dummy_len))
+    	{
+    		LLOGE("socket rx error, errdump fail, after %d second retry", lconf.upload_period);
+    		luat_rtos_timer_start(lconf.upload_timer, lconf.upload_period * 1000, 0, luat_errdump_timer_callback, NULL);
+			goto SOCKET_CLOSE;
+    	}
+    	if (dummy_len >= 2)
+    	{
+    		if ('O' == response[0] && 'K' == response[1])
+    		{
+        		if (lconf.sys_error_r_cnt != lconf.sys_error_w_cnt || lconf.user_error_r_cnt != lconf.user_error_w_cnt)
+        		{
+        			LLOGD("errdump need retry!");
+        			luat_errdump_make_data(L);
+        			if (network_tx(lconf.netc, lconf.tx_buf.Data, lconf.tx_buf.Pos, 0, NULL, 0, &dummy_len, 0))
+					{
+						LLOGE("socket tx error, errdump fail, after %d second retry", lconf.upload_period);
+						luat_rtos_timer_start(lconf.upload_timer, lconf.upload_period * 1000, 0, luat_errdump_timer_callback, NULL);
+						goto SOCKET_CLOSE;
+					}
+					luat_rtos_timer_start(lconf.network_timer, 10000, 0, luat_errdump_rx_timer_callback, (void *)1);
+        		}
+        		else
+        		{
+        			LLOGD("errdump ok!");
+        			luat_log_clear(sys_error_log_file_path);
+        			luat_log_clear(user_error_log_file_path);
+        			lconf.upload_poweron_reason_done = 1;
+        			goto SOCKET_CLOSE;
+        		}
+    		}
+    	}
+    	break;
+    case LUAT_ERRDUMP_CLOSE:
+    	goto SOCKET_CLOSE;
+    	break;
+    }
+    return 0;
+SOCKET_CLOSE:
+	luat_rtos_timer_stop(lconf.network_timer);
+	lconf.is_uploading = 0;
+	network_close(lconf.netc, 0);
+	network_release_ctrl(lconf.netc);
+	OS_DeInitBuffer(&lconf.tx_buf);
+	lconf.netc = NULL;
+	return 0;
+}
+
+static LUAT_RT_RET_TYPE luat_errdump_rx_timer_callback(LUAT_RT_CB_PARAM)
+{
+	if (param)
+	{
+		uint32_t retry = (uint32_t)param;
+		if (retry < 3)
+		{
+			LLOGE("errdump tx fail %d cnt, retry", retry);
+			rtos_msg_t msg = {
+				.handler = l_errdump_callback,
+				.ptr = NULL,
+				.arg1 = LUAT_ERRDUMP_TX,
+				.arg2 = retry,
+			};
+			luat_msgbus_put(&msg, 0);
+		}
+	}
+	else
+	{
+		LLOGE("errdump server connect fail, after %d second retry", lconf.upload_period);
+		rtos_msg_t msg = {
+			.handler = l_errdump_callback,
+			.ptr = NULL,
+			.arg1 = LUAT_ERRDUMP_CLOSE,
+			.arg2 = 0,
+		};
+		luat_msgbus_put(&msg, 0);
+		lconf.is_uploading = 0;
+		luat_rtos_timer_start(lconf.upload_timer, lconf.upload_period * 1000, 0, luat_errdump_timer_callback, NULL);
+	}
+}
+
+
+
+static LUAT_RT_RET_TYPE luat_errdump_timer_callback(LUAT_RT_CB_PARAM)
+{
+
+	if (!lconf.upload_poweron_reason_done || luat_fs_fsize(sys_error_log_file_path) > 0 || luat_fs_fsize(user_error_log_file_path) > 0)
+	{
+		lconf.is_uploading = 1;
+		rtos_msg_t msg = {
+			.handler = l_errdump_callback,
+			.ptr = NULL,
+			.arg1 = LUAT_ERRDUMP_CONNECT,
+			.arg2 = 0,
+		};
+		luat_msgbus_put(&msg, 0);
+	}
+	else
+	{
+		LLOGD("no info errdump stop");
+	}
+}
+
+static void luat_log_save(const char *path, const uint8_t *data, uint32_t len)
+{
+	if (!lconf.error_dump_enable) return;
+	FILE* fd = luat_fs_fopen(path, "a+");
+	if (!fd)
+	{
+		return;
+	}
+	size_t now_len = luat_fs_fsize(path);
+	if ((now_len + len) > ERR_DUMP_LEN_MAX)
+	{
+		uint8_t *buffer = luat_heap_malloc(now_len + len);
+		if (!buffer)
+		{
+			return;
+		}
+		luat_fs_fseek(fd, 0, SEEK_SET);
+		luat_fs_fread(buffer, now_len, 1, fd);
+		memcpy(buffer + now_len, data, len);
+		luat_fs_fseek(fd, 0, SEEK_SET);
+		luat_fs_fwrite(buffer + (now_len + len) - ERR_DUMP_LEN_MAX, ERR_DUMP_LEN_MAX, 1, fd);
+		luat_heap_free(buffer);
+	}
+	else
+	{
+		luat_fs_fwrite(data, len, 1, fd);
+	}
+	luat_fs_fclose(fd);
+	if (!lconf.is_uploading)
+	{
+		luat_rtos_timer_start(lconf.upload_timer, 2000, 0, luat_errdump_timer_callback, NULL);
+	}
+
+}
+
+static void luat_log_clear(const char *path)
+{
+	if (luat_fs_fexist(path)) luat_fs_remove(path);
+}
+
+static void luat_log_load(const char *path, Buffer_Struct *buffer)
+{
+	if (!lconf.error_dump_enable) return;
+	size_t len = luat_fs_fsize(path);
+	if (!len)
+	{
+		return;
+	}
+	FILE* fd = luat_fs_fopen(path, "a+");
+	if (buffer->MaxLen < len)
+	{
+		OS_ReInitBuffer(buffer, len);
+	}
+	len = luat_fs_fread(buffer->Data, len, 1, fd);
+	if (len > 0)
+	{
+		buffer->Pos = len;
+	}
+	luat_fs_fclose(fd);
+}
+
+
+
+#endif
+
+void luat_log_save_file(const uint8_t *data, uint32_t len)
+{
+#ifdef LUAT_USE_ERR_DUMP
+	lconf.sys_error_w_cnt++;
+	luat_log_save(sys_error_log_file_path, data, len);
+	lconf.sys_error_w_cnt++;
+#endif
+}
+
+void luat_log_record_init(uint8_t enable, uint32_t upload_period)
+{
+#ifdef LUAT_USE_ERR_DUMP
+	lconf.error_dump_enable = enable;
+	if (lconf.error_dump_enable)
+	{
+		if (upload_period)
+		{
+			if (!lconf.upload_timer)
+			{
+				luat_rtos_timer_create(&lconf.upload_timer);
+			}
+			if (!lconf.network_timer)
+			{
+				luat_rtos_timer_create(&lconf.network_timer);
+			}
+			lconf.upload_period = upload_period;
+			luat_rtos_timer_start(lconf.upload_timer, 2000, 0, luat_errdump_timer_callback, NULL);
+			luat_rtos_timer_stop(lconf.network_timer);
+		}
+		else
+		{
+			lconf.upload_period = 0;
+			luat_rtos_timer_delete(lconf.upload_timer);
+			luat_rtos_timer_delete(lconf.network_timer);
+		}
+	}
+	else
+	{
+		luat_log_clear(sys_error_log_file_path);
+		luat_log_clear(user_error_log_file_path);
+		luat_rtos_timer_delete(lconf.upload_timer);
+		luat_rtos_timer_delete(lconf.network_timer);
+		if (lconf.user_string)
+		{
+			luat_heap_free(lconf.user_string);
+			lconf.user_string = NULL;
+		}
+	}
+#endif
+}
+
+/*
+读取异常日志,这里可以读取系统和用户的,主要用于用户发送给自己的服务器,如果配置了周期上传,请不要使用!!!
+@api    log.dump(zbuff, type, isDelete)
+@zbuff 日志信息缓存,如果为nil就不会读出,一般当
+@int 日志类型,目前只有log.TYPE_SYS和log.TYPE_USR
+@boolean 是否删除日志
+@return boolean true表示本次读取前并没有写入数据,false反之,在删除日志前,最好再读一下确保没有新的数据写入了
+@usage
+local result = log.dump(buff, log.TYPE_SYS, false) --读出系统记录的异常日志
+local result = log.dump(nil, log.TYPE_SYS, true) --清除系统记录的异常日志
+*/
+static int l_log_dump(lua_State *L) {
+#ifdef LUAT_USE_ERR_DUMP
+	int is_delete = 0;
+	if (LUA_TBOOLEAN == lua_type(L, 3))
+	{
+		is_delete = lua_toboolean(L, 3);
+	}
+	luat_zbuff_t *buff = tozbuff(L);
+	int result = 0;
+	const char *path = NULL;
+	int type = luaL_optinteger(L, 2, LUAT_LOG_RECORD_TYPE_USR);
+	if (type >= LUAT_LOG_RECORD_TYPE_NONE)
+	{
+		lua_pushboolean(L, 1);
+		return 1;
+	}
+
+	switch(type)
+	{
+	case LUAT_LOG_RECORD_TYPE_SYS:
+		result = (lconf.sys_error_r_cnt != lconf.sys_error_w_cnt);
+		path = sys_error_log_file_path;
+		break;
+	case LUAT_LOG_RECORD_TYPE_USR:
+		result = (lconf.user_error_r_cnt != lconf.user_error_w_cnt);
+		path = user_error_log_file_path;
+		break;
+	}
+	if (buff)
+	{
+		Buffer_Struct buffer;
+		buffer.Data = buff->addr;
+		buffer.MaxLen = buff->len;
+		buffer.Pos = 0;
+		switch(type)
+		{
+		case LUAT_LOG_RECORD_TYPE_SYS:
+			lconf.sys_error_r_cnt = lconf.sys_error_w_cnt;
+			break;
+		case LUAT_LOG_RECORD_TYPE_USR:
+			lconf.user_error_r_cnt = lconf.user_error_w_cnt;
+			break;
+		}
+
+		buff->addr = buffer.Data;
+		buff->len = buffer.MaxLen;
+		buff->used = buffer.Pos;
+		luat_log_load(path, &buffer);
+	}
+	lua_pushboolean(L, result);
+	if (is_delete)
+	{
+		luat_log_clear(path);
+	}
+#else
+	lua_pushboolean(L, 1);
+#endif
+	return 1;
+}
+
+/*
+写入用户的异常日志,注意最大只有4KB,超过部分新的覆盖旧的,开启自动上传后会上传到合宙IOT平台
+@api    log.record(string)
+@string  日志
+@return nil 无返回值
+@usage
+log.record("socket long time no connect") --记录下"socket long time no connect"
+*/
+static int l_log_record(lua_State *L) {
+#ifdef LUAT_USE_ERR_DUMP
+	if (LUA_TSTRING == lua_type(L, 1))
+	{
+		size_t len = 0;
+		const char *str = luaL_tolstring(L, 1, &len);
+		if (len)
+		{
+			lconf.user_error_w_cnt++;
+			luat_log_save(user_error_log_file_path, str, len);
+			lconf.user_error_w_cnt++;
+		}
+	}
+#endif
+	return 0;
+}
+
+/*
+配置关键日志上传IOT平台,这里的日志包括引起luavm异常退出的日志和用户通过record写入的日志,类似于air的errDump
+@api    log.uploadConfig(enable, period, user_flag)
+@boolean  是否启用记录功能,false的话将不会记录任何日志
+@int     定时上传周期,单位秒,默认600秒,这个是自动上传时候后的重试时间时间,在开机后或者有record操作后会很快尝试上传到合宙IOT平台一次,如果为0,则不会上传,由用户dump后自己上传自己的平台
+@string 用户的特殊标识,可以为空
+@return nil 无返回值
+@usage
+log.uploadConfig(true, 3600, "12345678")	--一个小时尝试上次一次,上传时会在imei后附加上12345678
+log.uploadConfig(false)	--关闭记录功能,不再上传
+log.uploadConfig(true, 0)	--记录,但是不会主动上传,由用户实现上传功能
+*/
+static int l_log_upload_config(lua_State *L) {
+#ifdef LUAT_USE_ERR_DUMP
+	if (LUA_TBOOLEAN == lua_type(L, 1))
+	{
+		luat_log_record_init(lua_toboolean(L, 1), luaL_optinteger(L, 2, 600));
+	}
+	if (lconf.error_dump_enable)
+	{
+		if (LUA_TSTRING == lua_type(L, 3))
+		{
+			size_t len = 0;
+			const char *str = luaL_tolstring(L, 3, &len);
+			if (lconf.user_string)
+			{
+				luat_heap_free(lconf.user_string);
+				lconf.user_string = NULL;
+			}
+			lconf.user_string = luat_heap_malloc(len + 1);
+			memcpy(lconf.user_string, str, len + 1);
+		}
+	}
+
+#endif
+	return 0;
+}
+
 #include "rotable2.h"
 static const rotable_Reg_t reg_log[] =
 {
@@ -234,6 +781,9 @@ static const rotable_Reg_t reg_log[] =
     { "setLevel" ,  ROREG_FUNC(l_log_set_level)},
     { "getLevel" ,  ROREG_FUNC(l_log_get_level)},
     { "style",      ROREG_FUNC(l_log_style)},
+	{ "dump",		ROREG_FUNC(l_log_dump)},
+	{ "record", 	ROREG_FUNC(l_log_record)},
+	{ "uploadConfig", 	ROREG_FUNC(l_log_upload_config)},
     //{ "_log" ,      ROREG_FUNC(l_log_2_log)},
 
 
@@ -247,6 +797,8 @@ static const rotable_Reg_t reg_log[] =
     { "LOG_WARN",   ROREG_INT(LUAT_LOG_WARN)},
     //@const LOG_ERROR number error日志模式
     { "LOG_ERROR",  ROREG_INT(LUAT_LOG_ERROR)},
+	{ "TYPE_SYS",  ROREG_INT(LUAT_LOG_RECORD_TYPE_SYS)},
+	{ "TYPE_USR",  ROREG_INT(LUAT_LOG_RECORD_TYPE_USR)},
 	{ NULL,         ROREG_INT(0) }
 };
 

+ 3 - 0
luat/modules/luat_main.c

@@ -108,6 +108,9 @@ static int report (lua_State *L, int status) {
   if (status != LUA_OK) {
     const char *msg = lua_tostring(L, -1);
     l_message("LUAT", msg);
+#ifdef LUAT_USE_ERR_DUMP
+    luat_log_save_file(msg, strlen(msg));
+#endif
     lua_pop(L, 1);  /* remove message */
   }
   return status;