/* Copyright Yann Weber This file is part of asmsh. asmsh is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. asmsh 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 General Public License for more details. You should have received a copy of the GNU General Public License along with asmsh. If not, see . */ #ifndef ASMSH_LOGGER_H #define ASMSH_LOGGER_H #include "config.h" /** A logger suitable for a shell * * Collect messages and deliver them when needed */ #include #include #include #include #include ///! TODO varargs macro & log functions, perror etc. #define asmsh_log_trace(msg) \ asmsh_log(_default_logger, ASMSH_TRACE, __FUNCTION__, msg) #define asmsh_log_debug(msg) \ asmsh_log(_default_logger, ASMSH_DEBUG, __FUNCTION__, msg) #define asmsh_log_info(msg) \ asmsh_log(_default_logger, ASMSH_INFO, __FUNCTION__, msg) #define asmsh_log_warning(msg) \ asmsh_log(_default_logger, ASMSH_WARN, __FUNCTION__, msg) #define asmsh_log_error(msg) \ asmsh_log(_default_logger, ASMSH_ERR, __FUNCTION__, msg) #define asmsh_log_fatal(msg) \ asmsh_log(_default_logger, ASMSH_FATAL, __FUNCTION__, msg) #define ASMSH_LOG_BUFFER_ALLOC 4096 typedef struct asmsh_logger_s asmsh_logger_t; typedef struct asmsh_log_msg_s asmsh_log_msg_t; typedef enum asmsh_loglevel_e asmsh_loglevel_t; typedef int (asmsh_log_fmt_f)(asmsh_log_msg_t*, char*, int); extern asmsh_logger_t *_default_logger; enum asmsh_loglevel_e { ASMSH_TRACE = 0, ASMSH_DEBUG = 10, ASMSH_INFO = 20, ASMSH_WARN = 30, ASMSH_ERR = 40, ASMSH_FATAL = 50 }; struct asmsh_log_msg_s { asmsh_loglevel_t level; time_t timestamp; char *caller; char *msg; asmsh_log_msg_t *nxt; }; struct asmsh_logger_s { asmsh_loglevel_t min_level; /** Buffered messages * * A single buffer is used to store asmsh_log_msg_t and the * associated strings (caller & msg) * msgs will be a sequence of [asmsh_log_msg_t][char*(caller)][char*(msg)]... */ void *msgs; /** Point on the address of the next message */ asmsh_log_msg_t *nxt; /** Memory used by stored messages */ size_t msgs_sz; /** Allocated buffer for messages */ size_t msgs_alloc; /** Default formatter */ asmsh_log_fmt_f *fmt; }; static inline int asmsh_logger_msg_islast(asmsh_logger_t *logger, asmsh_log_msg_t *msg) { return ((void*)msg) == ((void*)logger->nxt); } static inline int asmsh_logger_empty(asmsh_logger_t *logger) { return asmsh_logger_msg_islast(logger, (asmsh_log_msg_t*)logger->msgs); } /** If null use default min_level of WARN * @param asmsh_logger_t* Optionnal logger to set * @return 0 if ok else -1 */ int asmsh_logger_setup(asmsh_logger_t *logger); asmsh_logger_t* asmsh_logger_new(asmsh_loglevel_t min_level); void asmsh_logger_free(asmsh_logger_t* logger); int asmsh_logger_dprint_fmt(int fd, asmsh_logger_t *logger, asmsh_log_fmt_f *custom_fmt); static int asmsh_logger_dprint(int fd, asmsh_logger_t *logger) { return asmsh_logger_dprint_fmt(fd, logger, NULL); } /// Collect & format messages before printing them on stderr static inline int asmsh_logger_stderr(asmsh_logger_t *logger) { return asmsh_logger_dprint(2, logger); } int asmsh_log(asmsh_logger_t *logger, asmsh_loglevel_t lvl, const char caller[], const char *msg); const char * asmsh_loglevel_name(asmsh_loglevel_t lvl); /** Default formatter with UTC datetime, lvl, caller and message */ int asmsh_log_default_fmt(asmsh_log_msg_t *msg, char *res, int sz); /** Simple formatter with level and message */ int asmsh_log_lvl_fmt(asmsh_log_msg_t *msg, char *res, int sz); #endif