[Feature][T108] [task-view-1683] realize Log storage requirements from gsw

Only Configure: No
Affected branch: GSW_V1453
Affected module: log
Self-test: yes
Doc Update: no

Change-Id: Ie7bc0d95dfb77dd8f74d9571907885d77d631267
diff --git a/mbtk/rootfs/etc/init.d/mbtk_boot_server_ready b/mbtk/rootfs/etc/init.d/mbtk_boot_server_ready
index f0fdaf1..26ab10a 100755
--- a/mbtk/rootfs/etc/init.d/mbtk_boot_server_ready
+++ b/mbtk/rootfs/etc/init.d/mbtk_boot_server_ready
@@ -20,6 +20,7 @@
 
 	#mbtk_start /bin/mbtk_info_test
 	mbtk_start /bin/mbtk_logd
+        mbtk_start /bin/gsw_log_check
     # i2s ×ó¶ÔÆë´«ÊäģʽÉèÖÃÖ¸Áî
 	#ubus call audio_if config_pcmexpert "{ 'frame_format': 1, 'invert_frame' : 0, 'frame_polarity' : 1, 'bitclk_polarity' : 0, 'fsyc_shift' : 1}"
 	echo "--mbtk server ready boot end--" > /dev/kmsg
diff --git a/mbtk/test/libgsw_lib/gsw_log_check.c b/mbtk/test/libgsw_lib/gsw_log_check.c
new file mode 100755
index 0000000..510b815
--- /dev/null
+++ b/mbtk/test/libgsw_lib/gsw_log_check.c
@@ -0,0 +1,604 @@
+#include <stdio.h>

+#include <stdlib.h>

+#include <string.h>

+#include <dirent.h>

+#include <regex.h>

+#include <sys/stat.h>

+#include <sys/time.h>

+#include <time.h>

+#include <limits.h>

+#include <fcntl.h>

+#include <unistd.h>

+#include <ctype.h>

+#include <dlfcn.h>

+

+

+typedef void (*mbtk_log)(int level, const char *format,...);

+static void *handle = NULL;

+static mbtk_log fun_ptr_log = NULL;

+#define LIB_PATH				 "/lib/libmbtk_lib.so"

+#define LOG_LEVLE_CONFIG_FILE 	 "/etc/telinit"

+#define MAX_FILES 500

+#define MAX_PATH  100

+#define CP_LOG_PATH  	"/media/var/log"

+#define DUMP_LOG_PATH  	"/media/var/log/modem_dump"

+#define EMMC_HEALTH 	"/sys/kernel/debug/mmc0/mmc0:0001/health"

+#define CP_LOG_MAX_SIZE 	(600 * 1024 * 1024)

+#define DUMP_LOG_MAX_SIZE 	(100 * 1024 * 1024)

+#define SEVEN_DAYS_SECONDS  (7 * 24 * 60 * 60)

+

+#ifndef LOG_ERR_LEVEL

+#define LOG_ERR_LEVEL  3      /* error conditions */

+#endif

+#ifndef LOG_WARN_LEVEL

+#define LOG_WARN_LEVEL 4   /* warning conditions */

+#endif

+#ifndef LOG_INFO_LEVEL

+#define LOG_INFO_LEVEL 6      /* informational */

+#endif

+#ifndef LOG_DEBUG_LEVEL

+#define LOG_DEBUG_LEVEL 7     /* debug-level messages */

+#endif

+#ifndef LOG_VERBOSE_LEVEL

+#define LOG_VERBOSE_LEVEL 8

+#endif

+

+#define LOGV(fmt, args ...) \

+    do{ \

+        char *file_ptr_1001 = __FILE__; \

+        char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1;   \

+        char line_1001[10] = {0}; \

+        sprintf(line_1001, "%d", __LINE__); \

+        while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \

+            if(*ptr_1001 == '/') \

+                 break; \

+            ptr_1001--; \

+        } \

+        fun_ptr_log(LOG_INFO_LEVEL, "%s#%s: [log_check]" fmt, ptr_1001 + 1, line_1001, ##args); \

+    } while(0)

+

+#define LOGI(fmt, args...) \

+    do{ \

+        char *file_ptr_1001 = __FILE__; \

+        char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1;   \

+        char line_1001[10] = {0}; \

+        sprintf(line_1001, "%d", __LINE__); \

+        while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \

+            if(*ptr_1001 == '/') \

+                 break; \

+            ptr_1001--; \

+        } \

