logger.h

00001 /***************************************************************************
00002  *   Copyright (C) 2005-2008 by the FIFE team                              *
00003  *   http://www.fifengine.de                                               *
00004  *   This file is part of FIFE.                                            *
00005  *                                                                         *
00006  *   FIFE is free software; you can redistribute it and/or                 *
00007  *   modify it under the terms of the GNU Lesser General Public            *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2.1 of the License, or (at your option) any later version.    *
00010  *                                                                         *
00011  *   This library is distributed in the hope that it will be useful,       *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00014  *   Lesser General Public License for more details.                       *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Lesser General Public      *
00017  *   License along with this library; if not, write to the                 *
00018  *   Free Software Foundation, Inc.,                                       *
00019  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
00020  ***************************************************************************/
00021 
00022 #ifndef FIFE_LOGGER_H
00023 #define FIFE_LOGGER_H
00024 
00025 // Standard C++ library includes
00026 #include <iomanip>
00027 #include <iostream>
00028 #include <list>
00029 #include <sstream>
00030 #include <string>
00031 #include <vector>
00032 #include <map>
00033 #include <set>
00034 
00035 // 3rd party library includes
00036 
00037 // FIFE includes
00038 // These includes are split up in two parts, separated by one empty line
00039 // First block: files included from the FIFE root src directory
00040 // Second block: files included from the same folder
00041 #include "util/base/fife_stdint.h"
00042 
00043 #include "modules.h"
00044 
00045 #ifdef LOG_ENABLED
00046 
00049 #define FL_DBG(logger, msg) do { if (FIFE::LogManager::instance()->isVisible(logger.getModule())) logger.log(FIFE::LogManager::LEVEL_DEBUG, msg); } while(0)
00050 
00053 #define FL_LOG(logger, msg) do { if (FIFE::LogManager::instance()->isVisible(logger.getModule())) logger.log(FIFE::LogManager::LEVEL_LOG, msg); } while(0)
00054 
00057 #define FL_WARN(logger, msg) do { if (FIFE::LogManager::instance()->isVisible(logger.getModule())) logger.log(FIFE::LogManager::LEVEL_WARN, msg); } while(0)
00058 
00061 #define FL_ERR(logger, msg) do { if (FIFE::LogManager::instance()->isVisible(logger.getModule())) logger.log(FIFE::LogManager::LEVEL_ERROR, msg); } while(0)
00062 
00066 #define FL_PANIC(logger, msg) do { if (FIFE::LogManager::instance()->isVisible(logger.getModule())) logger.log(FIFE::LogManager::LEVEL_PANIC, msg); } while(0)
00067 
00068 #else
00069 // empty definitions in case logs are turned off for speed
00070 #define FL_DBG(logger, msg)
00071 #define FL_LOG(logger, msg)
00072 #define FL_WARN(logger, msg)
00073 #define FL_ERR(logger, msg)
00074 #define FL_PANIC(logger, msg)
00075 #endif
00076 
00077 namespace FIFE {
00078 
00082     class LMsg {
00083     public:
00084         LMsg(const std::string& msg=""): str(msg) {}
00085         ~LMsg() {}
00086 
00087         template <typename T> LMsg& operator<<(const T& t) {
00088             std::ostringstream stream;
00089             stream << t;
00090             str += stream.str();
00091             return *this;
00092         }
00093 
00094         std::string str;
00095     };
00096 
00099     class LogManager {
00100     public:
00105         enum LogLevel {
00106             LEVEL_DEBUG = 0,
00107             LEVEL_LOG   = 1,
00108             LEVEL_WARN  = 2,
00109             LEVEL_ERROR = 3,
00110             LEVEL_PANIC = 4
00111         };
00112 
00115         static LogManager* instance();
00116 
00119         ~LogManager();
00120 
00127         void log(LogLevel level, logmodule_t module, const std::string& msg);
00128 
00132         void setLevelFilter(LogLevel level);
00133 
00137         LogLevel getLevelFilter();
00138 
00147         void addVisibleModule(logmodule_t module);
00148 
00151         void removeVisibleModule(logmodule_t module);
00152 
00155         void clearVisibleModules();
00156 
00159         bool isVisible(logmodule_t module);
00160 
00163         void setLogToPrompt(bool log_to_promt);
00164 
00167         bool isLoggingToPrompt();
00168 
00171         void setLogToFile(bool logtofile);
00172 
00175         bool isLoggingToFile();
00176 
00180         std::string getModuleName(logmodule_t module);
00181 
00182     private:
00183         void validateModule(logmodule_t m);
00184 
00185         // hidden constructor for singleton
00186         LogManager();
00187         // validates if definitions in module.h are valid
00188         void validateModuleDescription(logmodule_t module);
00189 
00190         // singleton instance
00191         static LogManager* m_instance;
00192         // current filter level
00193         LogLevel m_level;
00194         // visibility array for modules
00195         bool m_modules[LM_MODULE_MAX];
00196         // used during module description validation to check cycles in hierarchy
00197         std::vector<logmodule_t> module_check_stack;
00198 
00199         bool m_logtofile;
00200         bool m_logtoprompt;
00201 
00202         std::ofstream* m_logfile;
00203     };
00204 
00211     class Logger {
00212     public:
00215         Logger(logmodule_t module);
00216 
00219         ~Logger();
00220 
00223         void log(LogManager::LogLevel level, const std::string& msg);
00224 
00228         void log(LogManager::LogLevel level, const LMsg& msg);
00229 
00232         inline logmodule_t getModule() const { return m_module; }
00233 
00234     private:
00235         logmodule_t m_module;
00236     };
00237 
00247     struct pprint {
00248         void* p;
00249         pprint( void* _p ) : p(_p) {}
00250     };
00251 }
00252 
00253 namespace std {
00263     template <class Ch, class Tr>
00264     basic_ostream<Ch,Tr>& operator<<( basic_ostream<Ch,Tr>& s, const FIFE::pprint& p ) {
00265         s << "0x"
00266             << hex << setw( 2*sizeof(void*) ) << setfill('0')
00267             << reinterpret_cast<uint64_t>( p.p );
00268 
00269         return s;
00270     }
00271 }
00272 
00273 
00274 #endif