/* * Filename: log.c * Description: local log file °ü·Ã * * Author: ºñ¿± aka. Cronan */ #define __LIBTHECORE__ #include "stdafx.h" #ifndef __WIN32__ #define SYSLOG_FILENAME "syslog" #define SYSERR_FILENAME "syserr" #define PTS_FILENAME "PTS" #else #define SYSLOG_FILENAME "syslog.txt" #define SYSERR_FILENAME "syserr.txt" #define PTS_FILENAME "PTS.txt" #endif typedef struct log_file_s * LPLOGFILE; typedef struct log_file_s LOGFILE; struct log_file_s { char* filename; FILE* fp; int last_hour; int last_day; }; LPLOGFILE log_file_sys = NULL; LPLOGFILE log_file_err = NULL; LPLOGFILE log_file_pt = NULL; static char log_dir[32] = { 0, }; unsigned int log_keep_days = 3; // Internal functions LPLOGFILE log_file_init(const char* filename, const char *openmode); void log_file_destroy(LPLOGFILE logfile); void log_file_rotate(LPLOGFILE logfile); void log_file_check(LPLOGFILE logfile); void log_file_set_dir(const char *dir); static unsigned int log_level_bits = 7; void log_set_level(unsigned int bit) { log_level_bits |= bit; } void log_unset_level(unsigned int bit) { log_level_bits &= ~bit; } void log_set_expiration_days(unsigned int days) { log_keep_days = days; } int log_get_expiration_days(void) { return log_keep_days; } int log_init(void) { log_file_set_dir("./log"); do { log_file_sys = log_file_init(SYSLOG_FILENAME, "a+"); if( NULL == log_file_sys ) break; log_file_err = log_file_init(SYSERR_FILENAME, "a+"); if( NULL == log_file_err ) break; log_file_pt = log_file_init(PTS_FILENAME, "w"); if( NULL == log_file_pt ) break; return true; } while( false ); return false; } void log_destroy(void) { log_file_destroy(log_file_sys); log_file_destroy(log_file_err); log_file_destroy(log_file_pt); log_file_sys = NULL; log_file_err = NULL; log_file_pt = NULL; } void log_rotate(void) { log_file_check(log_file_sys); log_file_check(log_file_err); log_file_check(log_file_pt); log_file_rotate(log_file_sys); } #ifndef __WIN32__ void _sys_err(const char *func, int line, const char *format, ...) { va_list args; time_t ct = time(0); char *time_s = asctime(localtime(&ct)); struct timeval tv; int nMiliSec = 0; gettimeofday(&tv, NULL); char buf[1024 + 2]; // \nÀ» ºÙÀ̱â À§ÇØ.. int len; if (!log_file_err) return; time_s[strlen(time_s) - 1] = '\0'; len = snprintf(buf, 1024, "SYSERR: %-15.15s.%ld :: %s: ", time_s + 4, tv.tv_usec, func); buf[1025] = '\0'; if (len < 1024) { va_start(args, format); vsnprintf(buf + len, 1024 - len, format, args); va_end(args); } strcat(buf, "\n"); // log_file_err ¿¡ Ãâ·Â fputs(buf, log_file_err->fp); fflush(log_file_err->fp); // log_file_sys ¿¡µµ Ãâ·Â fputs(buf, log_file_sys->fp); fflush(log_file_sys->fp); } #else void _sys_err(const char *func, int line, const char *format, ...) { va_list args; time_t ct = time(0); char *time_s = asctime(localtime(&ct)); char buf[1024 + 2]; // \nÀ» ºÙÀ̱â À§ÇØ.. int len; if (!log_file_err) return; time_s[strlen(time_s) - 1] = '\0'; len = snprintf(buf, 1024, "SYSERR: %-15.15s :: %s: ", time_s + 4, func); buf[1025] = '\0'; if (len < 1024) { va_start(args, format); vsnprintf(buf + len, 1024 - len, format, args); va_end(args); } strcat(buf, "\n"); // log_file_err ¿¡ Ãâ·Â fputs(buf, log_file_err->fp); fflush(log_file_err->fp); // log_file_sys ¿¡µµ Ãâ·Â fputs(buf, log_file_sys->fp); fflush(log_file_sys->fp); fputs(buf, stdout); fflush(stdout); } #endif static char sys_log_header_string[33] = ""; void sys_log_header(const char *header) { strncpy(sys_log_header_string, header, 32); } void sys_log(unsigned int bit, const char *format, ...) { va_list args; struct timeval tv; int nMiliSec = 0; gettimeofday(&tv, NULL); if (bit != 0 && !(log_level_bits & bit)) return; if (log_file_sys) { time_t ct = time(0); char *time_s = asctime(localtime(&ct)); fprintf(log_file_sys->fp, sys_log_header_string); time_s[strlen(time_s) - 1] = '\0'; fprintf(log_file_sys->fp, "%-15.15s.%ld :: ", time_s + 4, tv.tv_usec ); va_start(args, format); vfprintf(log_file_sys->fp, format, args); va_end(args); fputc('\n', log_file_sys->fp); fflush(log_file_sys->fp); } #ifndef __WIN32__ // log_levelÀÌ 1 ÀÌ»óÀÏ °æ¿ì¿¡´Â Å×½ºÆ®ÀÏ °æ¿ì°¡ ¸¹À¸´Ï stdout¿¡µµ Ãâ·ÂÇÑ´Ù. if (log_level_bits > 1) { #endif fprintf(stdout, sys_log_header_string); va_start(args, format); vfprintf(stdout, format, args); va_end(args); fputc('\n', stdout); fflush(stdout); #ifndef __WIN32__ } #endif } void pt_log(const char *format, ...) { va_list args; if (!log_file_pt) return; va_start(args, format); vfprintf(log_file_pt->fp, format, args); va_end(args); fputc('\n', log_file_pt->fp); fflush(log_file_pt->fp); } LPLOGFILE log_file_init(const char * filename, const char * openmode) { LPLOGFILE logfile; FILE * fp; struct tm curr_tm; time_t time_s; time_s = time(0); curr_tm = *localtime(&time_s); fp = fopen(filename, openmode); if (!fp) return NULL; logfile = (LPLOGFILE) malloc(sizeof(LOGFILE)); logfile->filename = strdup(filename); logfile->fp = fp; logfile->last_hour = curr_tm.tm_hour; logfile->last_day = curr_tm.tm_mday; return (logfile); } void log_file_destroy(LPLOGFILE logfile) { if (logfile == NULL) { return; } if (logfile->filename) { free(logfile->filename); logfile->filename = NULL; } if (logfile->fp) { fclose(logfile->fp); logfile->fp = NULL; } free(logfile); } void log_file_check(LPLOGFILE logfile) { struct stat sb; // ÆÄÀÏÀÌ ¾øÀ¸¹Ç·Î ´Ù½Ã ¿¬´Ù. if (stat(logfile->filename, &sb) != 0 && errno == ENOENT) { fclose(logfile->fp); logfile->fp = fopen(logfile->filename, "a+"); } } void log_file_delete_old(const char *filename) { struct stat sb; int num1, num2; char buf[32]; char system_cmd[512]; struct tm new_tm; if (stat(filename, &sb) == -1) { perror("log_file_delete_old: stat"); return; } if (!S_ISDIR(sb.st_mode)) return; new_tm = *tm_calc(NULL, -log_keep_days); sprintf(buf, "%04d%02d%02d", new_tm.tm_year + 1900, new_tm.tm_mon + 1, new_tm.tm_mday); num1 = atoi(buf); #ifndef __WIN32__ { struct dirent ** namelist; int n; n = scandir(filename, &namelist, 0, alphasort); if (n < 0) perror("scandir"); else { char name[MAXNAMLEN+1]; while (n-- > 0) { strncpy(name, namelist[n]->d_name, 255); name[255] = '\0'; free(namelist[n]); if (*name == '.') continue; if (!isdigit(*name)) continue; num2 = atoi(name); if (num2 <= num1) { snprintf(system_cmd, sizeof(system_cmd), "rm -rf %s/%s", filename, name); system(system_cmd); sys_log(0, "%s: SYSTEM_CMD: %s", __FUNCTION__, system_cmd); fprintf(stderr, "%s: SYSTEM_CMD: %s %s:%d %s:%d\n", __FUNCTION__, system_cmd, buf, num1, name, num2); } } } free(namelist); } #else { WIN32_FIND_DATA fdata; HANDLE hFind; if ((hFind = FindFirstFile(filename, &fdata)) != INVALID_HANDLE_VALUE) { do { if (!isdigit(*fdata.cFileName)) continue; num2 = atoi(fdata.cFileName); if (num2 <= num1) { sprintf(system_cmd, "del %s\\%s", filename, fdata.cFileName); system(system_cmd); sys_log(0, "SYSTEM_CMD: %s", system_cmd); } } while (FindNextFile(hFind, &fdata)); } } #endif } void log_file_rotate(LPLOGFILE logfile) { struct tm curr_tm; time_t time_s; char dir[256]; char system_cmd[512]; time_s = time(0); curr_tm = *localtime(&time_s); if (curr_tm.tm_mday != logfile->last_day) { struct tm new_tm; new_tm = *tm_calc(&curr_tm, -3); #ifndef __WIN32__ sprintf(system_cmd, "rm -rf %s/%04d%02d%02d", log_dir, new_tm.tm_year + 1900, new_tm.tm_mon + 1, new_tm.tm_mday); #else sprintf(system_cmd, "del %s\\%04d%02d%02d", log_dir, new_tm.tm_year + 1900, new_tm.tm_mon + 1, new_tm.tm_mday); #endif system(system_cmd); sys_log(0, "SYSTEM_CMD: %s", system_cmd); logfile->last_day = curr_tm.tm_mday; } if (curr_tm.tm_hour != logfile->last_hour) { struct stat stat_buf; snprintf(dir, sizeof(dir), "%s/%04d%02d%02d", log_dir, curr_tm.tm_year + 1900, curr_tm.tm_mon + 1, curr_tm.tm_mday); if (stat(dir, &stat_buf) != 0 || S_ISDIR(stat_buf.st_mode)) { #ifdef __WIN32__ CreateDirectory(dir, NULL); #else mkdir(dir, S_IRWXU); #endif } sys_log(0, "SYSTEM: LOG ROTATE (%04d-%02d-%02d %d)", curr_tm.tm_year + 1900, curr_tm.tm_mon + 1, curr_tm.tm_mday, logfile->last_hour); // ·Î±× ÆÄÀÏÀ» ´Ý°í fclose(logfile->fp); // ¿Å±ä´Ù. #ifndef __WIN32__ snprintf(system_cmd, sizeof(system_cmd), "mv %s %s/%s.%02d", logfile->filename, dir, logfile->filename, logfile->last_hour); #else snprintf(system_cmd, sizeof(system_cmd), "move %s %s\\%s.%02d", logfile->filename, dir, logfile->filename, logfile->last_hour); #endif system(system_cmd); // ¸¶Áö¸· ÀúÀå½Ã°£ ÀúÀå logfile->last_hour = curr_tm.tm_hour; // ·Î±× ÆÄÀÏÀ» ´Ù½Ã ¿¬´Ù. logfile->fp = fopen(logfile->filename, "a+"); } } void log_file_set_dir(const char *dir) { strcpy(log_dir, dir); log_file_delete_old(log_dir); }