blob: 510b815772af21b0980fbe55893a2de0284cf418 [file] [log] [blame]
#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;
}