|
#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__
|