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 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 }