logger.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <algorithm>
00024 #include <iomanip>
00025 #include <fstream>
00026
00027
00028 #include <SDL.h>
00029
00030
00031
00032
00033
00034
00035 #include "modules.h"
00036 #include "logger.h"
00037 #include "util/base/exception.h"
00038
00039
00040 struct ModuleInfo {
00041 logmodule_t module;
00042 logmodule_t parent;
00043 std::string name;
00044 };
00045 MODULE_INFO_RELATIONSHIPS
00046
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 if(logtofile){
00154 m_logfile = new std::ofstream("fife.log");
00155 }
00156 else {
00157 if (m_logfile){
00158 delete m_logfile;
00159 }
00160 }
00161 m_logtofile = logtofile;
00162 }
00163
00164 bool LogManager::isLoggingToFile() {
00165 return m_logtofile;
00166 }
00167
00168 bool LogManager::isVisible(logmodule_t module) {
00169 if (!m_modules[module]) {
00170 return false;
00171 }
00172 if (moduleInfos[module].parent != LM_CORE) {
00173 return isVisible(moduleInfos[module].parent);
00174 }
00175 return true;
00176 }
00177
00178 LogManager::LogManager():
00179 m_level(LEVEL_DEBUG),
00180 module_check_stack(),
00181 m_logtofile(false),
00182 m_logtoprompt(false) {
00183 validateModuleDescription(LM_CORE);
00184 m_logfile = 0;
00185 clearVisibleModules();
00186 }
00187
00188 void LogManager::validateModule(logmodule_t m) {
00189 if ((m <= LM_CORE) || (m >= LM_MODULE_MAX)) {
00190 std::cout << "Invalid module received in LogManager: " << m << ", aborting\n";
00191 abort();
00192 }
00193 }
00194
00195 void LogManager::validateModuleDescription(logmodule_t module) {
00196 if (module == LM_CORE) {
00197 for (int m = static_cast<int>(LM_CORE)+1; m < static_cast<int>(LM_MODULE_MAX); m++) {
00198 if (moduleInfos[m].module != static_cast<logmodule_t>(m)) {
00199 std::ostringstream stream;
00200 stream << m;
00201 std::string msg = "Log module definition ids do not match in index ";
00202 msg += stream.str();
00203 std::cout << msg << std::endl;
00204 throw InvalidFormat(msg);
00205 }
00206 module_check_stack.clear();
00207 validateModuleDescription(static_cast<logmodule_t>(m));
00208 }
00209 } else {
00210 module_check_stack.push_back(module);
00211 if (count(module_check_stack.begin(), module_check_stack.end(), module) > 1) {
00212 throw InvalidFormat("Log module definition hierachy contains cycles");
00213 }
00214 }
00215 }
00216
00217 std::string LogManager::getModuleName(logmodule_t module) {
00218 return moduleInfos[module].name;
00219 }
00220 }