/src/dlib/logger/logger_kernel_1.h
C Header | 476 lines | 286 code | 76 blank | 114 comment | 13 complexity | f945135888c6f4e0886cd30452ecf7b8 MD5 | raw file
- // Copyright (C) 2006 Davis E. King (davisking@users.sourceforge.net)
- // License: Boost Software License See LICENSE.txt for the full license.
- #ifndef DLIB_LOGGER_KERNEl_1_
- #define DLIB_LOGGER_KERNEl_1_
-
- #include "../threads.h"
- #include "../misc_api.h"
- #include "../set.h"
- #include "logger_kernel_abstract.h"
- #include <limits>
- #include <cstring>
- #include "../algs.h"
- #include "../assert.h"
- #include "../uintn.h"
- #include "../map.h"
- #include "../smart_pointers.h"
-
- namespace dlib
- {
-
- // ----------------------------------------------------------------------------------------
-
- class log_level
- {
- public:
- log_level(
- int priority_,
- const char* name_
- ) :
- priority(priority_)
- {
- strncpy(name,name_,19);
- name[19] = '\0';
- }
-
- int priority;
- char name[20];
- };
-
- const log_level LALL (std::numeric_limits<int>::min(),"ALL");
- const log_level LNONE (std::numeric_limits<int>::max(),"NONE");
- const log_level LTRACE(-100,"TRACE");
- const log_level LDEBUG(0 ,"DEBUG");
- const log_level LINFO (100,"INFO ");
- const log_level LWARN (200,"WARN ");
- const log_level LERROR(300,"ERROR");
- const log_level LFATAL(400,"FATAL");
-
- // ----------------------------------------------------------------------------------------
-
- void set_all_logging_output_streams (
- std::ostream& out
- );
-
- void set_all_logging_levels (
- const log_level& new_level
- );
-
- // ----------------------------------------------------------------------------------------
-
- void print_default_logger_header (
- std::ostream& out,
- const std::string& logger_name,
- const log_level& l,
- const uint64 thread_id
- );
-
- // ----------------------------------------------------------------------------------------
-
- class logger
- {
- /*!
- INITIAL VALUE
- - print_header == print_default_logger_header
- - out.rdbuf() == std::cout.rdbuf()
- - cur_level == LERROR
- - auto_flush_enabled == true
-
- CONVENTION
- - print_header == logger_header()
- - out.rdbuf() == output_streambuf()
- - cur_level == level()
- - logger_name == name()
- - auto_flush_enabled == auto_flush()
-
- - logger::gd::loggers == a set containing all currently existing loggers.
- - logger::gd::m == the mutex used to lock everything in the logger
- - logger::gd::thread_names == a map of thread ids to thread names.
- - logger::gd::next_thread_name == the next thread name that will be given out
- to a thread when we find that it isn't already in thread_names.
- !*/
-
- class logger_stream
- {
- /*!
- INITIAL VALUE
- - been_used == false
-
- CONVENTION
- - enabled == is_enabled()
- - if (been_used) then
- - logger::gd::m is locked
- - someone has used the << operator to write something to the
- output stream.
- !*/
- public:
- logger_stream (
- const log_level& l_,
- logger& log_
- ) :
- l(l_),
- log(log_),
- been_used(false),
- enabled (l.priority >= log.cur_level.priority)
- {}
-
- inline ~logger_stream(
- )
- {
- if (!been_used)
- {
- return;
- }
- else
- {
- print_end_of_line();
- }
- }
-
- bool is_enabled (
- ) const { return enabled; }
-
- template <typename T>
- inline logger_stream& operator << (
- const T& item
- )
- {
- if (!enabled)
- {
- return *this;
- }
- else
- {
- print_header_and_stuff();
- log.out << item;
- return *this;
- }
- }
-
- private:
-
- void print_header_and_stuff (
- );
- /*!
- ensures
- - if (!been_used) then
- - prints the logger header
- - locks log.gd.m
- - #been_used == true
- !*/
-
- void print_end_of_line (
- );
- /*!
- ensures
- - prints a newline to log.out
- - unlocks log.gd.m
- !*/
-
- const log_level& l;
- logger& log;
- bool been_used;
- const bool enabled;
- };
-
- friend class logger_stream;
- public:
-
- logger (
- const char* name_
- );
-
- virtual ~logger (
- );
-
- const std::string& name (
- ) const { return logger_name; }
-
- logger_stream operator << (
- const log_level& l
- ) const { return logger_stream(l,const_cast<logger&>(*this)); }
-
- bool is_child_of (
- const logger& log
- ) const
- {
- return (name().find(log.name() + ".") == 0) || (log.name() == name());
- }
-
- const log_level level (
- ) const
- {
- auto_mutex M(gd.m);
- return log_level(cur_level);
- };
-
- void set_level (
- const log_level& new_level
- )
- {
- auto_mutex M(gd.m);
- gd.loggers.reset();
- while (gd.loggers.move_next())
- {
- if (gd.loggers.element()->is_child_of(*this))
- gd.loggers.element()->cur_level = new_level;
- }
-
- gd.set_level(logger_name, new_level);
- }
-
- bool auto_flush (
- ) const
- {
- auto_mutex M(gd.m);
- return auto_flush_enabled;
- };
-
- void set_auto_flush (
- bool enabled
- )
- {
- auto_mutex M(gd.m);
- gd.loggers.reset();
- while (gd.loggers.move_next())
- {
- if (gd.loggers.element()->is_child_of(*this))
- gd.loggers.element()->auto_flush_enabled = enabled;
- }
-
- gd.set_auto_flush(logger_name, enabled);
- }
-
- std::streambuf* output_streambuf (
- )
- {
- auto_mutex M(gd.m);
- return out.rdbuf();
- }
-
- void set_output_stream (
- std::ostream& out_
- )
- {
- auto_mutex M(gd.m);
- gd.loggers.reset();
- while (gd.loggers.move_next())
- {
- if (gd.loggers.element()->is_child_of(*this))
- gd.loggers.element()->out.rdbuf(out_.rdbuf());
- }
-
- gd.set_output_stream(logger_name, out_);
- }
-
- typedef void (*print_header_type)(
- std::ostream& out,
- const std::string& logger_name,
- const log_level& l,
- const uint64 thread_id
- );
-
- print_header_type logger_header (
- ) const { return print_header; }
-
- void set_logger_header (
- print_header_type ph
- )
- {
- auto_mutex M(gd.m);
- gd.loggers.reset();
- while (gd.loggers.move_next())
- {
- if (gd.loggers.element()->is_child_of(*this))
- gd.loggers.element()->print_header = ph;
- }
-
- gd.set_logger_header(logger_name, ph);
- }
-
- private:
-
-
- struct global_data
- {
- rmutex m;
- set<logger*>::kernel_1b loggers;
- map<thread_id_type,uint64>::kernel_1b thread_names;
- uint64 next_thread_name;
-
- global_data (
- );
-
- ~global_data(
- );
-
- uint64 get_thread_name (
- );
- /*!
- requires
- - m is locked
- ensures
- - returns a unique id for the calling thread. also makes the number
- small and nice unlike what you get from get_thread_id()
- !*/
-
- void thread_end_handler (
- );
- /*!
- ensures
- - removes the terminated thread from thread_names
- !*/
-
- struct level_container
- {
- level_container ();
-
- log_level val;
- map<std::string,scoped_ptr<level_container> >::kernel_1b_c table;
- } level_table;
-
- const log_level level (
- const std::string& name
- ) const;
- /*!
- ensures
- - returns the level loggers with the given name are supposed
- to have
- !*/
-
- void set_level (
- const std::string& name,
- const log_level& new_level
- );
- /*!
- ensures
- - for all children C of name:
- - #level(C) == new_level
- - if name == "" then
- - for all loggers L:
- - #level(L) == new_level
- !*/
-
- struct auto_flush_container
- {
- bool val;
- map<std::string,scoped_ptr<auto_flush_container> >::kernel_1b_c table;
- } auto_flush_table;
-
- bool auto_flush (
- const std::string& name
- ) const;
- /*!
- ensures
- - returns the auto_flush value loggers with the given name are supposed
- to have
- !*/
-
- void set_auto_flush (
- const std::string& name,
- bool enabled
- );
- /*!
- ensures
- - for all children C of name:
- - #auto_flush_enabled(C) == enabled
- - if name == "" then
- - for all loggers L:
- - #auto_flush_enabled(L) == enabled
- !*/
-
- struct output_streambuf_container
- {
- std::streambuf* val;
- map<std::string,scoped_ptr<output_streambuf_container> >::kernel_1b_c table;
- } streambuf_table;
-
- std::streambuf* output_streambuf (
- const std::string& name
- );
- /*!
- ensures
- - returns the streambuf loggers with the given name are supposed
- to have
- !*/
-
- void set_output_stream (
- const std::string& name,
- std::ostream& out_
- );
- /*!
- ensures
- - for all children C of name:
- - #output_streambuf(C) == out_.rdbuf()
- - if name == "" then
- - for all loggers L:
- - #output_streambuf(L) == out_.rdbuf()
- !*/
-
- struct logger_header_container
- {
- print_header_type val;
- map<std::string,scoped_ptr<logger_header_container> >::kernel_1b_c table;
- } header_table;
-
- print_header_type logger_header (
- const std::string& name
- );
- /*!
- ensures
- - returns the header function loggers with the given name are supposed
- to have
- !*/
-
- void set_logger_header (
- const std::string& name,
- print_header_type ph
- );
- /*!
- ensures
- - for all children C of name:
- - #logger_header(C) == ph
- - if name == "" then
- - for all loggers L:
- - #logger_header(L) == ph
- !*/
-
- }; // end of struct global_data
-
- static global_data& get_global_data();
-
- friend void set_all_logging_levels (
- const log_level& new_level
- );
-
- friend void set_all_logging_output_streams (
- std::ostream& out
- );
-
-
- global_data& gd;
-
- const std::string logger_name;
-
- print_header_type print_header;
- bool auto_flush_enabled;
- std::ostream out;
- log_level cur_level;
-
-
- // restricted functions
- logger(const logger&); // copy constructor
- logger& operator=(const logger&); // assignment operator
-
- };
-
- // ----------------------------------------------------------------------------------------
-
- }
-
- #ifdef NO_MAKEFILE
- #include "logger_kernel_1.cpp"
- #endif
-
- #endif // DLIB_LOGGER_KERNEl_1_
-