logger.cpp

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 // Standard C++ library includes
00023 #include <algorithm>
00024 #include <iomanip>
00025 #include <fstream>
00026 
00027 // 3rd party library includes
00028 #include <SDL.h>
00029 
00030 // FIFE includes
00031 // These includes are split up in two parts, separated by one empty line
00032 // First block: files included from the FIFE root src directory
00033 // Second block: files included from the same folder
00034 // #include "guichan_addon/console.h"
00035 #include "modules.h"
00036 #include "logger.h"
00037 #include "util/base/exception.h"
00038 
00039 // define the module info relationships structure here, begin
00040 struct ModuleInfo {
00041     logmodule_t module;
00042     logmodule_t parent;
00043     std::string name;
00044 };
00045 MODULE_INFO_RELATIONSHIPS
00046 // end
00047 
00048 namespace FIFE {
00049     LogManager* LogManager::m_instance = NULL;
00050 
00051     Logger::Logger(logmodule_t module):
00052         m_module(module) {
00053     }
00054     
00055     Logger::~Logger() {
00056     }
00057     
00058     void Logger::log(LogManager::LogLevel level, const std::string& msg) {
00059         LogManager::instance()->log(level, m_module, msg);
00060     }
00061     
00062     void Logger::log(LogManager::LogLevel level, const LMsg& msg) {
00063         LogManager::instance()->log(level, m_module, msg.str);
00064     }
00065     
00066     LogManager* LogManager::instance() {
00067         if (!m_instance) {
00068             m_instance = new LogManager();
00069         }
00070         return m_instance;
00071     }
00072     
00073     LogManager::~LogManager() {
00074         delete m_instance;
00075     }
00076     
00077     
00078     void LogManager::log(LogLevel level, logmodule_t module, const std::string& msg) {
00079         if (level < m_level) {
00080             return;
00081         }
00082         if (!isVisible(module)) {
00083             return;
00084         }
00085         std::string lvlstr = "";
00086         switch (level) {
00087             case LEVEL_DEBUG: lvlstr = "dbg";
00088             break;
00089             
00090             case LEVEL_LOG: lvlstr = "log";
00091             break;
00092             
00093             case LEVEL_WARN: lvlstr = "warn";
00094             break;
00095             
00096             case LEVEL_ERROR: lvlstr = "error";
00097             break;
00098             
00099             case LEVEL_PANIC: lvlstr = "panic";
00100             break;
00101             
00102             default: lvlstr = "error";
00103             break;
00104         }
00105         if (m_logtoprompt) {
00106             std::cout << moduleInfos[module].name << ": " << lvlstr << ": " << msg << std::endl;
00107         }
00108         if (m_logtofile) {
00109             *m_logfile << moduleInfos[module].name << ": " << lvlstr << ": " << msg << std::endl;
00110         }
00111         if (level == LEVEL_PANIC) {
00112             abort();
00113         }
00114     }
00115     
00116     void LogManager::setLevelFilter(LogLevel level) {
00117         m_level = level;
00118     }
00119     
00120     LogManager::LogLevel LogManager::getLevelFilter() {
00121         return m_level;
00122     }
00123 
00124     void LogManager::addVisibleModule(logmodule_t module) {
00125         validateModule(module);
00126         int ind = static_cast<int>(module);
00127         m_modules[ind] = true;
00128         if (moduleInfos[ind].parent != LM_CORE) {
00129             addVisibleModule(moduleInfos[ind].parent);
00130         }
00131     }
00132     
00133     void LogManager::removeVisibleModule(logmodule_t module) {
00134         validateModule(module);
00135         m_modules[module] = false;
00136     }
00137     
00138     void LogManager::clearVisibleModules() {
00139         for (int i = 0; i < LM_MODULE_MAX; i++) {
00140             m_modules[i] = false;
00141         }
00142     }
00143 
00144     void LogManager::setLogToPrompt(bool log_to_promt) {
00145         m_logtoprompt = log_to_promt;
00146     }
00147     
00148     bool LogManager::isLoggingToPrompt() {
00149         return m_logtoprompt;
00150     }
00151     
00152     void LogManager::setLogToFile(bool logtofile) {
00153         m_logtofile = logtofile;
00154     }
00155     
00156     bool LogManager::isLoggingToFile() {
00157         return m_logtofile;
00158     }
00159     
00160     bool LogManager::isVisible(logmodule_t module) {
00161         if (!m_modules[module]) {
00162             return false;
00163         }
00164         if (moduleInfos[module].parent != LM_CORE) {
00165             return isVisible(moduleInfos[module].parent);
00166         }
00167         return true;
00168     }
00169         
00170     LogManager::LogManager():
00171         m_level(LEVEL_DEBUG),
00172         module_check_stack(),
00173         m_logtofile(false),
00174         m_logtoprompt(false) {
00175         validateModuleDescription(LM_CORE);
00176         m_logfile = new std::ofstream("fife.log");
00177         clearVisibleModules();
00178     }
00179     
00180     void LogManager::validateModule(logmodule_t m) {
00181         if ((m <= LM_CORE) || (m >= LM_MODULE_MAX)) {
00182             std::cout << "Invalid module received in LogManager: " << m << ", aborting\n";
00183             abort();
00184         }
00185     }
00186     
00187     void LogManager::validateModuleDescription(logmodule_t module) {
00188         if (module == LM_CORE) {
00189             for (int m = static_cast<int>(LM_CORE)+1; m < static_cast<int>(LM_MODULE_MAX); m++) {
00190                 if (moduleInfos[m].module != static_cast<logmodule_t>(m)) {
00191                     std::ostringstream stream;
00192                     stream << m;
00193                     std::string msg = "Log module definition ids do not match in index ";
00194                     msg += stream.str();
00195                     std::cout << msg << std::endl;
00196                     throw InvalidFormat(msg);
00197                 }
00198                 module_check_stack.clear();
00199                 validateModuleDescription(static_cast<logmodule_t>(m));
00200             }
00201         } else {
00202             module_check_stack.push_back(module);
00203             if (count(module_check_stack.begin(), module_check_stack.end(), module) > 1) {
00204                 throw InvalidFormat("Log module definition hierachy contains cycles");
00205             }
00206         }
00207     }
00208     
00209     std::string LogManager::getModuleName(logmodule_t module) {
00210         return moduleInfos[module].name;
00211     }
00212 }
Generated by  doxygen 1.6.2-20100208