libqb  1.0.3
simplelog.c
/*
* Copyright (c) 2011 Red Hat, Inc.
*
* All rights reserved.
*
* Author: Angus Salkeld <asalkeld@redhat.com>
*
* libqb is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* libqb is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
*/
#include "os_base.h"
#include <signal.h>
#include <syslog.h>
#include <qb/qbdefs.h>
#include <qb/qblog.h>
#define MY_TAG_ONE (1)
#define MY_TAG_TWO (1 << 1)
#define MY_TAG_THREE (1 << 2)
static uint8_t _log_priority = LOG_WARNING;
static void
func_one(void)
{
FILE *fd;
qb_logt(LOG_DEBUG, MY_TAG_TWO, "arf arf?");
qb_logt(LOG_CRIT, MY_TAG_THREE, "arrrg!");
qb_logt(134, MY_TAG_THREE, "big priority");
qb_logt(LOG_ERR, MY_TAG_THREE, "oops, I did it again");
qb_log(LOG_INFO, "are you aware ...");
fd = fopen("/nothing.txt", "r+");
if (fd == NULL) {
qb_perror(LOG_ERR, "can't open(\"/nothing.txt\")");
} else {
fclose(fd);
}
}
static void
func_two(void)
{
qb_logt(LOG_DEBUG, 0, "arf arf?");
qb_logt(LOG_CRIT, MY_TAG_ONE, "arrrg!");
qb_log(LOG_ERR, "oops, I did it again");
qb_logt(LOG_INFO, MY_TAG_THREE, "are you aware ...");
}
static void
show_usage(const char *name)
{
printf("usage: \n");
printf("%s <options>\n", name);
printf("\n");
printf(" options:\n");
printf("\n");
printf(" -v verbose\n");
printf(" -t threaded logging\n");
printf(" -o log to stdout\n");
printf(" -e log to stderr\n");
printf(" -b log to blackbox\n");
printf(" -f <filename> log to a file\n");
printf(" -h show this help text\n");
printf("\n");
}
static int32_t do_blackbox = QB_FALSE;
static int32_t do_threaded = QB_FALSE;
static void
sigsegv_handler(int sig)
{
(void)signal(SIGSEGV, SIG_DFL);
if (do_blackbox) {
qb_log_blackbox_write_to_file("simple-log.fdata");
}
raise(SIGSEGV);
}
static const char *
my_tags_stringify(uint32_t tags)
{
return "libqb";
} else if (qb_bit_is_set(tags, 0)) {
return "ONE";
} else if (qb_bit_is_set(tags, 1)) {
return "TWO";
} else if (qb_bit_is_set(tags, 2)) {
return "THREE";
} else {
return "MAIN";
}
}
static void
trace_logger(int32_t t,
struct qb_log_callsite *cs, time_t timestamp, const char *msg)
{
char output_buffer[QB_LOG_MAX_LEN];
output_buffer[0] = '\0';
qb_log_target_format(t, cs, timestamp, msg, output_buffer);
fprintf(stderr, "%s\n", output_buffer);
}
static void
m_filter(struct qb_log_callsite *cs)
{
if ((cs->priority >= LOG_ALERT &&
cs->priority <= _log_priority) &&
strcmp(cs->filename, __FILE__) == 0) {
} else {
}
}
int32_t
main(int32_t argc, char *argv[])
{
const char *options = "vhteobdf:";
int32_t opt;
int32_t tracer;
int32_t do_stderr = QB_FALSE;
int32_t do_stdout = QB_FALSE;
int32_t do_dump_blackbox = QB_FALSE;
char *logfile = NULL;
int32_t log_fd = -1;
while ((opt = getopt(argc, argv, options)) != -1) {
switch (opt) {
case 'd':
do_dump_blackbox = QB_TRUE;
break;
case 't':
do_threaded = QB_TRUE;
break;
case 'e':
do_stderr = QB_TRUE;
break;
case 'o':
do_stdout = QB_TRUE;
break;
case 'b':
do_blackbox = QB_TRUE;
break;
case 'f':
logfile = optarg;
break;
case 'v':
_log_priority++;
break;
case 'h':
default:
show_usage(argv[0]);
exit(0);
break;
}
}
if (do_dump_blackbox) {
qb_log_blackbox_print_from_file("simple-log.fdata");
exit(0);
}
signal(SIGSEGV, sigsegv_handler);
qb_log_init("simple-log", LOG_USER, LOG_INFO);
qb_log_tags_stringify_fn_set(my_tags_stringify);
if (do_stderr) {
qb_log_format_set(QB_LOG_STDERR, "[%p] %4g: %f:%l %b");
tracer = qb_log_custom_open(trace_logger, NULL, NULL, NULL);
qb_log_format_set(tracer, "%4g: %n() %b");
QB_LOG_FILTER_FILE, __FILE__,
LOG_TRACE, 200);
}
if (do_stdout) {
QB_LOG_FILTER_FILE, __FILE__,
LOG_ALERT, QB_MIN(LOG_DEBUG, _log_priority));
qb_log_format_set(QB_LOG_STDOUT, "[%p] %4g: %f:%l %b");
}
if (do_blackbox) {
QB_LOG_FILTER_FILE, "*", LOG_DEBUG);
}
if (logfile) {
log_fd = qb_log_file_open(logfile);
QB_LOG_FILTER_FILE, __FILE__, _log_priority);
qb_log_format_set(log_fd, "[%N] %t %n() [%p] %b");
qb_log_ctl(log_fd, QB_LOG_CONF_THREADED, do_threaded);
}
if (do_threaded) {
}
qb_log(LOG_DEBUG, "hello");
qb_log(LOG_INFO, "this is an info");
qb_log(LOG_NOTICE, "hello - notice?");
{
char * str = NULL;
qb_log(LOG_ERR,
"%s-%d-%s-%u",
NULL, 952, str, 56);
}
func_one();
func_two();
if (!do_threaded) {
/* Disabling syslog here will prevent the logs from
* getting flushed in qb_log_fini() if threaded
* logging is on.
*/
qb_log(LOG_WARNING, "no syslog");
qb_log(LOG_ERR, "no syslog");
}
if (do_blackbox) {
logfile = NULL;
logfile[5] = 'a';
} else {
}
return 0;
}
These are some convience macros and defines.
#define QB_FALSE
Definition: qbdefs.h:47
#define qb_bit_is_set(barray, bit)
Definition: qbdefs.h:56
#define qb_bit_clear(barray, bit)
Definition: qbdefs.h:55
#define QB_MIN(a, b)
Definition: qbdefs.h:42
#define qb_bit_set(barray, bit)
Definition: qbdefs.h:54
#define QB_TRUE
Definition: qbdefs.h:48
The logging API provides four main parts (basics, filtering, threading & blackbox).
@ QB_LOG_FILTER_ADD
Definition: qblog.h:595
void qb_log_format_set(int32_t t, const char *format)
Set the format specifiers.
int32_t qb_log_filter_ctl2(int32_t value, enum qb_log_filter_conf c, enum qb_log_filter_type type, const char *text, uint8_t high_priority, uint8_t low_priority)
This extends qb_log_filter_ctl() by been able to provide a high_priority.
void qb_log_blackbox_print_from_file(const char *filename)
Read the blackbox for file and print it out.
void qb_log_init(const char *name, int32_t facility, uint8_t priority)
Init the logging system.
@ QB_LOG_BLACKBOX
Definition: qblog.h:553
@ QB_LOG_SYSLOG
Definition: qblog.h:551
@ QB_LOG_STDOUT
Definition: qblog.h:554
@ QB_LOG_STDERR
Definition: qblog.h:552
int32_t qb_log_file_open(const char *filename)
Open a log file.
#define QB_LOG_MAX_LEN
Definition: qblog.h:267
#define qb_logt(priority, tags, fmt, args...)
This is the function to generate a log message if you want to manually add tags.
Definition: qblog.h:478
int32_t qb_log_custom_open(qb_log_logger_fn log_fn, qb_log_close_fn close_fn, qb_log_reload_fn reload_fn, void *user_data)
Open a custom log target.
#define qb_leave()
Definition: qblog.h:533
#define qb_perror(priority, fmt, args...)
This is similar to perror except it goes into the logging system.
Definition: qblog.h:523
int32_t qb_log_filter_ctl(int32_t value, enum qb_log_filter_conf c, enum qb_log_filter_type type, const char *text, uint8_t low_priority)
This allows you modify the 'tags' and 'targets' callsite fields at runtime.
void qb_log_tags_stringify_fn_set(qb_log_tags_stringify_fn fn)
Set the callback to map the 'tags' bit map to a string.
int32_t qb_log_filter_fn_set(qb_log_filter_fn fn)
Instead of using the qb_log_filter_ctl() functions you can apply the filters manually by defining a c...
#define qb_enter()
Definition: qblog.h:532
@ QB_LOG_FILTER_FILE
Definition: qblog.h:586
int32_t qb_log_thread_start(void)
Start the logging pthread.
@ QB_LOG_CONF_ENABLED
Definition: qblog.h:573
@ QB_LOG_CONF_THREADED
Definition: qblog.h:577
@ QB_LOG_CONF_SIZE
Definition: qblog.h:576
int32_t qb_log_ctl(int32_t target, enum qb_log_conf conf_type, int32_t arg)
Main logging control function.
#define qb_log(priority, fmt, args...)
This is the main function to generate a log message.
Definition: qblog.h:501
#define QB_LOG_TAG_LIBQB_MSG_BIT
Definition: qblog.h:407
uint32_t tags
Definition: qblog.h:6
void qb_log_fini(void)
Logging system finalization function.
ssize_t qb_log_blackbox_write_to_file(const char *filename)
Write the blackbox to file.
void qb_log_target_format(int32_t target, struct qb_log_callsite *cs, time_t timestamp, const char *formatted_message, char *output_buffer)
Format the callsite and timestamp info according to the format.
#define LOG_TRACE
Definition: qblog.h:265
An instance of this structure is created in a special ELF section at every dynamic debug callsite.
Definition: qblog.h:277
uint8_t priority
Definition: qblog.h:281
uint32_t targets
Definition: qblog.h:283
const char * filename
Definition: qblog.h:279