--- scribo/ChangeLog | 4 + scribo/scribo/debug/logger.hh | 249 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 250 insertions(+), 3 deletions(-) diff --git a/scribo/ChangeLog b/scribo/ChangeLog index 69814de..1122e11 100644 --- a/scribo/ChangeLog +++ b/scribo/ChangeLog @@ -1,3 +1,7 @@ +2012-05-07 Guillaume Lazzara <z@lrde.epita.fr> + + * scribo/debug/logger.hh: Improve log system. + 2012-04-05 Guillaume Lazzara <z@lrde.epita.fr> Remove useless targets in scribo/src/binarization. diff --git a/scribo/scribo/debug/logger.hh b/scribo/scribo/debug/logger.hh index f16dd89..5822cf3 100644 --- a/scribo/scribo/debug/logger.hh +++ b/scribo/scribo/debug/logger.hh @@ -1,4 +1,4 @@ -// Copyright (C) 2011 EPITA Research and Development Laboratory +// Copyright (C) 2011, 2012 EPITA Research and Development Laboratory // (LRDE) // // This file is part of Olena. @@ -27,6 +27,8 @@ #ifndef SCRIBO_CORE_LOGGER_HH # define SCRIBO_CORE_LOGGER_HH +# include <iostream> +# include <ctype.h> # include <mln/core/concept/image.hh> # include <mln/data/wrap.hh> # include <mln/value/int_u8.hh> @@ -34,6 +36,7 @@ # include <mln/io/pbm/save.hh> # include <mln/io/pgm/save.hh> # include <mln/io/ppm/save.hh> +# include <mln/util/timer.hh> namespace scribo { @@ -41,15 +44,48 @@ namespace scribo namespace debug { + /*! \brief Enum defining different level of image logging + + According to the debug level set in #logger_ the image may + be saved or not. + */ enum Level { None = 0, Special, // Reserved Results, AuxiliaryResults, - All + All, + InvalidLevel // Reserved }; + /*! \brief Enum defining different modes of text logging + + According to the verbose mode set in #logger_ the text may + be logged or not. + */ + enum VerboseMode + { + Mute = 0, + UserDebug, // Reserved + Time, + Low, + Medium, + Full, + Invalid, // Reserved + }; + + + /*! \brief returns the corresponding verboseMode from its name. + + \internal + \warning Don't forget to update this function if a VerboseMode + value is added. + \endinternal + */ + VerboseMode txt_to_verbose_mode(const std::string& name); + + namespace internal { @@ -60,6 +96,22 @@ namespace scribo public: static logger_& instance(); + /// Text Logging + /// @{ + bool is_verbose() const; + bool is_at_verbose_mode(VerboseMode mode) const; + + bool set_verbose_mode(VerboseMode mode); + VerboseMode verbose_mode() const; + + void set_verbose_prefix(const std::string& prefix); + + void log(VerboseMode mode, const std::string& text); + /// @} + + + /// Image Logging + /// @{ bool is_enabled() const; bool is_at_level(Level level) const; @@ -72,6 +124,37 @@ namespace scribo template <typename I> void log_image(Level dbg_level, const Image<I>& ima, const char *name); + /// @} + + /*! \brief Time Logging + + This class provides two timers in order to performs + benchmarks inside a program. + + Local time logging is meant to be used for benchmarking a + small portion of code, whereas global time logging is meant + to benchmark a whole program. + + They can be used both at the same time. + + Stopping time logging will output the computed time if + Verbose mode is higher or equal to #Time. + */ + /// @{ + void start_local_time_logging(); + void stop_local_time_logging(const std::string& time_title); + + void start_global_time_logging(); + void stop_global_time_logging(const std::string& time_title); + /// @} + + + /*! \brief Quickly logs text. + It uses the default log mode to know if the text + */ + template <typename V> + logger_& operator<<(const V&v); + logger_& operator<<(std::ostream& (*f)(std::ostream&)); private: // Methods logger_(); @@ -110,6 +193,12 @@ namespace scribo private: // Attributes Level level_; + VerboseMode verbose_mode_; + std::string verbose_prefix_; + std::ostream& stream_; + + mln::util::timer t_local_; + mln::util::timer t_global_; }; } // end of namespace scribo::debug::internal @@ -124,6 +213,14 @@ namespace scribo namespace internal { + std::string to_upper(const std::string& s) + { + std::string out(s); + for (size_t i = 0; i < s.size(); ++i) + out[i] = toupper(s[i]); + return out; + } + inline logger_& logger_::instance() @@ -135,7 +232,10 @@ namespace scribo inline logger_::logger_() - : level_(None) + : level_(None), + verbose_mode_(Mute), + stream_(std::cerr), + verbose_prefix_("LOG: ") { // Magick::InitializeMagick(0); } @@ -143,6 +243,7 @@ namespace scribo inline logger_::logger_(const logger_&) + : stream_(std::cerr) { abort(); } @@ -150,6 +251,64 @@ namespace scribo inline bool + logger_::is_verbose() const + { + return verbose_mode_ > Mute; + } + + + inline + bool + logger_::is_at_verbose_mode(VerboseMode mode) const + { + return mode == verbose_mode_; + } + + + inline + bool + logger_::set_verbose_mode(VerboseMode mode) + { + if (mode != Invalid) + { + verbose_mode_ = mode; + return true; + } + return false; + } + + + inline + VerboseMode + logger_::verbose_mode() const + { + return verbose_mode_; + } + + + inline + void + logger_::set_verbose_prefix(const std::string& prefix) + { + verbose_prefix_ = prefix; + } + + + inline + void + logger_::log(VerboseMode mode, const std::string& text) + { +# ifndef SCRIBO_NDEBUG + if (verbose_mode_ < mode) + return; + + std::cerr << verbose_prefix_ << text << std::endl; +# endif // ! SCRIBO_NDEBUG + } + + + inline + bool logger_::is_enabled() const { return level_ != None; @@ -212,6 +371,44 @@ namespace scribo } + inline + void + logger_::start_local_time_logging() + { + t_local_.restart(); + } + + + inline + void + logger_::stop_local_time_logging(const std::string& time_title) + { + t_local_.stop(); + if (verbose_mode_ >= Time) + std::cerr << time_title << " " << t_local_ << "s" << std::endl; + } + + + inline + void + logger_::start_global_time_logging() + { + t_global_.restart(); + } + + + inline + void + logger_::stop_global_time_logging(const std::string& time_title) + { + t_global_.stop(); + if (verbose_mode_ >= Time) + std::cerr << time_title << " " << t_global_ << "s" << std::endl; + } + + + // Private dispatch + template <unsigned n, typename I> void logger_::log_image_dispatch(const value::int_u<n>&, const Image<I>& ima, const char *name) @@ -273,6 +470,26 @@ namespace scribo mln::debug::filename(name + ".pgm")); } + + template <typename V> + logger_& + logger_::operator<<(const V& v) + { + if (verbose_mode_ >= Low) + stream_ << v; + return *this; + } + + + logger_& + logger_::operator<<(std::ostream& (*f)(std::ostream&)) + { + if (verbose_mode_ >= Low) + f(stream_); + return *this; + } + + } // end of namespace scribo::debug::internal @@ -284,6 +501,32 @@ namespace scribo } + VerboseMode txt_to_verbose_mode(const std::string& name) + { + struct mode_name + { + const char *name; + VerboseMode mode; + }; + static const mode_name mode[] = { + { "MUTE", Mute }, + { "USERDEBUG", UserDebug }, + { "TIME", Time }, + { "LOW", Low }, + { "MEDIUM", Medium }, + { "FULL", Full }, + { "INVALID", Invalid } + }; + + unsigned i; + std::string name_ = internal::to_upper(name); + for (i = 0; mode[i].mode != Invalid; ++i) + if (mode[i].name == name_) + break; + + return mode[i].mode; + }; + # endif // ! MLN_INCLUDE_ONLY } // end of namespace scribo::debug -- 1.7.2.5