+        fun_ptr_log(LOG_INFO_LEVEL, "%s#%s: [log_check]" fmt, ptr_1001 + 1, line_1001, ##args); \

+    } while(0)

+

+#define LOGD(fmt, args...) \

+    do{ \

+        char *file_ptr_1001 = __FILE__; \

+        char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1;   \

+        char line_1001[10] = {0}; \

+        sprintf(line_1001, "%d", __LINE__); \

+        while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \

+            if(*ptr_1001 == '/') \

+                 break; \

+            ptr_1001--; \

+        } \

+        fun_ptr_log(LOG_INFO_LEVEL, "%s#%s: [log_check]" fmt, ptr_1001 + 1, line_1001, ##args); \

+    } while(0)

+

+#define LOGW(fmt, args...) \

+    do{ \

+        char *file_ptr_1001 = __FILE__; \

+        char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1;   \

+        char line_1001[10] = {0}; \

+        sprintf(line_1001, "%d", __LINE__); \

+        while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \

+            if(*ptr_1001 == '/') \

+                 break; \

+            ptr_1001--; \

+        } \

+        fun_ptr_log(LOG_INFO_LEVEL, "%s#%s: [log_check]" fmt, ptr_1001 + 1, line_1001, ##args); \

+    } while(0)

+

+#define LOGE(fmt, args...) \

+    do{ \

+		char *file_ptr_1001 = __FILE__; \

+		char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1;   \

+		char line_1001[10] = {0}; \

+		sprintf(line_1001, "%d", __LINE__); \

+		while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \

+			if(*ptr_1001 == '/') \

+				break; \

+			ptr_1001--; \

+		} \

+		fun_ptr_log(LOG_INFO_LEVEL, "%s#%s: [log_check]" fmt, ptr_1001 + 1, line_1001, ##args); \

+	} while(0)

+

+int32_t init_handle()

+{

+	handle = dlopen(LIB_PATH, RTLD_NOW);

+	if(handle == NULL)

+	{

+		return -1;

+	}

+	if(fun_ptr_log == NULL)

+	{

+		fun_ptr_log = (mbtk_log)dlsym(handle, "mbtk_log");

+		if(fun_ptr_log ==  NULL)

+		{

+			return -1;

+		}

+	}

+	return 0;

+}

+

+typedef struct {

+	char name[128];

+	time_t mtime;

+	off_t size;

+} LogDir;

+

+int compare_mtime(const void *a, const void *b) {

+	LogDir *dirA = (LogDir *)a;

+	LogDir *dirB = (LogDir *)b;

+	return (dirA->mtime - dirB->mtime); // 升序排序

+}

+

+static int get_cp_log_folder(char *path, LogDir *dirs, int *dirs_count)

+{

+    DIR *dp    = NULL;

+	DIR *subdp = NULL;

+	struct dirent *entry;

+	struct dirent *subentry;

+	struct stat st;

+	regex_t regex;

+	int 	count = 0;

+	int  	folder_size = 0;

+	int  	total_size  = 0;

+	char 	full_path[1024];

+	char 	temp_path[1024];

+	

+    // 编译正则表达式:^Log[0-9]{3}.*

+    if (regcomp(&regex, "^Log[0-9]{3}.*", REG_EXTENDED) != 0) 

+	{

+		fprintf(stderr, "Failed to compile regex.\n");

+		return -1;

+		}

+

+	dp = opendir(path);

+	if (dp == NULL) 

+	{

+		perror("opendir");

+		return -1;

+    }

+

+    while ((entry = readdir(dp)) != NULL) 

+	{

+		if (regexec(&regex, entry->d_name, 0, NULL, 0) == 0)   //entr:Log00x

+		{

+			snprintf(full_path, sizeof(full_path), "%s/%s", path, entry->d_name);

+			strncpy(dirs[count].name, full_path, sizeof(dirs[count].name));

+			//printf("flod:%s \n", full_path);

+

+			if (strstr(full_path, "tar.gz") != NULL)    		//tar file

+			{

+				if (lstat(full_path, &st) < 0)

+				{

+					perror("lstat");

+				}	

+				folder_size += st.st_size;

+				dirs[count].mtime = st.st_mtime;

+

+			}

+			else 

+			{

+				subdp = opendir(full_path); 					//Log00x Folder

+				if (NULL == subdp)

+				{

+					LOGE("cant open:%s\n", full_path);

+					continue;

+				}

+				

+				while ((subentry = readdir(subdp)) != NULL) 

+				{

+					if (strcmp(subentry->d_name, ".") == 0 || strcmp(subentry->d_name, "..") == 0)

+						continue;

+					

+					//snprintf(temp_path, sizeof(temp_path), "%s/%s", full_path, subentry->d_name);

+					temp_path[0] = '\0';

+					strncat(temp_path, full_path, sizeof(temp_path) - 1);

+					strncat(temp_path, "/", sizeof(temp_path) - strlen(temp_path) - 1);

+					strncat(temp_path, subentry->d_name, sizeof(temp_path) - strlen(temp_path) - 1);

+					

+					//printf("file:%s \n", temp_path);

+	

+					if (lstat(temp_path, &st) < 0) 

+					{

+						perror("lstat");

+						continue;

+					}

+					if (S_ISREG(st.st_mode)) 

+					{

+						folder_size += st.st_size;

+						dirs[count].mtime = st.st_mtime;

+					}

+				

+				}

+				if(NULL != subdp)

+					closedir(subdp);

+

+			}

+			dirs[count].size = folder_size;

+			total_size += folder_size;

+			folder_size = 0;

+			count++;

+			

+			if (count >= MAX_FILES) 

+			{

+				fprintf(stderr, "Too many matching directories, increase MAX_DIRS.\n");

+				break;

+			}

+		}

+	}

+	

+	closedir(dp);

+	regfree(&regex);

+	qsort(dirs, count, sizeof(LogDir), compare_mtime);

+	

+	*dirs_count = count;

+	return total_size;

+

+}

+

+static int get_dump_log_folder(char *path, LogDir *files, int *dirs_count)

+{

+	

+	DIR *dp = NULL;

+	struct dirent *entry;

+	char full_path[4096];

+	int  total_size = 0;

+	int  count = 0;

+	struct stat st;

+

+	dp = opendir(path);

+	if (NULL == dp) 

+	{

+		perror("opendir");

+		return -1;

+	}

+

+    while ((entry = readdir(dp)) != NULL)

+	{

+		if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)

+			continue;

+		snprintf(full_path, sizeof(full_path), "%s/%s", path, entry->d_name);

+

+		

+

+		

+		//printf("file:%s \n", full_path);

+		

+		if (lstat(full_path, &st) < 0) {

+			perror("lstat");

+			continue;

+		}

+		if (S_ISREG(st.st_mode)) {

+			total_size += st.st_size;			

+			strncpy(files[count].name, full_path, sizeof(files[count].name));

+			files[count].size = st.st_size;

+			files[count++].mtime = st.st_mtime;

+		}

+    }

+	if(NULL != dp)

+		closedir(dp);

+	*dirs_count = count;

+	

+	qsort(files, count, sizeof(LogDir), compare_mtime);

+	return total_size;

+

+}

+

+

+int get_emmc_health(char *path)

+{

+	char buffer[1024];

+	int 	result = -1;

+	int 	i = 0;

+	int fd = open(path, O_RDONLY);

+	if (fd == -1)

+	{

+		LOGE("can not open health node");

+		return -1;

+	}

+

+	ssize_t bytes_read = read(fd, buffer, sizeof(buffer) - 1);

+	if (bytes_read > 0) 

+	{

+		buffer[bytes_read] = '\0';

+		LOGI("emmc health node string:\n%s len:%d\n", buffer, bytes_read);

+	}

+	close(fd);

+	

+	for(i = 0; i < bytes_read; i++)

+	{

+		if('-' == buffer[i])

+		{

+			char num_str[4] = {buffer[i+1], buffer[i+2], buffer[i+3], '\0'};

+			result = atoi(num_str);

+			LOGI("emmc health %d\n", result);

+			break;

+		}

+	}

+	

+	return result;

+

+}

+

+int set_log_level(const char *log_level)

