#include "precompile.h" #include "log_single.h" #include "log_base.h" #include "log.h" #include "spinlock.h" #include "fileutil.h" #include "strutil.h" #include typedef struct singlelogfactory_t singlelogfactory_t; typedef struct singlelog_t { logbase_t base; char *file_path; FILE *fp; LONG use_lock; lock_t lock; LONG flush; int first_record; }singlelog_t; struct singlelogfactory_t { logfactory_t base; }; static void singlefilefactory_destroy(void *self) { singlelogfactory_t *fac = (singlelogfactory_t *)self; if (fac) { if (fac->base.name) free(fac->base.name); free(fac); } } static void* singlefilefactory_create_log(void *self, const char* inst) { singlelog_t *log = MALLOC_T(singlelog_t); log->base.level = XLOG_LEVEL_ALL; log->base.factory = self; log->base.inst_name = _strdup(inst); log->file_path = 0; log->fp = NULL; log->use_lock = 0; log->flush = 1; log->first_record = 0; fastlock_init(log->lock); return log; } static int singlefilefactory_set_log_param(void *self, void *log, const char *key, const char *value) { singlelog_t *slog = (singlelog_t*)log; if (_stricmp(key, "file") == 0) { char *p; if (strchr(value, ':') == NULL) { char tmp[MAX_PATH]; GetModuleFileNameA(NULL, tmp, MAX_PATH); p = strrchr(tmp, '\\'); *(p+1) = 0; slog->file_path = strdup_printf("%s%s", tmp, value); } else { slog->file_path = _strdup(value); } p = strrchr(slog->file_path, '\\'); if (p) { *p = 0; CreateDirRecursiveA(slog->file_path); *p = '\\'; } } else if (_stricmp(key, "use_lock") == 0) { if (_stricmp(value, "true") == 0 || _stricmp(value, "1") == 0) { slog->use_lock = 1; } } else if (_stricmp(key, "flush") == 0) { if (_stricmp(value, "true") == 0 || _stricmp(value, "1") == 0) { slog->flush = 1; } } else if (_stricmp(key, "level") == 0) { if (_stricmp(value, "all") == 0) { slog->base.level = 0; } else if (_stricmp(value, "trace") == 0) { slog->base.level = 1; } else if (_stricmp(value, "debug") == 0) { slog->base.level = 2; } else if (_stricmp(value, "info") == 0) { slog->base.level = 3; } else if (_stricmp(value, "warn") == 0) { slog->base.level = 4; } else if (_stricmp(value, "error") == 0) { slog->base.level = 5; } else if (_stricmp(value, "fatal") == 0) { slog->base.level = 6; } else if (_stricmp(value, "none") == 0) { slog->base.level = 7; } else { return -1; } } else { return -1; } return 0; } static int singlefilefactory_init_log(void *self, void *log) { singlelog_t *slog = (singlelog_t*)log; slog->fp = fopen(slog->file_path, "ab"); if (slog->fp) { slog->first_record = !!ftell(slog->fp); } return slog->fp ? 0 : -1; } static int singlefilefactory_term_log(void *self, void *log) { singlelog_t *slog = (singlelog_t*)log; if (slog->fp) { fclose(slog->fp); slog->fp = NULL; } slog->use_lock = 0; if (slog->file_path) { free(slog->file_path); slog->file_path = NULL; } return 0; } static void singlefilefactory_destroy_log(void *self, void *log) { singlelog_t *slog = (singlelog_t*)log; if (slog) { if (slog->base.inst_name) free(slog->base.inst_name); free(slog); } } static int singlefilefactory_record_log(void *self, void *log, int level, unsigned long ts_low, unsigned long ts_high, const char *s, int sn) { singlelog_t *slog = (singlelog_t*)log; if (slog->fp) { SYSTEMTIME st; FILETIME utc_ft, local_ft; char tmp[64]; int n; if (slog->use_lock) { fastlock_enter(slog->lock); } #ifdef _WIN32 utc_ft.dwLowDateTime = (DWORD)ts_low; utc_ft.dwHighDateTime = (DWORD)ts_high; FileTimeToLocalFileTime(&utc_ft, &local_ft); FileTimeToSystemTime(&local_ft, &st); #else GetLocalTime(&st); #endif // _WIN32 if (slog->first_record) { n = sprintf(tmp, "[%02d:%02d:%02d.%03d][%s] ", st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, log_level2str(level)); slog->first_record = 0; } else { n = sprintf(tmp, "\r\n[%02d:%02d:%02d.%03d][%s] ", st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, log_level2str(level)); } _fwrite_nolock(tmp, n, 1, slog->fp); _fwrite_nolock(s, sn, 1, slog->fp); if (slog->flush) _fflush_nolock(slog->fp); } if (slog->use_lock) { fastlock_leave(slog->lock); } return 0; } int singlefilefactory_create(logfactory_t **p_fac) { singlelogfactory_t *fac; if (!p_fac) return -1; fac = MALLOC_T(singlelogfactory_t); if (!fac) { return -1; } fac->base.name = _strdup("single"); fac->base.record_log = &singlefilefactory_record_log; fac->base.init_log = &singlefilefactory_init_log; fac->base.set_log_param = &singlefilefactory_set_log_param; fac->base.term_log = &singlefilefactory_term_log; fac->base.create_log = &singlefilefactory_create_log; fac->base.destroy_log = &singlefilefactory_destroy_log; fac->base.destroy = &singlefilefactory_destroy; *p_fac = &fac->base; return 0; }