static inline void am_level_logv(const char *module, AmLogLevel level, const char *format, va_list vlist) { char text[2*1024] = {0}; char str[4*1024] = {0}; int len = vsnprintf(text, sizeof(text), format, vlist); if (AM_LIKELY((uint32_t)len < sizeof(text))) { text[len] = '\0'; } else { text[sizeof(text) - 1] = '\0'; } logTimeStamp ? snprintf(str, sizeof(str) - 1, "[%s]%s\n", get_timestamp(), text) : snprintf(str, sizeof(str) - 1, "%s\n", text); AM_LOCK(); switch(logTarget) { case AM_LOG_TARGET_STDERR: { fprintf(stderr, "%s", str); }break; case AM_LOG_TARGET_SYSLOG: { openlog(empty_module_name(module), LOG_PID, LOG_USER); syslog(level_to_syslog[level], "%s\n", text); }break; case AM_LOG_TARGET_FILE: { if ((write(logfile.fd(), str, strlen(str)) < 0)) { fprintf(stderr, "%s: %s: %d\n", B_RED("Failed writing logs to file. Redirect log to console"), strerror(errno), logfile.fd()); logfile.set_log_fd(-1); logTarget = AM_LOG_TARGET_STDERR; fprintf(stderr, "%s", str); } }break; case AM_LOG_TARGET_NULL: default: break; } AM_UNLOCK(); }
/* *time: level: process[pid]: [tid] tag: message * [verbose ] */ static int _log_print(int lvl, const char *tag, const char *file, int line, const char *func, const char *msg) { int ret = 0, i = 0; struct iovec vec[LOG_IOVEC_MAX]; char s_time[LOG_TIME_SIZE]; char s_lvl[LOG_LEVEL_SIZE]; char s_tag[LOG_TAG_SIZE]; char s_pname[LOG_PNAME_SIZE]; char s_pid[LOG_PNAME_SIZE]; char s_tid[LOG_PNAME_SIZE]; char s_file[LOG_TEXT_SIZE]; char s_msg[LOG_BUF_SIZE]; pthread_mutex_lock(&_log_mutex); log_get_time(s_time, sizeof(s_time), 0); if (_log_fp == stderr || _log_fd == STDERR_FILENO) { switch(lvl) { case LOG_EMERG: case LOG_ALERT: case LOG_CRIT: case LOG_ERR: snprintf(s_lvl, sizeof(s_lvl), B_RED("[%7s]"), _log_level_str[lvl]); snprintf(s_msg, sizeof(s_msg), RED("%s"), msg); break; case LOG_WARNING: snprintf(s_lvl, sizeof(s_lvl), B_YELLOW("[%7s]"), _log_level_str[lvl]); snprintf(s_msg, sizeof(s_msg), YELLOW("%s"), msg); break; case LOG_INFO: snprintf(s_lvl, sizeof(s_lvl), B_GREEN("[%7s]"), _log_level_str[lvl]); snprintf(s_msg, sizeof(s_msg), GREEN("%s"), msg); break; case LOG_DEBUG: snprintf(s_lvl, sizeof(s_lvl), B_WHITE("[%7s]"), _log_level_str[lvl]); snprintf(s_msg, sizeof(s_msg), WHITE("%s"), msg); break; default: snprintf(s_lvl, sizeof(s_lvl), "[%7s]", _log_level_str[lvl]); snprintf(s_msg, sizeof(s_msg), "%s", msg); break; } } else { snprintf(s_lvl, sizeof(s_lvl), "[%7s]", _log_level_str[lvl]); snprintf(s_msg, sizeof(s_msg), "%s", msg); } if (CHECK_LOG_PREFIX(_log_prefix, LOG_PIDTID_BIT)) { snprintf(s_pname, sizeof(s_pname), "[%s ", _proc_name); snprintf(s_pid, sizeof(s_pid), "pid:%d ", getpid()); snprintf(s_tid, sizeof(s_tid), "tid:%d]", _gettid()); snprintf(s_tag, sizeof(s_tag), "[%s]", tag); snprintf(s_file, sizeof(s_file), "[%s:%d: %s] ", file, line, func); } if (CHECK_LOG_PREFIX(_log_prefix, LOG_FUNCLINE_BIT)) { snprintf(s_file, sizeof(s_file), "[%s:%d: %s] ", file, line, func); } i = -1; if (CHECK_LOG_PREFIX(_log_prefix, LOG_TIMESTAMP_BIT)) { vec[++i].iov_base = (void *)s_time; vec[i].iov_len = strlen(s_time); } if (CHECK_LOG_PREFIX(_log_prefix, LOG_PIDTID_BIT)) { vec[++i].iov_base = (void *)s_pname; vec[i].iov_len = strlen(s_pname); vec[++i].iov_base = (void *)s_pid; vec[i].iov_len = strlen(s_pid); vec[++i].iov_base = (void *)s_tid; vec[i].iov_len = strlen(s_tid); } vec[++i].iov_base = (void *)s_lvl; vec[i].iov_len = strlen(s_lvl); if (CHECK_LOG_PREFIX(_log_prefix, LOG_TAG_BIT)) { vec[++i].iov_base = (void *)s_tag; vec[i].iov_len = strlen(s_tag); } if (CHECK_LOG_PREFIX(_log_prefix, LOG_FUNCLINE_BIT)) { vec[++i].iov_base = (void *)s_file; vec[i].iov_len = strlen(s_file); } vec[++i].iov_base = (void *)s_msg; vec[i].iov_len = strlen(s_msg); if (UNLIKELY(!_log_syslog)) { ret = _log_handle->write(vec, i+1); } pthread_mutex_unlock(&_log_mutex); return ret; }