Project

General

Profile

Download (5.4 KB) Statistics
| Branch: | Tag: | Revision:
#ifndef __SPEW_H__
#define __SPEW_H__


#include <stdarg.h> // for va_list
#include <stddef.h> // for size_t
#include <stdint.h> // for uint64_t
#include "simplest-defs.h" // for boolint
struct spewlog; // lines 13-13


enum {
SPEW_DEFAULT_ROLL_PERIOD = 1440, // go: logging.DefaultLogfileRollPeriod
// go: logging.MaxLogFileSize
SPEW_MAX_LOGFILE_SIZE = 1024ll * 1024ll * 512ll,
THREADNAME_SIZE = 16, // <== man pthread_setname_np()
};

/* Two INFO levels.

The theory is that in production we want INFO about
open/close/dropped connections, how many extents we found on disk,
etc. Such INFO is kind-of useless and distracting for tests.
Thus, the default verbosity is SPEW_TEST_INFO for tests.
Production code should run at SPEW_INFO and print more spewage.
*/
enum {
FIRST_SPEW_LEVEL = 0u,
SPEW_TRACE = 0u,
SPEW_DEBUG = 1u,
SPEW_INFO = 2u,
SPEW_TEST_INFO = 3u,
SPEW_WARN = 4u,
SPEW_ERROR = 5u,
SPEW_BUG = 6u,
SPEW_FATAL = 7u,
SPEW_CRIT = 8u,
N_SPEW_LEVELS = 9u,
};


extern struct spewlog the_spew_log;
extern struct spewlog the_metrics_log;


const char *
log_get_level_name(size_t level);
size_t
log_level_of_level_name(const char *level_name);
size_t
log_set_level(struct spewlog *log, size_t new_level);
size_t
log_add_level(struct spewlog *log, size_t add, size_t sub);

void
HACK_log_inc_level_count(size_t level);
void
spew_reset_level_counts(uint64_t *level_counters, size_t level_counters_len);

void
log_config(struct spewlog *log, const char *logrootdir, const char *argv0,
size_t roll_period_m, boolint spew_to_stderr, boolint debug);
void log_teardown(struct spewlog *log);

boolint
log_enabled(struct spewlog *log, size_t level);

void
logv(struct spewlog *log,
boolint honor_spewage_suppression,
boolint maybe_roll,
boolint is_stack_trace,
size_t level,
const char *file,
size_t line,
const char *fn,
const char *fmt,
va_list ap)
__attribute__((format(printf, 9, 0)));

void log0(struct spewlog *log,
boolint honor_spewage_suppression,
boolint maybe_roll,
boolint is_stack_trace,
size_t level,
const char *file,
size_t line,
const char *fn,
const char *fmt,
...)
__attribute__ ((format (printf, 9, 10)));
void
log1(struct spewlog *log,
const char *fmt,
...)
__attribute__ ((format (printf, 2, 3)));
boolint
spew_logfile_ok(struct spewlog *log);

/* Legacy APIs.
*/
static inline const char *
spew_get_level_name(size_t level)
{
return log_get_level_name(level);
}
static inline size_t
spew_set_level(size_t new_level)
{
return log_set_level(&the_spew_log, new_level);
}
static inline size_t spew_more(void)
{
return log_add_level(&the_spew_log, /*add=*/0, /*sub=*/1);
}
static inline size_t spew_less(void)
{
return log_add_level(&the_spew_log, /*add=*/1, /*sub=*/0);
}

/* Simple backtrace facility.
*/
void spew_backtrace_simple(void);

#define would_spew(lvl) log_enabled(&the_spew_log, (lvl))

#define spew(lvl, fmt, ...) \
({ \
if (log_enabled(&the_spew_log, lvl)) { \
log0(&the_spew_log, \
/*honor_spewage_suppression=*/1, /*maybe_roll=*/1, \
/*is_stack_trace=*/0, \
lvl, __FILE__, __LINE__, __FUNCTION__, \
fmt, ##__VA_ARGS__); \
} \
})

#define spew_no_roll(lvl, fmt, ...) \
({ \
if (log_enabled(&the_spew_log, lvl)) { \
log0(&the_spew_log, \
/*honor_spewage_suppression=*/1, /*maybe_roll=*/0, \
/*is_stack_trace=*/0, \
lvl, __FILE__, __LINE__, __FUNCTION__, \
fmt, ##__VA_ARGS__); \
} \
})

#define spew_for_backtrace(lvl, file, line, function, symbol) \
({ \
if (log_enabled(&the_spew_log, lvl)) { \
log0(&the_spew_log, \
/*honor_spewage_suppression=*/1, /*maybe_roll=*/0, \
/*is_stack_trace=*/1, \
lvl, file, line, function, "%s", symbol); \
} \
})

void
spew_config(int argc, char *const argv[], const char *logrootdir,
size_t roll_period_m, boolint spew_to_stderr, boolint debug);
void
spew_teardown(void);

size_t
spew_get_level(void);
// Different from DEBUG_spew_get_level because it acquires a lock.

boolint
DEBUG_shutup(boolint suppress);
size_t
DEBUG_spew_get_level(void);


#endif // !__SPEW_H__
(13-13/14)