Files
picom/src/log.h
Yuxuan Shui 185c0ce97c Guard log_printf in LOG macros with a log level check
So that the format arguments will only be evaluated if the log is
enabled by the log level. Allow us to add more expensive logs without
impact performance when they are not enabled.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-12-20 02:34:45 +00:00

100 lines
3.4 KiB
C

// SPDX-License-Identifier: MPL-2.0
// Copyright (c) 2018 Yuxuan Shui <yshuiv7@gmail.com>
#pragma once
#include <assert.h>
#include <stdio.h>
#include "compiler.h"
enum log_level {
LOG_LEVEL_INVALID = -1,
LOG_LEVEL_TRACE = 0,
LOG_LEVEL_DEBUG,
LOG_LEVEL_INFO,
LOG_LEVEL_WARN,
LOG_LEVEL_ERROR,
LOG_LEVEL_FATAL,
};
#define LOG(level, x, ...) \
do { \
if (LOG_LEVEL_##level >= log_get_level_tls()) { \
log_printf(tls_logger, LOG_LEVEL_##level, __func__, x, \
##__VA_ARGS__); \
} \
} while (0)
#define log_trace(x, ...) LOG(TRACE, x, ##__VA_ARGS__)
#define log_debug(x, ...) LOG(DEBUG, x, ##__VA_ARGS__)
#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__)
#define log_fatal(x, ...) LOG(FATAL, x, ##__VA_ARGS__)
/// Print out an error message.
#define printf_err(format, ...) log_error(format, ##__VA_ARGS__)
/// Print out an error message with function name.
#define printf_errf(format, ...) log_error(format, ##__VA_ARGS__)
/// Print out an error message with function name, and quit with a
/// specific exit code.
#define printf_errfq(code, format, ...) \
{ \
log_error(format, ##__VA_ARGS__); \
exit(code); \
}
/// Print out a debug message.
#define printf_dbg(format, ...) log_debug(format, ##__VA_ARGS__)
/// Print out a debug message with function name.
#define printf_dbgf(format, ...) log_debug(format, ##__VA_ARGS__)
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);
attr_nonnull_all void log_destroy(struct log *);
attr_nonnull(1) void log_set_level(struct log *l, int level);
attr_pure enum log_level log_get_level(const struct log *l);
attr_nonnull_all void log_add_target(struct log *, struct log_target *);
attr_const enum log_level string_to_log_level(const char *);
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);
}
static inline attr_pure enum log_level log_get_level_tls(void) {
assert(tls_logger);
return log_get_level(tls_logger);
}
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);
attr_malloc struct log_target *glx_string_marker_logger_new(void);
// vim: set noet sw=8 ts=8: