[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/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(®ex, "^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(®ex, 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(®ex);
+ 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;
+}
+
+
+
+