2018-12-16 01:42:37 +08:00
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
// Copyright (c) 2018 Yuxuan Shui <yshuiv7@gmail.com>
|
|
|
|
|
|
|
|
#pragma once
|
2018-12-20 07:10:58 +08:00
|
|
|
#include <assert.h>
|
2018-12-16 01:42:37 +08:00
|
|
|
#include <stdio.h>
|
|
|
|
|
2018-12-20 07:10:58 +08:00
|
|
|
#include "compiler.h"
|
|
|
|
|
|
|
|
enum log_level {
|
2018-12-20 09:58:23 +08:00
|
|
|
LOG_LEVEL_INVALID = -1,
|
2018-12-20 07:10:58 +08:00
|
|
|
LOG_LEVEL_TRACE = 0,
|
|
|
|
LOG_LEVEL_DEBUG,
|
|
|
|
LOG_LEVEL_INFO,
|
|
|
|
LOG_LEVEL_WARN,
|
|
|
|
LOG_LEVEL_ERROR,
|
2018-12-20 09:58:23 +08:00
|
|
|
LOG_LEVEL_FATAL,
|
2018-12-20 07:10:58 +08:00
|
|
|
};
|
|
|
|
|
2019-02-13 12:11:41 +08:00
|
|
|
#define LOG_UNLIKELY(level, x, ...) \
|
|
|
|
do { \
|
|
|
|
if (unlikely(LOG_LEVEL_##level >= log_get_level_tls())) { \
|
|
|
|
log_printf(tls_logger, LOG_LEVEL_##level, __func__, x, ##__VA_ARGS__); \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
2019-02-08 05:48:39 +08:00
|
|
|
#define LOG(level, x, ...) \
|
|
|
|
do { \
|
|
|
|
if (LOG_LEVEL_##level >= log_get_level_tls()) { \
|
|
|
|
log_printf(tls_logger, LOG_LEVEL_##level, __func__, x, ##__VA_ARGS__); \
|
|
|
|
} \
|
2018-12-20 10:34:45 +08:00
|
|
|
} while (0)
|
2019-02-13 12:11:41 +08:00
|
|
|
#define log_trace(x, ...) LOG_UNLIKELY(TRACE, x, ##__VA_ARGS__)
|
|
|
|
#define log_debug(x, ...) LOG_UNLIKELY(DEBUG, x, ##__VA_ARGS__)
|
2018-12-20 07:10:58 +08:00
|
|
|
#define log_info(x, ...) LOG(INFO, x, ##__VA_ARGS__)
|
|
|
|
#define log_warn(x, ...) LOG(WARN, x, ##__VA_ARGS__)
|
|
|
|
#define log_error(x, ...) LOG(ERROR, x, ##__VA_ARGS__)
|
2018-12-20 09:58:23 +08:00
|
|
|
#define log_fatal(x, ...) LOG(FATAL, x, ##__VA_ARGS__)
|
2018-12-20 07:10:58 +08:00
|
|
|
|
2020-02-27 04:16:55 +08:00
|
|
|
#define log_error_errno(x, ...) LOG(ERROR, x ": %s", ##__VA_ARGS__, strerror(errno))
|
|
|
|
|
2018-12-20 07:10:58 +08:00
|
|
|
struct log;
|
|
|
|
struct log_target;
|
|
|
|
|
|
|
|
attr_printf(4, 5) void log_printf(struct log *, int level, const char *func,
|
|
|
|
const char *fmt, ...);
|
|
|
|
|
|
|
|
attr_malloc struct log *log_new(void);
|
2019-02-08 05:48:39 +08:00
|
|
|
/// Destroy a log struct and every log target added to it
|
2018-12-20 07:10:58 +08:00
|
|
|
attr_nonnull_all void log_destroy(struct log *);
|
|
|
|
attr_nonnull(1) void log_set_level(struct log *l, int level);
|
2018-12-20 10:34:45 +08:00
|
|
|
attr_pure enum log_level log_get_level(const struct log *l);
|
2018-12-20 07:10:58 +08:00
|
|
|
attr_nonnull_all void log_add_target(struct log *, struct log_target *);
|
2019-02-21 22:08:08 +08:00
|
|
|
attr_pure enum log_level string_to_log_level(const char *);
|
2019-02-08 05:48:39 +08:00
|
|
|
/// Remove a previously added log target for a log struct, and destroy it. If the log
|
|
|
|
/// target was never added, nothing happens.
|
|
|
|
void log_remove_target(struct log *l, struct log_target *tgt);
|
2018-12-20 07:10:58 +08:00
|
|
|
|
|
|
|
extern thread_local struct log *tls_logger;
|
|
|
|
|
|
|
|
/// Create a thread local logger
|
|
|
|
static inline void log_init_tls(void) {
|
|
|
|
tls_logger = log_new();
|
|
|
|
}
|
|
|
|
/// Set thread local logger log level
|
|
|
|
static inline void log_set_level_tls(int level) {
|
|
|
|
assert(tls_logger);
|
|
|
|
log_set_level(tls_logger, level);
|
|
|
|
}
|
|
|
|
static inline attr_nonnull_all void log_add_target_tls(struct log_target *tgt) {
|
|
|
|
assert(tls_logger);
|
|
|
|
log_add_target(tls_logger, tgt);
|
|
|
|
}
|
|
|
|
|
2019-02-08 05:48:39 +08:00
|
|
|
static inline attr_nonnull_all void log_remove_target_tls(struct log_target *tgt) {
|
|
|
|
assert(tls_logger);
|
|
|
|
log_remove_target(tls_logger, tgt);
|
|
|
|
}
|
|
|
|
|
2018-12-20 10:34:45 +08:00
|
|
|
static inline attr_pure enum log_level log_get_level_tls(void) {
|
|
|
|
assert(tls_logger);
|
|
|
|
return log_get_level(tls_logger);
|
|
|
|
}
|
|
|
|
|
2018-12-20 07:10:58 +08:00
|
|
|
static inline void log_deinit_tls(void) {
|
|
|
|
assert(tls_logger);
|
|
|
|
log_destroy(tls_logger);
|
|
|
|
tls_logger = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
attr_malloc struct log_target *stderr_logger_new(void);
|
|
|
|
attr_malloc struct log_target *file_logger_new(const char *file);
|
|
|
|
attr_malloc struct log_target *null_logger_new(void);
|
2019-03-27 22:51:20 +08:00
|
|
|
attr_malloc struct log_target *gl_string_marker_logger_new(void);
|
2018-12-20 07:10:58 +08:00
|
|
|
|
|
|
|
// vim: set noet sw=8 ts=8:
|