change the logging function to support priority masking

This commit is contained in:
2017-09-18 02:46:54 +00:00
parent cdc64c347f
commit c5ac9558ab
3 changed files with 278 additions and 141 deletions

View File

@ -41,18 +41,6 @@
#include "../cmn/syscall.h"
#endif
static const qse_char_t* __priority_names[] =
{
QSE_T("panic"),
QSE_T("alert"),
QSE_T("critical"),
QSE_T("error"),
QSE_T("warning"),
QSE_T("notice"),
QSE_T("info"),
QSE_T("debug")
};
static const qse_mchar_t* __syslog_month_names[] =
{
QSE_MT("Jan"),
@ -94,16 +82,48 @@ static const qse_mchar_t* __syslog_month_names[] =
# define LOG_DEBUG 7
#endif
static int __syslog_priority[] =
/* use a simple look-up table for mapping a priority to a syslog value.
* i assume it's faster than getting the position of the first lowest bit set
* and use a smaller and dense table without gap-filling 0s. */
static int __syslog_priority[256] =
{
LOG_EMERG,
LOG_ALERT,
LOG_CRIT,
LOG_ERR,
LOG_WARNING,
LOG_NOTICE,
LOG_INFO,
LOG_DEBUG
0,
LOG_EMERG, /* 1 */
LOG_ALERT, /* 2 */
0,
LOG_CRIT, /* 4 */
0, 0, 0,
LOG_ERR, /* 8 */
0, 0, 0, 0, 0, 0, 0,
LOG_WARNING, /* 16 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
LOG_NOTICE, /* 32 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0,
LOG_INFO, /* 64 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0,
LOG_DEBUG, /* 128 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0
};
#if defined(_WIN32)
@ -137,12 +157,45 @@ static struct syslog_fac_info_t __syslog_fac_info[] =
{ QSE_T("local4"), QSE_LOG_LOCAL4 },
{ QSE_T("local5"), QSE_LOG_LOCAL5 },
{ QSE_T("local6"), QSE_LOG_LOCAL6 },
{ QSE_T("local7"), QSE_LOG_LOCAL7 },
{ QSE_NULL, 0 }
{ QSE_T("local7"), QSE_LOG_LOCAL7 }
};
#endif
static QSE_INLINE int get_active_priority_bits (int flags)
{
int priority_bits = 0;
if (flags & QSE_LOG_MASKED_PRIORITY)
{
priority_bits = flags & QSE_LOG_MASK_PRIORITY;
}
else
{
int pri = flags & QSE_LOG_MASK_PRIORITY;
switch (pri)
{
case QSE_LOG_DEBUG:
priority_bits |= QSE_LOG_DEBUG;
case QSE_LOG_INFO:
priority_bits |= QSE_LOG_INFO;
case QSE_LOG_NOTICE:
priority_bits |= QSE_LOG_NOTICE;
case QSE_LOG_WARNING:
priority_bits |= QSE_LOG_WARNING;
case QSE_LOG_ERROR:
priority_bits |= QSE_LOG_ERROR;
case QSE_LOG_CRITICAL:
priority_bits |= QSE_LOG_CRITICAL;
case QSE_LOG_ALERT:
priority_bits |= QSE_LOG_ALERT;
case QSE_LOG_PANIC:
priority_bits |= QSE_LOG_PANIC;
}
}
return priority_bits;
}
int qse_log_init (qse_log_t* log, qse_mmgr_t* mmgr, const qse_char_t* ident, int potflags, const qse_log_target_t* target)
{
QSE_MEMSET (log, 0, QSE_SIZEOF(*log));
@ -169,12 +222,15 @@ int qse_log_init (qse_log_t* log, qse_mmgr_t* mmgr, const qse_char_t* ident, int
if (ident) qse_strxcpy (log->ident, QSE_COUNTOF(log->ident), ident);
if (qse_mtx_init(&log->mtx, mmgr) <= -1) return -1;
log->active_priority_bits = get_active_priority_bits(log->flags);
#if defined(_WIN32)
/* TODO: windows event logging */
#else
log->syslog_facility = QSE_LOG_USER;
#endif
return 0;
}
@ -328,64 +384,16 @@ void qse_log_setoption (qse_log_t* log, int option)
void qse_log_setpriority (qse_log_t* log, int priority)
{
log->flags = (log->flags & (QSE_LOG_MASK_TARGET | QSE_LOG_MASK_OPTION)) | (priority & QSE_LOG_MASK_PRIORITY);
log->active_priority_bits = get_active_priority_bits (log->flags);
}
int qse_log_setprioritybyname (qse_log_t* log, const qse_char_t* name)
{
qse_size_t i;
for (i = 0; i < QSE_COUNTOF(__priority_names); i++)
{
if (qse_strcmp(__priority_names[i], name) == 0)
{
qse_log_setpriority (log, i);
return 0;
}
}
return -1;
}
const qse_char_t* qse_log_getpriorityname (qse_log_t* log)
{
int pri = log->flags & QSE_LOG_MASK_PRIORITY;
if (pri < 0 || pri >= QSE_COUNTOF(__priority_names)) return QSE_NULL;
return __priority_names[pri];
}
void qse_log_setsyslogfacility (qse_log_t* log, qse_log_facility_t facility)
{
#ifndef _WIN32
#if !defined(_WIN32)
log->syslog_facility = facility;
#endif
}
int qse_log_setsyslogfacilitybyname (qse_log_t* log, const qse_char_t* name)
{
#if defined(_WIN32)
/* do nothing */
return 0;
#else
struct syslog_fac_info_t* f = __syslog_fac_info;
while (f->name != QSE_NULL)
{
if (qse_strcmp (f->name, name) == 0)
{
log->syslog_facility = f->code;
return 0;
}
f++;
}
return -1;
#endif
}
static QSE_INLINE void __report_over_sio (qse_log_t* log, qse_sio_t* sio, const qse_mchar_t* tm, const qse_char_t* ident, const qse_char_t* fmt, va_list arg)
{
int id_out = 0;
@ -442,7 +450,7 @@ void qse_log_reportv (qse_log_t* log, const qse_char_t* ident, int pri, const qs
if ((log->flags & QSE_LOG_MASK_TARGET) == 0) return; /* no target */
if (log->flags & QSE_LOG_ENABLE_MASKED)
if (log->flags & QSE_LOG_MASKED_PRIORITY)
{
if (!(pri & (log->flags & QSE_LOG_MASK_PRIORITY))) return;
}
@ -522,6 +530,7 @@ void qse_log_reportv (qse_log_t* log, const qse_char_t* ident, int pri, const qs
if (!log->wmsgbuf) goto done;
#endif
/* the priority value given must have only 1 bit set. otherwise, it will translate to wrong values */
sl_pri = (pri < QSE_COUNTOF(__syslog_priority))? __syslog_priority[(pri & QSE_LOG_MASK_PRIORITY)]: LOG_DEBUG;
fplen = qse_mbs_fmt(log->dmsgbuf, QSE_MT("<%d>"), (int)(log->syslog_facility | sl_pri));
@ -533,7 +542,6 @@ void qse_log_reportv (qse_log_t* log, const qse_char_t* ident, int pri, const qs
cnow.hour, cnow.min, cnow.sec);
if (fpdlen == (qse_size_t)-1) goto done;
if (log->flags & QSE_LOG_HOST_IN_REMOTE_SYSLOG)
{
struct utsname un;
@ -656,8 +664,91 @@ done:
qse_mtx_unlock (&log->mtx);
}
const qse_char_t* qse_get_log_priority_name (int pri)
/* --------------------------------------------------------------------------
* HELPER FUNCTIONS
* -------------------------------------------------------------------------- */
static const qse_char_t* __priority_names[] =
{
if (pri < 0 || pri >= QSE_COUNTOF(__priority_names)) return QSE_NULL;
return __priority_names[pri];
/* NOTE: QSE_LOG_PRIORITY_LEN_MAX must be redefined if strings here
* can produce a longer compositional name. e.g. panic|critical|... */
QSE_T("panic"),
QSE_T("alert"),
QSE_T("critical"),
QSE_T("error"),
QSE_T("warning"),
QSE_T("notice"),
QSE_T("info"),
QSE_T("debug")
};
qse_size_t qse_get_log_priority_name (int pri, qse_char_t* buf, qse_size_t len)
{
qse_size_t tlen, xlen, rem, i;
tlen = 0;
rem = len;
for (i = 0; i < QSE_COUNTOF(__priority_names); i++)
{
if (pri & (1UL << i))
{
if (rem <= 1) break;
xlen = (tlen <= 0)?
qse_strxcpy (&buf[tlen], rem, __priority_names[i]):
qse_strxjoin (&buf[tlen], rem, QSE_T("|"), __priority_names[i], QSE_NULL);
rem -= xlen;
tlen += xlen;
}
}
if (len >= tlen) buf[tlen] = QSE_T('\0');
return tlen;
}
int qse_get_log_priority_by_name (const qse_char_t* name)
{
qse_size_t i;
qse_cstr_t tok;
const qse_char_t* ptr;
int pri = 0;
ptr = name;
while (ptr)
{
ptr = qse_strtok (ptr, QSE_T("|"), &tok);
if (tok.ptr)
{
for (i = 0; i < QSE_COUNTOF(__priority_names); i++)
{
if (qse_strxcmp(tok.ptr, tok.len, __priority_names[i]) == 0)
{
pri |= (1UL << i);
break;
}
}
if (i >= QSE_COUNTOF(__priority_names)) return 0; /* unknown name included */
}
}
return pri;
}
int qse_get_log_facility_by_name (const qse_char_t* name, qse_log_facility_t* fcode)
{
qse_size_t i;
for (i = 0; i < QSE_COUNTOF(__syslog_fac_info); i++)
{
if (qse_strcmp (__syslog_fac_info[i].name, name) == 0)
{
*fcode = __syslog_fac_info[i].code;
return 0;
}
}
return -1;
}