MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
simple_logger.hpp
Go to the documentation of this file.
1 /*
2  * ==============================================================================
3  *
4  * Filename: simple_logger.hpp
5  *
6  * Description: A simple XML based logger.
7  *
8  * Version: 1.0
9  * Created: Saturday 24 May 2014 06:25:10 IST
10  * Revision: none
11  * Compiler: gcc
12  *
13  * Author: Dilawar Singh (), dilawars@ncbs.res.in
14  * Organization: NCBS Bangalore
15  *
16  * Copyright (C) 2014, Dilawar Singh, NCBS Bangalore
17  *
18  * This program is free software; you can redistribute it and/or modify
19  * it under the terms of the GNU General Public License as published by
20  * the Free Software Foundation; either version 2 of the License, or
21  * (at your option) any later version.
22  *
23  * This program is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26  * GNU General Public License for more details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with this program; if not, see <http://www.gnu.org/licenses/>.
30  *
31  * ==============================================================================
32  */
33 
34 #ifndef MOOSE_LOGGER_INC
35 #define MOOSE_LOGGER_INC
36 
37 #include <sstream>
38 #include <string>
39 #include <cstdlib>
40 #include <ctime>
41 #include <numeric>
42 #include <map>
43 #include <vector>
44 #include <iostream>
45 #include <iomanip>
46 #include <sys/stat.h>
47 #include <fstream>
48 
49 using namespace std;
50 
51 #define T_RESET "\033[0m"
52 #define T_BLACK "\033[30m" /* Black */
53 #define T_RED "\033[31m" /* Red */
54 #define T_GREEN "\033[32m" /* Green */
55 #define T_YELLOW "\033[33m" /* Yellow */
56 #define T_BLUE "\033[34m" /* Blue */
57 #define T_MAGENTA "\033[35m" /* Magenta */
58 #define T_CYAN "\033[36m" /* Cyan */
59 #define T_WHITE "\033[37m" /* White */
60 #define T_BOLDBLACK "\033[1m\033[30m" /* Bold Black */
61 #define T_BOLDRED "\033[1m\033[31m" /* Bold Red */
62 #define T_BOLDGREEN "\033[1m\033[32m" /* Bold Green */
63 #define T_BOLDYELLOW "\033[1m\033[33m" /* Bold Yellow */
64 #define T_BOLDBLUE "\033[1m\033[34m" /* Bold Blue */
65 #define T_BOLDMAGENTA "\033[1m\033[35m" /* Bold Magenta */
66 #define T_BOLDCYAN "\033[1m\033[36m" /* Bold Cyan */
67 #define T_BOLDWHITE "\033[1m\033[37m" /* Bold White */
68 
69 class SimpleLogger {
70 
71  public:
72 
79  {
80  startTime = timeStamp();
81  homeDir = getenv("HOME");
82 
83  logSS << "<log simulator=\"moose\">" << endl;
84  logSS << "\t<start_time>" << startTime << "</start_time>" << endl;
85  logSS << "\t<messages>" << endl;
86 
87 #ifdef OS_WINDOWS
88  outputFile = homeDir + "\\.moose\\log";
89 #else
90  outputFile = homeDir + "/.moose/log";
91 #endif
92  }
93 
95  {
96 
97  }
98 
104  const std::string timeStamp()
105  {
106  time_t now = time(0);
107  struct tm tstruct;
108  char buf[80];
109  tstruct = *localtime(&now);
110  strftime(buf, sizeof(buf), "%Y-%m-%d.%X", &tstruct);
111  return buf;
112  }
113 
121  void updateGlobalCount(string type)
122  {
123  if(elementsMap.find(type) == elementsMap.end())
124  elementsMap[type] = 1;
125  else
126  elementsMap[type] = elementsMap[type] + 1;
127  }
128 
129  template<typename A, typename B>
130  string mapToString(const map<A, B>& m, string title = "") const
131  {
132  unsigned width = 50;
133  stringstream ss;
134 
135  ss << title;
136  for(unsigned i = 0; i < width - title.size(); ++i)
137  ss << "~";
138  ss << endl;
139 
140  typename map<A, B>::const_iterator it;
141  for( it = m.begin(); it != m.end(); it++)
142  ss << setw(width/2) << it->first << setw(width/2) << it->second << endl;
143 
144  for(unsigned i = 0; i < width; ++i)
145  ss << "=";
146 
147  ss << endl;
148  return ss.str();
149  }
150 
159  string dumpStats( int which )
160  {
161  stringstream ss;
162  // unsigned width = 50;
163  ss << endl;
164  if(which == 0)
165  ss << mapToString<string, unsigned long>(elementsMap, "data_structure");
166 
167  else if( which == 1)
168  {
169  timekeeperMap["Simulation"] = accumulate(
170  simulationTime.begin()
171  , simulationTime.end()
172  , 0.0
173  );
174  timekeeperMap["Initialization"] = accumulate(
175  initializationTime.begin()
176  , initializationTime.end()
177  , 0.0
178  );
179  timekeeperMap["Creation"] = accumulate(
180  creationTime.begin()
181  , creationTime.end()
182  , 0.0
183  );
184 
185  ss << mapToString<string, float>( timekeeperMap, "simulation_stats" );
186  }
187  return ss.str();
188  }
189 
190 
201  template<typename A, typename B>
202  void mapToXML(ostringstream& ss, const map<A, B>& m, const char* tagName
203  , unsigned indent) const
204  {
205  string prefix = "";
206  for(unsigned int i = 0; i < indent; ++i)
207  prefix += "\t";
208  ss << prefix << "<" << tagName << ">" << endl;
209 
210  typename map<A, B>::const_iterator it;
211  for(it = m.begin(); it != m.end(); it++)
212  {
213  ss << prefix << prefix
214  << "<" << it->first << ">"
215  << it->second
216  << "</" << it->first << ">" << endl;
217  }
218 
219  ss << prefix << "</" << tagName << ">" << endl;
220  }
221 
227  string save( const char* outFile = "")
228  {
229  string logFile = string(outFile);
230  if(logFile.size() == 0)
231  logFile = outputFile;
232 
233  // End of messages.
234  logSS << "\t</messages>" << endl;
235 
236  mapToXML<string, unsigned long>(logSS, elementsMap, "data_structure", 1);
237  mapToXML<string, float>(logSS, timekeeperMap, "times", 1);
238 
239  logSS << "\t<end_time>" << timeStamp() << "</end_time>" << endl;
240 
241  logSS << "</log>" << endl;
242 
243  fstream logF;
244  logF.open(logFile.c_str(), std::fstream::out | std::fstream::app);
245  logF << logSS.str();
246  logF.close();
247  return logSS.str();
248  }
249 
257  bool isDir( const std::string& name )
258  {
259 #ifdef OS_WINDOWS
260  struct _stat buf;
261  int result = _stat( name.c_str(), &buf );
262 #else
263  struct stat buf;
264  int result = stat( name.c_str(), &buf );
265 #endif
266  if(result == 0 && S_ISDIR(buf.st_mode))
267  return true;
268  else
269  return false;
270  }
271 
279  void dump(string type, string msg, bool autoFormat = true)
280  {
281 
282 #if VERBOSITY < 0
283  return;
284 #endif
285 
286  stringstream ss;
287  ss.precision( 12 );
288  ss << "[" << type << "] ";
289  bool set = false;
290  bool reset = true;
291  string color = T_GREEN;
292  if(type == "WARNING" || type == "WARN" || type == "FIXME")
293  color = T_YELLOW;
294  else if(type == "DEBUG")
295  color = T_CYAN;
296  else if(type == "ERROR" || type == "FAIL" || type == "FATAL" || type == "ASSERT_FAILURE")
297  color = T_RED;
298  else if(type == "INFO" || type == "EXPECT_FAILURE")
299  color = T_MAGENTA;
300  else if(type == "LOG")
301  color = T_BLUE;
302 
303  for(unsigned int i = 0; i < msg.size(); ++i)
304  {
305  if('`' == msg[i])
306  {
307  if(!set and reset)
308  {
309  set = true;
310  reset = false;
311  ss << color;
312  }
313  else if(set && !reset)
314  {
315  reset = true;
316  set = false;
317  ss << T_RESET;
318  }
319  }
320  else if('\n' == msg[i])
321  ss << "\n + ";
322  else
323  ss << msg[i];
324  }
325 
326  /* Be safe than sorry */
327  if(!reset)
328  ss << T_RESET;
329 
330  logSS << ss.str() << endl;
331  cerr << ss.str() << endl;
332  }
333 
334 
344  std::string log(string type, const string& msg)
345  {
346 #ifdef ENABLE_LOGGER
347  stringstream ss;
348  string time = timeStamp();
349  fstream logF;
350  logF.open(outputFile.c_str(), std::fstream::out | std::fstream::app);
351  ss << "<" << type << " time=\"" << time << "\">";
352  ss << msg << "</" << type << ">" << endl;
353  logF << ss.str();
354  logF.close();
355  string newmsg = ss.str();
356  return newmsg;
357 #else
358  return string("");
359 #endif
360 
361  }
362 
363 
364  private:
365  map<string, unsigned long> elementsMap;
366  map<string, float> timekeeperMap;
367 
368  public:
369 
370  string mooseDir;
371  string homeDir;
372 
373  string outputFile;
374  string startTime;
375  string endTime;
376 
377  ostringstream logSS;
378 
379  /* Map to keep simulation run-time data. */
380  vector<float> simulationTime;
381  vector<float> initializationTime;
382  vector<float> creationTime;
383 };
384 
385 extern SimpleLogger logger;
386 
387 #endif /* ----- #ifndef MOOSE_LOGGER_INC ----- */
string mapToString(const map< A, B > &m, string title="") const
SimpleLogger()
Constructor of logger. The wrapper script of moose must make sure that $HOME/.moose is created...
void updateGlobalCount(string type)
When an element is created in moose, log its presense in this map.
string dumpStats(int which)
Dump statistics onto console.
#define T_MAGENTA
#define T_CYAN
#define T_BLUE
map< string, unsigned long > elementsMap
ostringstream logSS
string save(const char *outFile="")
Convert this logger to XML.
#define T_YELLOW
#define T_GREEN
vector< float > simulationTime
void mapToXML(ostringstream &ss, const map< A, B > &m, const char *tagName, unsigned indent) const
Converts a map to XML like staructure.
SimpleLogger logger
map< string, float > timekeeperMap
bool isDir(const std::string &name)
Checks if given directory path exists on system.
static char name[]
Definition: mfield.cpp:401
#define T_RED
vector< float > initializationTime
const std::string timeStamp()
Get current timestamp.
void dump(string type, string msg, bool autoFormat=true)
Dumps a message to console.
vector< float > creationTime
#define T_RESET
std::string log(string type, const string &msg)
Compose a message and log to logging file.