/*************************************************************************************** * * IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. * * By downloading, copying, installing or using the software you agree to this license. * If you do not agree to this license, do not download, install, * copy or use the software. * * Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved. * * Redistribution and use in binary forms, with or without modification, are permitted. * * Unless required by applicable law or agreed to in writing, software distributed * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific * language governing permissions and limitations under the License. * ****************************************************************************************/ #include "sys_inc.h" #include "sys_log.h" /***************************************************************************************/ HT_LOG_CTX g_log_ctx = { NULL, NULL, HT_LOG_ERR, // default log level 0, 1024, // Maximum file size in KB 0, 3, // Maximum file indexes 1, // Loop write log flag 0 }; static const char * g_log_level_str[] = { "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL" }; /***************************************************************************************/ void log_get_name(const char * log_fname, char * name, int size) { const char * p; p = strrchr(log_fname, '.'); if (p) { char fname[256] = {'\0'}; int len = p - log_fname; len = (len <= size ? len : size); strncpy(fname, log_fname, len); p++; if (*p == '\0') { p = "log"; } snprintf(name, size, "%s-%d.%s", fname, g_log_ctx.cur_idx+1, p); } else { snprintf(name, size, "%s-%d.log", log_fname, g_log_ctx.cur_idx+1); } if (++g_log_ctx.cur_idx >= g_log_ctx.max_idx) { g_log_ctx.cur_idx = 0; } } HT_API int log_init(const char * log_fname) { char name[256] = {'\0'}; log_close(); if (g_log_ctx.rewind) { log_get_name(log_fname, name, sizeof(name)-1); } else { strncpy(name, log_fname, sizeof(name)-1); } g_log_ctx.fp = fopen(name, "w+"); if (g_log_ctx.fp == NULL) { printf("log init fopen[%s] failed[%s]\r\n", name, strerror(errno)); return -1; } g_log_ctx.cur_size = 0; g_log_ctx.mutex = sys_os_create_mutex(); if (g_log_ctx.mutex == NULL) { printf("log init mutex failed[%s]\r\n", strerror(errno)); return -1; } if (!g_log_ctx.time_init) { strncpy(g_log_ctx.name, log_fname, sizeof(g_log_ctx.name)-1); } return 0; } HT_API int log_time_init(const char * fname_prev) { char fpath[256]; time_t time_now = time(NULL); struct tm * st = localtime(&(time_now)); snprintf(fpath, sizeof(fpath), "%s-%04d%02d%02d_%02d%02d%02d.log", fname_prev, st->tm_year+1900, st->tm_mon+1, st->tm_mday, st->tm_hour, st->tm_min, st->tm_sec); g_log_ctx.rewind = 0; g_log_ctx.time_init = 1; strncpy(g_log_ctx.name, fname_prev, sizeof(g_log_ctx.name)-1); return log_init(fpath); } HT_API int log_reinit(const char * log_fname) { int ret = 0; char name[256] = {'\0'}; sys_os_mutex_enter(g_log_ctx.mutex); if (g_log_ctx.fp) { fclose(g_log_ctx.fp); g_log_ctx.fp = NULL; } if (g_log_ctx.rewind) { log_get_name(log_fname, name, sizeof(name)-1); } else { strncpy(name, log_fname, sizeof(name)-1); } g_log_ctx.fp = fopen(name, "w+"); if (g_log_ctx.fp == NULL) { printf("log init fopen[%s] failed[%s]\r\n", name, strerror(errno)); ret = -1; } g_log_ctx.cur_size = 0; if (!g_log_ctx.time_init) { strncpy(g_log_ctx.name, log_fname, sizeof(g_log_ctx.name)-1); } sys_os_mutex_leave(g_log_ctx.mutex); return ret; } HT_API int log_time_reinit(const char * fname_prev) { char fpath[256]; time_t time_now = time(NULL); struct tm * st = localtime(&(time_now)); snprintf(fpath, sizeof(fpath), "%s-%04d%02d%02d_%02d%02d%02d.log", fname_prev, st->tm_year+1900, st->tm_mon+1, st->tm_mday, st->tm_hour, st->tm_min, st->tm_sec); g_log_ctx.rewind = 0; g_log_ctx.time_init = 1; strncpy(g_log_ctx.name, fname_prev, sizeof(g_log_ctx.name)-1); return log_reinit(fpath); } HT_API void log_close() { sys_os_mutex_enter(g_log_ctx.mutex); if (g_log_ctx.fp) { fclose(g_log_ctx.fp); g_log_ctx.fp = NULL; } sys_os_mutex_leave(g_log_ctx.mutex); if (g_log_ctx.mutex) { sys_os_destroy_sig_mutex(g_log_ctx.mutex); g_log_ctx.mutex = NULL; } } void log_switch() { if (g_log_ctx.cur_size >= g_log_ctx.max_size * 1024) { if (g_log_ctx.time_init) { log_time_reinit(g_log_ctx.name); } else { log_reinit(g_log_ctx.name); } } } int log_print_ex(int level, const char *fmt, va_list argptr) { int slen = 0; time_t time_now; struct tm * st; if (g_log_ctx.fp == NULL || g_log_ctx.mutex == NULL) { return 0; } time_now = time(NULL); st = localtime(&(time_now)); sys_os_mutex_enter(g_log_ctx.mutex); if (g_log_ctx.fp) { slen = fprintf(g_log_ctx.fp, "[%04d-%02d-%02d %02d:%02d:%02d] : [%s] ", st->tm_year+1900, st->tm_mon+1, st->tm_mday, st->tm_hour, st->tm_min, st->tm_sec, g_log_level_str[level]); if (slen > 0) { g_log_ctx.cur_size += slen; } slen = vfprintf(g_log_ctx.fp, fmt, argptr); fflush(g_log_ctx.fp); if (slen > 0) { g_log_ctx.cur_size += slen; } } sys_os_mutex_leave(g_log_ctx.mutex); log_switch(); return slen; } #ifndef IOS HT_API int log_print(int level, const char * fmt,...) { if (level < g_log_ctx.level || level > HT_LOG_FATAL) { return 0; } else { int slen; va_list argptr; va_start(argptr, fmt); slen = log_print_ex(level, fmt, argptr); va_end(argptr); return slen; } } #else HT_API int log_ios_print(int level, const char * fmt,...) { if (level < g_log_ctx.level || level > HT_LOG_FATAL) { return 0; } else { int slen; va_list argptr; va_start(argptr, fmt); slen = log_print_ex(level, fmt, argptr); va_end(argptr); return slen; } return 0; } #endif static int log_lock_print_ex(const char *fmt, va_list argptr) { int slen; if (g_log_ctx.fp == NULL || g_log_ctx.mutex == NULL) { return 0; } slen = vfprintf(g_log_ctx.fp, fmt, argptr); fflush(g_log_ctx.fp); if (slen > 0) { g_log_ctx.cur_size += slen; } return slen; } HT_API int log_lock_start(const char * fmt,...) { int slen = 0; va_list argptr; if (g_log_ctx.fp == NULL || g_log_ctx.mutex == NULL) { return 0; } va_start(argptr,fmt); sys_os_mutex_enter(g_log_ctx.mutex); slen = log_lock_print_ex(fmt,argptr); va_end(argptr); return slen; } HT_API int log_lock_print(const char * fmt,...) { int slen; va_list argptr; va_start(argptr,fmt); slen = log_lock_print_ex(fmt, argptr); va_end(argptr); return slen; } HT_API int log_lock_end(const char * fmt,...) { int slen; va_list argptr; va_start(argptr,fmt); slen = log_lock_print_ex(fmt, argptr); va_end(argptr); sys_os_mutex_leave(g_log_ctx.mutex); log_switch(); return slen; } HT_API void log_set_level(int level) { g_log_ctx.level = level; } HT_API int log_get_level() { return g_log_ctx.level; } HT_API void log_set_rewind(int rewind) { g_log_ctx.rewind = rewind; } HT_API int log_get_rewind() { return g_log_ctx.rewind; } HT_API void log_set_max_size(int max_size) { g_log_ctx.max_size = max_size; } HT_API int log_get_max_size() { return g_log_ctx.max_size; } HT_API void log_set_max_idx(int max_idx) { g_log_ctx.max_idx = max_idx; } HT_API int log_get_max_idx() { return g_log_ctx.max_idx; }