log.hh (fstransform-0.9.3-src) | : | log.hh (fstransform-0.9.4) | ||
---|---|---|---|---|
/* | /* | |||
* fstransform - transform a file-system to another file-system type, | * logging utilities for fsattr, fsmove, fsremap | |||
* preserving its contents and without the need for a backup | ||||
* | * | |||
* Copyright (C) 2011-2012 Massimiliano Ghilardi | * Copyright (C) 2011-2012 Massimiliano Ghilardi | |||
* | * | |||
* This program is free software: you can redistribute it and/or modify | * This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | * it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | * the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | * (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU General Public License for more details. | |||
* | * | |||
* You should have received a copy of the GNU General Public License | * You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | * along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
* | * | |||
* log.hh | * log.hh | |||
* | * | |||
* Created on: Mar 8, 2011 | * Created on: Mar 8, 2011 | |||
* Author: max | * Author: max | |||
*/ | */ | |||
#ifndef FSTRANSFORM_LOG_HH | #ifndef FSTRANSFORM_LOG_HH | |||
#define FSTRANSFORM_LOG_HH | #define FSTRANSFORM_LOG_HH | |||
#include "types.hh" /* for ft_string */ | #include "first.hh" | |||
#if defined(FT_HAVE_ERRNO_H) | #if defined(FT_HAVE_ERRNO_H) | |||
# include <errno.h> /* for EINVAL */ | # include <errno.h> /* for EINVAL */ | |||
#elif defined(FT_HAVE_CERRNO) && defined(__cplusplus) | #elif defined(FT_HAVE_CERRNO) && defined(__cplusplus) | |||
# include <cerrno> /* for EINVAL */ | # include <cerrno> /* for EINVAL */ | |||
#endif | #endif | |||
#if defined(FT_HAVE_STDARG_H) | #if defined(FT_HAVE_STDARG_H) | |||
# include <stdarg.h> /* for va_list. also for va_start(), va_end(), va_copy( ) used by log.cc */ | # include <stdarg.h> /* for va_list. also for va_start(), va_end(), va_copy( ) used by log.cc */ | |||
#elif defined(FT_HAVE_CSTDARG) && defined(__cplusplus) | #elif defined(FT_HAVE_CSTDARG) && defined(__cplusplus) | |||
# include <cstdarg> /* for va_list. also for va_start(), va_end(), va_copy( ) used by log.cc */ | # include <cstdarg> /* for va_list. also for va_start(), va_end(), va_copy( ) used by log.cc */ | |||
#endif | #endif | |||
#if defined(FT_HAVE_STDIO_H) | #if defined(FT_HAVE_STDIO_H) | |||
# include <stdio.h> /* for FILE. also for stdout, stderr used by log.cc */ | # include <stdio.h> /* for FILE. also for stdout, stderr, fprintf(), fileno () used by log.cc */ | |||
#elif defined(FT_HAVE_CSTDIO) && defined(__cplusplus) | #elif defined(FT_HAVE_CSTDIO) && defined(__cplusplus) | |||
# include <cstdio> /* for FILE. also for stdout, stderr used by log.cc */ | # include <cstdio> /* for FILE. also for stdout, stderr, fprintf(), fileno () used by log.cc */ | |||
#endif | #endif | |||
#include <list> /* for std::list<T> */ | #include <set> /* for std::set<T> */ | |||
#include <map> /* for std::map<K,V> */ | #include <map> /* for std::map<K,V> */ | |||
#include "mstring.hh" /* ft_mstring */ | ||||
FT_NAMESPACE_BEGIN | FT_NAMESPACE_BEGIN | |||
/** | /** | |||
* note 1.1) | * note 1.1) | |||
* log subsystem is automatically initialized and configured upon first call to | * log subsystem is automatically initialized and configured upon first call to | |||
* ff_log(), ff_vlog(), ff_log_register_range(), ff_log_unregister_range() or ff _log_set_threshold(). | * ff_log(), ff_vlog(), ff_log_register_range(), ff_log_unregister_range() or ff _log_set_threshold(). | |||
* | * | |||
* automatic configuration is: | * automatic configuration is: | |||
* print to stdout all INFO and NOTICE messages, with format FC_FMT_MSG | * print to stdout all INFO and NOTICE messages, with format FC_FMT_MSG | |||
* print to stderr all WARN, ERROR and FATAL messages, with format FC_FMT_MSG | * print to stderr all WARN, ERROR and FATAL messages, with format FC_FMT_MSG | |||
*/ | */ | |||
/* FC_FATAL is reserved for things that should not happen, i.e. bugs in the prog ram or in the operating system. */ | /* FC_FATAL is reserved for things that should not happen, i.e. bugs in the prog ram or in the operating system. */ | |||
enum ft_log_level { FC_LEVEL_NOT_SET, FC_DUMP, FC_TRACE, FC_DEBUG, FC_INFO, FC_N | enum ft_log_level { | |||
OTICE, FC_WARN, FC_ERROR, FC_FATAL }; | FC_LEVEL_NOT_SET = 0, | |||
FC_DUMP, FC_TRACE, FC_DEBUG, FC_INFO, FC_NOTICE, FC_WARN, FC_ERROR, FC_FATAL | ||||
, | ||||
FC_SHOW_DEFAULT_LEVEL = FC_TRACE | ||||
}; | ||||
enum ft_log_fmt { | enum ft_log_fmt { | |||
FC_FMT_MSG, /* message only */ | FC_FMT_MSG, /* message only */ | |||
FC_FMT_LEVEL_MSG, /* level + message */ | FC_FMT_LEVEL_MSG, /* level + message */ | |||
FC_FMT_DATETIME_LEVEL_MSG, /* datetime + level + message */ | FC_FMT_DATETIME_LEVEL_MSG, /* datetime + level + message */ | |||
FC_FMT_DATETIME_LEVEL_CALLER_MSG, /* datetime + level + [file.func(line)] + message */ | FC_FMT_DATETIME_LEVEL_CALLER_MSG, /* datetime + level + [file.func(line)] + message */ | |||
}; | }; | |||
enum ft_log_color { | ||||
FC_COL_AUTO = 0, | ||||
FC_COL_NONE, | ||||
FC_COL_ANSI, | ||||
}; | ||||
/** | /** | |||
* print to log fmt and subsequent printf-style args log stream(s). | * print to log fmt and subsequent printf-style args log stream(s). | |||
* if err != 0, append ": ", strerror(errno) and "\n" | * if err != 0, append ": ", strerror(errno) and "\n" | |||
* else append "\n" | * else append "\n" | |||
* finally return err | * finally return err | |||
*/ | */ | |||
#define ff_log_is_enabled(level) ff_logl_is_enabled(FT_THIS_FILE, level) | #define ff_log_is_enabled(level) ff_logl_is_enabled(FT_THIS_FILE, sizeof( | |||
#define ff_log(level, err, ...) ff_logl(FT_THIS_FILE, FT_THIS_FUNCTION, | FT_THIS_FILE)-1, level) | |||
FT_THIS_LINE, level, err, __VA_ARGS__) | #define ff_log(level, err, ...) ff_logl(FT_THIS_FILE, sizeof(FT_THIS_FIL | |||
#define ff_vlog(level, err, fmt, vargs) ff_logv(FT_THIS_FILE, FT_THIS_FUNCTION, | E)-1, FT_THIS_FUNCTION, FT_THIS_LINE, level, err, __VA_ARGS__) | |||
FT_THIS_LINE, level, err, fmt, vargs) | #define ff_vlog(level, err, fmt, vargs) ff_logv(FT_THIS_FILE, sizeof(FT_THIS_FIL | |||
E)-1, FT_THIS_FUNCTION, FT_THIS_LINE, level, err, fmt, vargs) | ||||
bool ff_logl_is_enabled(const char * caller_file, ft_log_level level); | ||||
int ff_logl(const char * caller_file, const char * caller_func, int caller_line | bool ff_logl_is_enabled(const char * caller_file, int caller_file_len, ft_log_le | |||
, ft_log_level level, int err, const char * fmt, ...); | vel level); | |||
int ff_logv(const char * caller_file, const char * caller_func, int caller_line | int ff_logl(const char * caller_file, int caller_file_len, const char * caller_ | |||
, ft_log_level level, int err, const char * fmt, va_list args); | func, int caller_line, ft_log_level level, int err, const char * fmt, ...); | |||
int ff_logv(const char * caller_file, int caller_file_len, const char * caller_ | ||||
func, int caller_line, ft_log_level level, int err, const char * fmt, va_list ar | ||||
gs); | ||||
const char * ff_log_level_to_string(ft_log_level level); | ||||
#if defined(EINVAL) && EINVAL < 0 | #if defined(EINVAL) && EINVAL < 0 | |||
# define ff_log_is_reported(err) ((err) >= 0) | # define ff_log_is_reported(err) ((err) >= 0) | |||
#else | #else | |||
# define ff_log_is_reported(err) ((err) <= 0) | # define ff_log_is_reported(err) ((err) <= 0) | |||
#endif | #endif | |||
struct ft_log_event | struct ft_log_event | |||
{ | { | |||
const char * str_now, * file, * file_suffix, * function, * fmt; | const char * str_now, * file, * file_suffix, * function, * fmt; | |||
int file_len, line, err; | int file_len, line, err; | |||
ft_log_level level; | ft_log_level level; | |||
va_list vargs; | va_list vargs; | |||
}; | }; | |||
class ft_log_appender; | ||||
typedef std::set<ft_log_appender *> ft_log_appenders; | ||||
typedef ft_log_appenders::iterator ft_log_appenders_iterator; | ||||
typedef ft_log_appenders::const_iterator ft_log_appenders_citerator; | ||||
class ft_log_appender { | class ft_log_appender { | |||
private: | private: | |||
FILE * stream; | FILE * stream; | |||
ft_log_fmt format; | ft_log_fmt format; | |||
ft_log_level min_level, max_level; | ft_log_level min_level, max_level; | |||
ft_log_color color; | ||||
/** destructor. */ | /** destructor. */ | |||
~ft_log_appender(); | ~ft_log_appender(); | |||
/** list of all appenders */ | /** list of all appenders */ | |||
static std::list<ft_log_appender *> & get_all_appenders(); | static ft_log_appenders & get_all_appenders(); | |||
public: | public: | |||
/** constructor. */ | /** constructor. */ | |||
ft_log_appender(FILE * stream, ft_log_fmt format = FC_FMT_MSG, ft_log_level | ft_log_appender(FILE * stream, ft_log_fmt format = FC_FMT_MSG, | |||
min_level = FC_TRACE, ft_log_level max_level = FC_FATAL); | ft_log_level min_level = FC_DUMP, ft_log_level max_level = F | |||
C_FATAL, | ||||
ft_log_color color = FC_COL_AUTO); | ||||
FT_INLINE void set_format(ft_log_fmt format) { this->format = format; } | FT_INLINE void set_format(ft_log_fmt format) { this->format = format; } | |||
FT_INLINE void set_min_level(ft_log_level min_level) { this->min_level = min _level; } | FT_INLINE void set_min_level(ft_log_level min_level) { this->min_level = min _level; } | |||
FT_INLINE void set_max_level(ft_log_level max_level) { this->max_level = max _level; } | FT_INLINE void set_max_level(ft_log_level max_level) { this->max_level = max _level; } | |||
/** write a log message to stream */ | /** write a log message to stream */ | |||
void append(ft_log_event & event); | void append(ft_log_event & event); | |||
/** flush this appender */ | /** flush this appender */ | |||
void flush(); | void flush(); | |||
/** flush all buffered streams used to log messages for specified level */ | /** flush all buffered streams used to log messages for specified level */ | |||
static void flush_all(ft_log_level level); | static void flush_all(ft_log_level level); | |||
/** set format and min/max levels of this appender */ | /** set format, min level and color of this appender */ | |||
void redefine(ft_log_fmt format = FC_FMT_MSG, ft_log_level min_level = FC_DE | void reconfigure(ft_log_fmt format_except_fatal = FC_FMT_MSG, ft_log_level s | |||
BUG, ft_log_level max_level = FC_FATAL); | tdout_min_level = FC_LEVEL_NOT_SET, ft_log_color color = FC_COL_AUTO); | |||
/** set format and min/max levels of all appenders attached to stream */ | /** set format, min level and color of all appenders */ | |||
static void redefine(FILE * stream, ft_log_fmt format = FC_FMT_MSG, ft_log_l | static void reconfigure_all(ft_log_fmt format_except_fatal = FC_FMT_MSG, ft_ | |||
evel min_level = FC_DEBUG, ft_log_level max_level = FC_FATAL); | log_level stdout_min_level = FC_LEVEL_NOT_SET, ft_log_color color = FC_COL_AUTO) | |||
; | ||||
}; | }; | |||
class ft_log; | ||||
typedef std::map<ft_mstring, ft_log *> all_loggers_type; | ||||
typedef all_loggers_type::iterator all_loggers_iterator; | ||||
typedef all_loggers_type::const_iterator all_loggers_citerator; | ||||
class ft_log { | class ft_log { | |||
private: | private: | |||
typedef std::map<ft_string, ft_log *>::iterator all_loggers_iterator; | friend class ft_log_appender; | |||
friend class ft_log_appender; | const ft_mstring * name; | |||
const ft_string * name; | ||||
ft_log * parent; | ft_log * parent; | |||
std::list<ft_log_appender *> appenders; | ft_log_appenders appenders; | |||
ft_log_level level; /* events less severe than level will be suppressed */ | ft_log_level level; /* events less severe than level will be suppressed */ | |||
mutable ft_log_level effective_level, threshold_level; | ||||
/** initialize loggers and appenders. */ | /** initialize loggers and appenders. */ | |||
static void initialize(); | static void initialize(); | |||
/** return map of all existing loggers. */ | /** return map of all existing loggers. */ | |||
static std::map<ft_string, ft_log *> & get_all_loggers(); | static all_loggers_type & get_all_loggers(); | |||
/** constructor. */ | /** constructor. */ | |||
ft_log(const ft_string & name, ft_log * parent, ft_log_level level = FC_LEVE L_NOT_SET); | ft_log(const ft_mstring & name, ft_log * parent, ft_log_level level = FC_LEV EL_NOT_SET); | |||
/** destructor. */ | /** destructor. */ | |||
~ft_log(); | ~ft_log(); | |||
/** find or create parent logger given child name. */ | /** find or create a parent logger given child name. */ | |||
static ft_log & get_parent(const ft_string & child_logger_name); | static ft_log & get_parent(const ft_mstring & child_logger_name); | |||
/** | ||||
* invalidate all cached effective_level and threshold_level. | ||||
* needed after some logger->level is changed. | ||||
*/ | ||||
static void invalidate_all_cached_levels(); | ||||
/** log a message (skip level check) */ | /** log a message (skip threshold_level check) */ | |||
void append(ft_log_event & event); | void append(ft_log_event & event); | |||
public: | public: | |||
/** return root logger */ | /** return root logger */ | |||
static ft_log & get_root_logger(); | static ft_log & get_root_logger(); | |||
/** find or create a logger by name */ | /** find or create a logger by name */ | |||
static ft_log & get_logger(const ft_string & logger_name); | static ft_log & get_logger(const ft_mstring & logger_name); | |||
/** log a message (unless its level is suppressed) */ | /** log a message (unless its level is suppressed) */ | |||
void log(ft_log_event & event); | void log(ft_log_event & event); | |||
/** return true if level is enabled (i.e. not suppressed) for this logger. * / | /** return true if level is enabled (i.e. not suppressed) for this logger. * / | |||
FT_INLINE bool is_enabled(ft_log_level level) const { return level >= get_ef fective_level(); } | FT_INLINE bool is_enabled(ft_log_level level) const { return level >= get_th reshold_level(); } | |||
/** get logger name. */ | /** get logger name. */ | |||
FT_INLINE const ft_string & get_name() const { return * name; } | FT_INLINE const ft_mstring & get_name() const { return * name; } | |||
/** return the level, i.e. least serious level that is not suppressed. */ | /** return the level, i.e. least serious level that is not suppressed. */ | |||
FT_INLINE ft_log_level get_level() const { return level; } | FT_INLINE ft_log_level get_level() const { return level; } | |||
/** set the level, i.e. least serious level that is not suppressed. */ | ||||
FT_INLINE void set_level(ft_log_level level) { this->level = level; } | ||||
/** return the effective level: if level is set return it, otherwise return parent effective level. */ | /** return the effective level: if level is set return it, otherwise return parent effective level. */ | |||
ft_log_level get_effective_level() const; | ft_log_level get_effective_level() const; | |||
/** return the threshold level: the minimum of this and all ancestor's level | ||||
s. */ | ||||
ft_log_level get_threshold_level() const; | ||||
/** set the level, i.e. least serious level that is not suppressed. */ | ||||
FT_INLINE void set_level(ft_log_level level) { this->level = level; invalida | ||||
te_all_cached_levels(); } | ||||
/** add an appender */ | /** add an appender */ | |||
void add_appender(ft_log_appender & appender); | void add_appender(ft_log_appender & appender); | |||
/** remove an appender */ | /** remove an appender */ | |||
void remove_appender(ft_log_appender & appender); | void remove_appender(ft_log_appender & appender); | |||
}; | }; | |||
FT_NAMESPACE_END | FT_NAMESPACE_END | |||
#endif /* FSTRANSFORM_LOG_HH */ | #endif /* FSTRANSFORM_LOG_HH */ | |||
End of changes. 30 change blocks. | ||||
45 lines changed or deleted | 85 lines changed or added |