+{

+	char 	command[256] = {0};

+	char 	*log_levl_param[6] = {"default", "cp_load", "atcmdsrv", "ciClientStubTas", "nvmproxy", "rild"};

+	int 	i = 0;

+	

+	for(i = 0; i < 6; i++)

+	{

+		snprintf(command, sizeof(command), 

+		         "sed -i 's/\\(setprop sys.%s.loglevel \\)\\S*/\\1%s/' %s",

+		         log_levl_param[i], log_level, LOG_LEVLE_CONFIG_FILE);

+		

+		int result = system(command);

+		if (result != 0) 

+		{

+		    LOGE("command execution failed.\n", command);

+		    return -1;

+		}

+	}

+	

+	return 0;

+}

+

+

+

+int is_modified_within_7_days(LogDir dir) 

+{

+	time_t now = time(NULL);

+	time_t mtime = dir.mtime;

+

+	// 计算时间差

+	double diff = difftime(now, mtime);

+

+	if (diff <= SEVEN_DAYS_SECONDS) 

+	{

+		return 1;

+	} else {

+		return 0;

+	}

+}

+

+int tar_log_file(const char *path_name, time_t mtime)

+{

+	char command[256] = {0};

+	struct timeval times[2];

+	char tar_file[128];

+	struct stat st;

+    time_t now;

+    struct tm *tm_info;

+    char time_str[64];

+	int ret; 

+	

+	LOGI("input log file: %s\n", path_name);

+	time(&now);

+	tm_info = localtime(&now);

+	strftime(time_str, sizeof(time_str), "%Y-%m-%d-%H:%M:%S", tm_info);

+	snprintf(tar_file, sizeof(tar_file)," %s-%s.tar.gz", path_name, time_str);

+	

+	LOGI("input log file: %s\n", tar_file);

+	

+	snprintf(command, sizeof(command), "tar -czvf %s %s", tar_file, path_name);

+	ret = system(command);

+	if (ret != 0) 

+	{

+		LOGE("command execution failed.\n", command);

+		return -1;

+	}

+

+

+	if (lstat(tar_file, &st) < 0) 

+	{

+	    return -1;

+	}

+	times[0].tv_sec = st.st_atime;

+	times[0].tv_usec = 0;

+	times[1].tv_sec = mtime;

+	times[1].tv_usec = 0;

+

+	if (utimes(tar_file, times) < 0)		

+	{

+	    return -1;

+	}	//update tar file mtime

+	

+	return 0;

+

+}

+

+

+int main(int argc, char* argv[])

