change the logging function to support priority masking
This commit is contained in:
		
							
								
								
									
										251
									
								
								qse/lib/si/log.c
									
									
									
									
									
								
							
							
						
						
									
										251
									
								
								qse/lib/si/log.c
									
									
									
									
									
								
							| @ -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; | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user