Skip to content

Commit

Permalink
Merge pull request #181 from jnpkrn/log-target-slot-enum
Browse files Browse the repository at this point in the history
log: enum qb_log_target_slot introduction + qblog.h cleanup
  • Loading branch information
chrissie-c committed Feb 22, 2016
2 parents c242bad + 837108b commit 7b9b72e
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 55 deletions.
81 changes: 56 additions & 25 deletions include/qb/qblog.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ extern "C" {
* Call qb_log() to generate a log message. Then to write the message
* somewhere meaningful call qb_log_ctl() to configure the targets.
*
* Simplist possible use:
* Simplest possible use:
* @code
* main() {
* qb_log_init("simple-log", LOG_DAEMON, LOG_INFO);
Expand All @@ -65,17 +65,18 @@ extern "C" {
* @endcode
*
* @par Configuring log targets.
* A log target can by syslog, stderr, the blackbox or a text file.
* A log target can be syslog, stderr, the blackbox, stdout, or a text file.
* By default only syslog is enabled.
*
* To enable a target do the following
* To enable a target do the following:
* @code
* qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_TRUE);
* @endcode
*
* syslog, stderr and the blackbox are static (they don't need
* to be created, just enabled or disabled. However you can open multiple
* logfiles (32 - QB_LOG_BLACKBOX). To do this use the following code.
* syslog, stderr, the blackbox, and stdout are static (they don't need
* to be created, just enabled or disabled). However you can open multiple
* logfiles (QB_LOG_TARGET_MAX - QB_LOG_TARGET_STATIC_MAX).
* To do this, use the following code:
* @code
* mytarget = qb_log_file_open("/var/log/mylogfile");
* qb_log_ctl(mytarget, QB_LOG_CONF_ENABLED, QB_TRUE);
Expand Down Expand Up @@ -114,19 +115,21 @@ extern "C" {
* -# function name + priority
* -# format string + priority
*
* So to make all logs from evil_fnunction() go to stderr do the following:
* So to make all logs from evil_function() go to stderr, do the following:
* @code
* qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD,
* QB_LOG_FILTER_FUNCTION, "evil_fnunction", LOG_TRACE);
* QB_LOG_FILTER_FUNCTION, "evil_function", LOG_TRACE);
* @endcode
*
* So to make all logs from totem* (with a priority <= LOG_INFO) go to stderr do the following:
* So to make all logs from totem* (with a priority <= LOG_INFO) go to stderr,
* do the following:
* @code
* qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD,
* QB_LOG_FILTER_FILE, "totem", LOG_INFO);
* @endcode
*
* So to make all logs with the substring "ringbuffer" go to stderr do the following:
* So to make all logs with the substring "ringbuffer" go to stderr,
* do the following:
* @code
* qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD,
* QB_LOG_FILTER_FORMAT, "ringbuffer", LOG_TRACE);
Expand All @@ -138,8 +141,8 @@ extern "C" {
* and use qg_log_filter_ctl to set the QB_LOG_CONF_THREADED flag on all the
* logging targets in use.
*
* To achieve non-blocking logging you can use threaded logging as well
* So any calls to write() or syslog() will not hold up your program.
* To achieve non-blocking logging, so that any calls to write() or syslog()
* will not hold up your program, you can use threaded logging as well.
*
* Threaded logging use:
* @code
Expand Down Expand Up @@ -278,7 +281,7 @@ void qb_log_real_va_(struct qb_log_callsite *cs, va_list ap);
*
* @note the performance of this will not impress you, as
* the filtering is done on each log message, not
* before hand. So try doing basic pre-filtering.
* beforehand. So try doing basic pre-filtering.
*
* @param function originating function name
* @param filename originating filename
Expand All @@ -300,7 +303,7 @@ void qb_log_from_external_source(const char *function,
__attribute__ ((format (printf, 3, 7)));

/**
* Get or create a callsite at the give position.
* Get or create a callsite at the given position.
*
* The result can then be passed into qb_log_real_()
*
Expand Down Expand Up @@ -397,12 +400,36 @@ void qb_log_from_external_source_va(const char *function,
#define qb_enter() qb_log(LOG_TRACE, "ENTERING %s()", __func__)
#define qb_leave() qb_log(LOG_TRACE, "LEAVING %s()", __func__)

#define QB_LOG_SYSLOG 0
#define QB_LOG_STDERR 1
#define QB_LOG_BLACKBOX 2
#define QB_LOG_STDOUT 3

#define QB_LOG_TARGET_MAX 32
/*
* Note that QB_LOG_TARGET_{STATIC_,}MAX are sentinel indexes
* as non-inclusive higher bounds of the respective categories
* (static and all the log targets) and also denote the number
* of (reserved) items in the category. Both are possibly subject
* of change, hence it is only adequate to always refer to them
* via these defined values.
* Similarly, there are QB_LOG_TARGET_{STATIC_,DYNAMIC_,}START
* and QB_LOG_TARGET_{STATIC_,DYNAMIC_,}END values, but these
* are inclusive lower and higher bounds, respectively.
*/
enum qb_log_target_slot {
QB_LOG_TARGET_START,

/* static */
QB_LOG_TARGET_STATIC_START = QB_LOG_TARGET_START,
QB_LOG_SYSLOG = QB_LOG_TARGET_STATIC_START,
QB_LOG_STDERR,
QB_LOG_BLACKBOX,
QB_LOG_STDOUT,
QB_LOG_TARGET_STATIC_MAX,
QB_LOG_TARGET_STATIC_END = QB_LOG_TARGET_STATIC_MAX - 1,

/* dynamic */
QB_LOG_TARGET_DYNAMIC_START = QB_LOG_TARGET_STATIC_MAX,

QB_LOG_TARGET_MAX = 32,
QB_LOG_TARGET_DYNAMIC_END = QB_LOG_TARGET_MAX - 1,
QB_LOG_TARGET_END = QB_LOG_TARGET_DYNAMIC_END,
};

enum qb_log_target_state {
QB_LOG_STATE_UNUSED = 1,
Expand Down Expand Up @@ -469,15 +496,15 @@ void qb_log_init(const char *name,
*
* It releases any shared memory.
* Stops the logging thread if running.
* Flushes the last message to their destinations.
* Flushes the last messages to their destinations.
*/
void qb_log_fini(void);

/**
* If you are using dynamically loadable modules via dlopen() and
* you load them after qb_log_init() then after you load the module
* you will need to do the following to get the filters to work
* in that module.
* in that module:
* @code
* _start = dlsym (dl_handle, "__start___verbose");
* _stop = dlsym (dl_handle, "__stop___verbose");
Expand Down Expand Up @@ -549,7 +576,7 @@ int32_t qb_log_filter_ctl2(int32_t value, enum qb_log_filter_conf c,
* Instead of using the qb_log_filter_ctl() functions you
* can apply the filters manually by defining a callback
* and setting the targets field using qb_bit_set() and
* qb_bit_clear() like the following below.
* qb_bit_clear() like the following below:
* @code
* static void
* m_filter(struct qb_log_callsite *cs)
Expand Down Expand Up @@ -593,7 +620,9 @@ void qb_log_format_set(int32_t t, const char* format);
* Open a log file.
*
* @retval -errno on error
* @retval 3 to 31 (to be passed into other qb_log_* functions)
* @retval value in inclusive range QB_LOG_TARGET_DYNAMIC_START
* to QB_LOG_TARGET_DYNAMIC_END
* (to be passed into other qb_log_* functions)
*/
int32_t qb_log_file_open(const char *filename);

Expand Down Expand Up @@ -629,7 +658,9 @@ void qb_log_blackbox_print_from_file(const char* filename);
* Open a custom log target.
*
* @retval -errno on error
* @retval 3 to 31 (to be passed into other qb_log_* functions)
* @retval value in inclusive range QB_LOG_TARGET_DYNAMIC_START
* to QB_LOG_TARGET_DYNAMIC_END
* (to be passed into other qb_log_* functions)
*/
int32_t qb_log_custom_open(qb_log_logger_fn log_fn,
qb_log_close_fn close_fn,
Expand Down
48 changes: 24 additions & 24 deletions lib/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ qb_log_real_va_(struct qb_log_callsite *cs, va_list ap)
int32_t found_threaded = QB_FALSE;
struct qb_log_target *t;
struct timespec tv;
int32_t pos;
enum qb_log_target_slot pos;
int32_t formatted = QB_FALSE;
char buf[QB_LOG_MAX_LEN];
char *str = buf;
Expand Down Expand Up @@ -237,7 +237,7 @@ qb_log_real_va_(struct qb_log_callsite *cs, va_list ap)
* 1 if we can find a threaded target that needs this log then post it
* 2 foreach non-threaded target call it's logger function
*/
for (pos = 0; pos <= conf_active_max; pos++) {
for (pos = QB_LOG_TARGET_START; pos <= conf_active_max; pos++) {
t = &conf[pos];
if ((t->state == QB_LOG_STATE_ENABLED)
&& qb_bit_is_set(cs->targets, pos)) {
Expand Down Expand Up @@ -287,9 +287,9 @@ qb_log_thread_log_write(struct qb_log_callsite *cs,
time_t timestamp, const char *buffer)
{
struct qb_log_target *t;
int32_t pos;
enum qb_log_target_slot pos;

for (pos = 0; pos <= conf_active_max; pos++) {
for (pos = QB_LOG_TARGET_START; pos <= conf_active_max; pos++) {
t = &conf[pos];
if ((t->state == QB_LOG_STATE_ENABLED) && t->threaded
&& qb_bit_is_set(cs->targets, t->pos)) {
Expand All @@ -312,7 +312,7 @@ qb_log_callsite_get(const char *function,
struct qb_log_callsite *cs;
int32_t new_dcs = QB_FALSE;
struct qb_list_head *f_item;
int32_t pos;
enum qb_log_target_slot pos;

if (!logger_inited) {
return NULL;
Expand All @@ -326,7 +326,7 @@ qb_log_callsite_get(const char *function,

if (new_dcs) {
pthread_rwlock_rdlock(&_listlock);
for (pos = 0; pos <= conf_active_max; pos++) {
for (pos = QB_LOG_TARGET_START; pos <= conf_active_max; pos++) {
t = &conf[pos];
if (t->state != QB_LOG_STATE_ENABLED) {
continue;
Expand Down Expand Up @@ -408,7 +408,7 @@ qb_log_callsites_register(struct qb_log_callsite *_start,
struct qb_log_callsite *cs;
struct qb_log_target *t;
struct qb_log_filter *flt;
int32_t pos;
enum qb_log_target_slot pos;

if (_start == NULL || _stop == NULL) {
return -EINVAL;
Expand Down Expand Up @@ -437,7 +437,7 @@ qb_log_callsites_register(struct qb_log_callsite *_start,
/*
* Now apply the filters on these new callsites
*/
for (pos = 0; pos <= conf_active_max; pos++) {
for (pos = QB_LOG_TARGET_START; pos <= conf_active_max; pos++) {
t = &conf[pos];
if (t->state != QB_LOG_STATE_ENABLED) {
continue;
Expand Down Expand Up @@ -828,18 +828,18 @@ _log_so_walk_dlnames(void)
static void
_log_target_state_set(struct qb_log_target *t, enum qb_log_target_state s)
{
int32_t i;
enum qb_log_target_slot i;
int32_t a_set = QB_FALSE;
int32_t u_set = QB_FALSE;

t->state = s;

for (i = 31; i >= 0; i--) {
if (!a_set && conf[i].state == QB_LOG_STATE_ENABLED) {
for (i = QB_LOG_TARGET_MAX; i > QB_LOG_TARGET_START; i--) {
if (!a_set && conf[i-1].state == QB_LOG_STATE_ENABLED) {
a_set = QB_TRUE;
conf_active_max = i;
conf_active_max = i-1;
}
if (!u_set && conf[i].state != QB_LOG_STATE_UNUSED) {
if (!u_set && conf[i-1].state != QB_LOG_STATE_UNUSED) {
u_set = QB_TRUE;
}
}
Expand All @@ -848,13 +848,14 @@ _log_target_state_set(struct qb_log_target *t, enum qb_log_target_state s)
void
qb_log_init(const char *name, int32_t facility, uint8_t priority)
{
int32_t i;
int32_t l;
enum qb_log_target_slot i;

i = pthread_rwlock_init(&_listlock, NULL);
assert(i == 0);
l = pthread_rwlock_init(&_listlock, NULL);
assert(l == 0);
qb_log_format_init();

for (i = 0; i < QB_LOG_TARGET_MAX; i++) {
for (i = QB_LOG_TARGET_START; i < QB_LOG_TARGET_MAX; i++) {
conf[i].pos = i;
conf[i].debug = QB_FALSE;
conf[i].file_sync = QB_FALSE;
Expand All @@ -872,9 +873,8 @@ qb_log_init(const char *name, int32_t facility, uint8_t priority)
_log_so_walk_dlnames();
#endif /* QB_HAVE_ATTRIBUTE_SECTION */

conf[QB_LOG_STDERR].state = QB_LOG_STATE_DISABLED;
conf[QB_LOG_BLACKBOX].state = QB_LOG_STATE_DISABLED;
conf[QB_LOG_STDOUT].state = QB_LOG_STATE_DISABLED;
for (i = QB_LOG_TARGET_STATIC_START; i < QB_LOG_TARGET_STATIC_MAX; i++)
conf[i].state = QB_LOG_STATE_DISABLED;

logger_inited = QB_TRUE;
(void)qb_log_syslog_open(&conf[QB_LOG_SYSLOG]);
Expand All @@ -893,7 +893,7 @@ qb_log_fini(void)
struct qb_list_head *iter2;
struct qb_list_head *next;
struct qb_list_head *next2;
int32_t pos;
enum qb_log_target_slot pos;

if (!logger_inited) {
return;
Expand All @@ -902,7 +902,7 @@ qb_log_fini(void)
qb_log_thread_stop();
pthread_rwlock_destroy(&_listlock);

for (pos = 0; pos <= conf_active_max; pos++) {
for (pos = QB_LOG_TARGET_START; pos <= conf_active_max; pos++) {
t = &conf[pos];
_log_target_disable(t);
qb_list_for_each_safe(iter2, next2, &t->filter_head) {
Expand All @@ -928,8 +928,8 @@ qb_log_fini(void)
struct qb_log_target *
qb_log_target_alloc(void)
{
int32_t i;
for (i = 0; i < QB_LOG_TARGET_MAX; i++) {
enum qb_log_target_slot i;
for (i = QB_LOG_TARGET_START; i < QB_LOG_TARGET_MAX; i++) {
if (conf[i].state == QB_LOG_STATE_UNUSED) {
_log_target_state_set(&conf[i], QB_LOG_STATE_DISABLED);
return &conf[i];
Expand Down
13 changes: 7 additions & 6 deletions lib/log_format.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,14 @@ static pthread_rwlock_t _formatlock;
void
qb_log_format_init(void)
{
int32_t i;
int32_t l;
struct qb_log_target *t;
enum qb_log_target_slot i;

i = pthread_rwlock_init(&_formatlock, NULL);
assert(i == 0);
l = pthread_rwlock_init(&_formatlock, NULL);
assert(l == 0);

for (i = 0; i < QB_LOG_TARGET_MAX; i++) {
for (i = QB_LOG_TARGET_START; i < QB_LOG_TARGET_MAX; i++) {
t = qb_log_target_get(i);
t->format = strdup("[%p] %b");
}
Expand All @@ -103,11 +104,11 @@ void
qb_log_format_fini(void)
{
struct qb_log_target *t;
int32_t i;
enum qb_log_target_slot i;

pthread_rwlock_destroy(&_formatlock);

for (i = 0; i < QB_LOG_TARGET_MAX; i++) {
for (i = QB_LOG_TARGET_START; i < QB_LOG_TARGET_MAX; i++) {
t = qb_log_target_get(i);
free(t->format);
}
Expand Down

0 comments on commit 7b9b72e

Please sign in to comment.