+{

+	int health;

+	LogDir cp_dirs[MAX_FILES];

+	LogDir dump_files[MAX_FILES];

+	int cp_dirs_count = 0;

+	int dump_files_count = 0;

+	int i = 0;

+	int ret = 0;

+	char command[128] = {0};

+	int total_size = 0;

+	int modify_7day;

+	init_handle();

+	

+	health = get_emmc_health(EMMC_HEALTH);

+	if(health != -1)

+	{	

+		if(health >= 50 && health < 70)

+		{

+			ret = set_log_level("5");			//warn

+			if(ret != 0)

+				LOGE("set log level error\n");

+		}

+		

+		if(health >= 70)

+		{

+			ret = set_log_level("0");				

+			if(ret != 0)

+				LOGE("set log level error\n");

+		}

+	}

+	else

+	{

+		LOGE("get emmc health error\n");

+	}

+

+	while(1)

+	{

+		i = 0;

+		total_size = get_cp_log_folder(CP_LOG_PATH, cp_dirs, &cp_dirs_count);

+		LOGI("module %s files size:%d MB\n",CP_LOG_PATH, (total_size/1024)/1024);

+		while(total_size >= CP_LOG_MAX_SIZE)

+		{

+			LOGI("Exceed capacity limit:%d MB  now:%d MB\n", (CP_LOG_MAX_SIZE/1024)/1024, (total_size/1024)/1024);

+			if(i >= cp_dirs_count)

+			{

+				LOGE("No more files that can be compressed\n");

+				break;

+			}

+			modify_7day = is_modified_within_7_days(cp_dirs[i]);

+			if(modify_7day == 0)

+			{

+				//Delete files created for more than 7 days

+				//snprintf(command, sizeof(command), "rm -rf %s", cp_dirs[i].name);

+				command[0] = '\0';

+				strncat(command, "rm -rf ", sizeof(command) - 1);

+				strncat(command, cp_dirs[i].name, sizeof(command) - strlen(command) - 1);

+				

+				LOGI("Delete files:%s created for more than 7 days\n", cp_dirs[i].name);

+				ret = system(command);

+				if (ret != 0) 

+				{

+					LOGE("command execution failed.\n", command);

+					return -1;

+				}

+				LOGI("Execute the command:%s\n", command);

+			}

+			

+			if(modify_7day == 1) 

+			{

+				if(strstr(cp_dirs[i].name, "tar.gz") != NULL)

+				{

+					LOGI("Tar file:%s already exists, No more compression at once\n", cp_dirs[i].name);

+					i++;

+					continue;

+				}

+

+				tar_log_file(cp_dirs[i].name, cp_dirs[i].mtime);

+

+				//snprintf(command, sizeof(command), "rm -rf %s", cp_dirs[i].name);

+				command[0] = '\0';

+				strncat(command, "rm -rf ", sizeof(command) - 1);

+				strncat(command, cp_dirs[i].name, sizeof(command) - strlen(command) - 1);

+				

+				LOGI("del folder command:%s\n", command);

+				ret = system(command);

+				if (ret != 0) 

+				{

+					LOGE("command execution failed.\n", command);

+					return -1;

+				}

+			}

+			i++;

+			total_size = get_cp_log_folder(CP_LOG_PATH, cp_dirs, &cp_dirs_count);

+			sleep(2);

+

+		}

+		

+		i = 0;

+		total_size = get_dump_log_folder(DUMP_LOG_PATH, dump_files, &dump_files_count);

+		LOGI("module %s files size:%d MB\n",DUMP_LOG_PATH, (total_size/1024)/1024);

+		while(total_size >= DUMP_LOG_MAX_SIZE)

+		{

+			LOGI("Exceed capacity limit:%d MB  now:%d MB\n", (DUMP_LOG_MAX_SIZE/1024)/1024, (total_size/1024)/1024);

+			if(i >= dump_files_count) 

+			{

+				LOGE("No more files that can be compressed\n");

+				break;

+			}

+			modify_7day = is_modified_within_7_days(dump_files[i]);

+			if(modify_7day == 0) 

+			{			

+				//del timeout file

+				//snprintf(command, sizeof(command), "rm -rf %s", dump_files[i].name);

+				command[0] = '\0'; 

+				strncat(command, "rm -rf ", sizeof(command) - 1);

+				strncat(command, cp_dirs[i].name, sizeof(command) - strlen(command) - 1);

+

+				LOGI("command:%s, total_size:%d \n", command, total_size);

+				ret = system(command);

+				if (ret != 0) 

+				{

+					LOGE("command execution failed.\n", command);

+					return -1;

+				}

+			}

+			if(modify_7day == 1) 

+			{

+				if(strstr(dump_files[i].name, "tar.gz") != NULL)

+				{

+					LOGI("Tar file:%s already exists, No more compression at once\n", dump_files[i].name);

+					i++;

+					continue;

+				}

+				tar_log_file(dump_files[i].name, dump_files[i].mtime);

+				

+				//del source file

+				//snprintf(command, sizeof(command), "rm -rf %s", dump_files[i].name);

+				command[0] = '\0';

+				strncat(command, "rm -rf ", sizeof(command) - 1);

+				strncat(command, dump_files[i].name, sizeof(command) - strlen(command) - 1);

+				

+				LOGI("del folder command:%s\n", command);

+				ret = system(command);

+				if (ret != 0) 

+				{

+					LOGE("command execution failed.\n", command);

+					return -1;

+				}

+			}

+			i++;

+			total_size = get_dump_log_folder(DUMP_LOG_PATH, dump_files, &dump_files_count);

+			sleep(2);

+		}

+

+		sleep(60);

+	

+#if 0

+		for(i = 0; i < cp_dirs_count && cp_dirs_count < MAX_FILES; i++) {

+			struct tm *tm_info = localtime(&cp_dirs[i].mtime);

+			strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S", tm_info);

+			printf("folder:%s, files:%ld, time:%s\n", cp_dirs[i].name, cp_dirs[i].size, timebuf);

+		}

+		

+	

+		

+		for(i = 0; i < dump_files_count && dump_files_count < MAX_FILES; i++) {

+			struct tm *tm_info = localtime(&dump_files[i].mtime);

+			strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S", tm_info);

+			printf("folder:%s, files:%ld, time:%s\n", dump_files[i].name, dump_files[i].size, timebuf);

+		}

+#endif

+		

+	}

+	

+	return 0;

+}

+

+

+

+