FIFE  2008.0
 All Classes Namespaces Functions Variables Enumerations Enumerator Pages
logger.cpp
1 /***************************************************************************
2  * Copyright (C) 2005-2008 by the FIFE team *
3  * http://www.fifengine.de *
4  * This file is part of FIFE. *
5  * *
6  * FIFE is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU Lesser General Public *
8  * License as published by the Free Software Foundation; either *
9  * version 2.1 of the License, or (at your option) any later version. *
10  * *
11  * This library is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14  * Lesser General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU Lesser General Public *
17  * License along with this library; if not, write to the *
18  * Free Software Foundation, Inc., *
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
20  ***************************************************************************/
21 
22 // Standard C++ library includes
23 #include <algorithm>
24 #include <iomanip>
25 #include <fstream>
26 
27 // 3rd party library includes
28 #include <SDL.h>
29 
30 // FIFE includes
31 // These includes are split up in two parts, separated by one empty line
32 // First block: files included from the FIFE root src directory
33 // Second block: files included from the same folder
34 #include "modules.h"
35 #include "logger.h"
36 #include "util/base/exception.h"
37 
38 // define the module info relationships structure here, begin
39 struct ModuleInfo {
40  logmodule_t module;
41  logmodule_t parent;
42  std::string name;
43 };
44 MODULE_INFO_RELATIONSHIPS
45 // end
46 
47 namespace FIFE {
48  LogManager* LogManager::m_instance = NULL;
49 
50  Logger::Logger(logmodule_t module):
51  m_module(module) {
52  }
53 
55  }
56 
57  void Logger::log(LogManager::LogLevel level, const std::string& msg) {
58  LogManager::instance()->log(level, m_module, msg);
59  }
60 
61  void Logger::log(LogManager::LogLevel level, const LMsg& msg) {
62  LogManager::instance()->log(level, m_module, msg.str);
63  }
64 
66  if (!m_instance) {
67  m_instance = new LogManager();
68  }
69  return m_instance;
70  }
71 
73  delete m_instance;
74  }
75 
76 
77  void LogManager::log(LogLevel level, logmodule_t module, const std::string& msg) {
78  if (level < m_level) {
79  return;
80  }
81  if (!isVisible(module)) {
82  return;
83  }
84  std::string lvlstr = "";
85  switch (level) {
86  case LEVEL_DEBUG: lvlstr = "DEBUG";
87  break;
88 
89  case LEVEL_LOG: lvlstr = "LOG";
90  break;
91 
92  case LEVEL_WARN: lvlstr = "WARN";
93  break;
94 
95  case LEVEL_ERROR: lvlstr = "ERROR";
96  break;
97 
98  case LEVEL_PANIC: lvlstr = "PANIC";
99  break;
100 
101  default: lvlstr = "ERROR";
102  break;
103  }
104  if (m_logtoprompt) {
105  std::cout << moduleInfos[module].name << ":" << lvlstr << ":" << msg << std::endl;
106  }
107  if (m_logtofile) {
108  *m_logfile << moduleInfos[module].name << ":" << lvlstr << ":" << msg << std::endl;
109  }
110  if (level == LEVEL_PANIC) {
111  abort();
112  }
113  }
114 
116  m_level = level;
117  }
118 
120  return m_level;
121  }
122 
123  void LogManager::addVisibleModule(logmodule_t module) {
124  validateModule(module);
125  int32_t ind = static_cast<int32_t>(module);
126  m_modules[ind] = true;
127  if (moduleInfos[ind].parent != LM_CORE) {
128  addVisibleModule(moduleInfos[ind].parent);
129  }
130  }
131 
132  void LogManager::removeVisibleModule(logmodule_t module) {
133  validateModule(module);
134  m_modules[module] = false;
135  }
136 
138  for (int32_t i = 0; i < LM_MODULE_MAX; i++) {
139  m_modules[i] = false;
140  }
141  }
142 
143  void LogManager::setLogToPrompt(bool log_to_promt) {
144  m_logtoprompt = log_to_promt;
145  }
146 
148  return m_logtoprompt;
149  }
150 
151  void LogManager::setLogToFile(bool logtofile) {
152  if(logtofile){
153  m_logfile = new std::ofstream("fife.log");
154  }
155  else {
156  if (m_logfile){
157  delete m_logfile;
158  }
159  }
160  m_logtofile = logtofile;
161  }
162 
164  return m_logtofile;
165  }
166 
167  bool LogManager::isVisible(logmodule_t module) {
168  if (!m_modules[module]) {
169  return false;
170  }
171  if (moduleInfos[module].parent != LM_CORE) {
172  return isVisible(moduleInfos[module].parent);
173  }
174  return true;
175  }
176 
177  LogManager::LogManager():
178  m_level(LEVEL_DEBUG),
179  module_check_stack(),
180  m_logtofile(false),
181  m_logtoprompt(false) {
182  validateModuleDescription(LM_CORE);
183  m_logfile = 0;
185  }
186 
187  void LogManager::validateModule(logmodule_t m) {
188  if ((m <= LM_CORE) || (m >= LM_MODULE_MAX)) {
189  std::cout << "Invalid module received in LogManager: " << m << ", aborting\n";
190  abort();
191  }
192  }
193 
194  void LogManager::validateModuleDescription(logmodule_t module) {
195  if (module == LM_CORE) {
196  for (int32_t m = static_cast<int32_t>(LM_CORE)+1; m < static_cast<int32_t>(LM_MODULE_MAX); m++) {
197  if (moduleInfos[m].module != static_cast<logmodule_t>(m)) {
198  std::ostringstream stream;
199  stream << m;
200  std::string msg = "Log module definition ids do not match in index ";
201  msg += stream.str();
202  std::cout << msg << std::endl;
203  throw InvalidFormat(msg);
204  }
205  module_check_stack.clear();
206  validateModuleDescription(static_cast<logmodule_t>(m));
207  }
208  } else {
209  module_check_stack.push_back(module);
210  if (count(module_check_stack.begin(), module_check_stack.end(), module) > 1) {
211  throw InvalidFormat("Log module definition hierarchy contains cycles");
212  }
213  }
214  }
215 
216  std::string LogManager::getModuleName(logmodule_t module) {
217  return moduleInfos[module].name;
218  }
219 }