Belle II Software  release-08-01-10
LogFile.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 #include "daq/slc/system/LogFile.h"
9 
10 #include <daq/slc/base/ConfigFile.h>
11 #include <daq/slc/base/StringUtil.h>
12 
13 #include <iostream>
14 #include <sstream>
15 #include <cstdio>
16 
17 #include <sys/stat.h>
18 #include <cstdlib>
19 #include <daq/slc/system/LockGuard.h>
20 
21 using namespace Belle2;
22 
23 bool LogFile::g_stderr = true;
24 bool LogFile::g_opened = false;
25 std::string LogFile::g_filepath;
26 std::string LogFile::g_linkpath;
27 std::ofstream LogFile::g_stream;
28 unsigned int LogFile::g_filesize = 0;
29 Mutex LogFile::g_mutex;
30 LogFile::Priority LogFile::g_threshold;
31 std::string LogFile::g_filename;
32 Date LogFile::g_date;
33 
34 LogFile::Priority LogFile::getPriority(const std::string& str)
35 {
36  const std::string s = StringUtil::toupper(str);
37  if (s == "DEBUG") {
38  return DEBUG;
39  } else if (s == "INFO") {
40  return INFO;
41  } else if (s == "NOTICE") {
42  return NOTICE;
43  } else if (s == "WARNING") {
44  return WARNING;
45  } else if (s == "ERROR") {
46  return ERROR;
47  } else if (s == "FATAL") {
48  return FATAL;
49  }
50  return UNKNOWN;
51 }
52 
53 void LogFile::open(const std::string& filename, Priority threshold)
54 {
55  if (!g_opened) {
56  ConfigFile config("slowcontrol");
57  std::string path = config.get("log.dir");
58  //if (path.size() == 0) path = config.get("logfile.dir");
59  system(("mkdir -p " + path + "/" + filename).c_str());
60  g_filename = filename;
61  g_date = Date();
62  g_filepath = path + StringUtil::form("/%s/%s.log", filename.c_str(), g_date.toString("%Y.%m.%d"));
63  g_linkpath = path + StringUtil::form("/%s/latest.log", filename.c_str());
64  //"/latest.log";
65  g_threshold = threshold;
66  g_opened = true;
67  open();
68  }
69 }
70 
71 void LogFile::open()
72 {
73  if (!g_opened) return;
74  struct stat st;
75  if (stat(g_filepath.c_str(), &st) == 0) {
76  g_filesize = st.st_size;
77  g_stream.open(g_filepath.c_str(), std::ios::out | std::ios::app);
78  } else {
79  g_filesize = 0;
80  g_stream.open(g_filepath.c_str(), std::ios::out);
81  }
82  debug("/* ---------- log file opened ---------- */");
83  debug("log file : %s (%d) ", g_filepath.c_str(), g_filesize);
84  std::string cmd = "ln -sf " + g_filepath + " " + g_linkpath;
85  system(cmd.c_str());
86  debug("sym link : %s", g_linkpath.c_str());
87 }
88 
89 void LogFile::close()
90 {
91  if (!g_opened) return;
92  g_stream.close();
93  g_opened = false;
94 }
95 
96 void LogFile::debug(const std::string& msg, ...)
97 {
98  va_list ap;
99  va_start(ap, msg);
100  put_impl(msg, DEBUG, ap);
101  va_end(ap);
102 }
103 
104 void LogFile::info(const std::string& msg, ...)
105 {
106  va_list ap;
107  va_start(ap, msg);
108  put_impl(msg, INFO, ap);
109  va_end(ap);
110 }
111 
112 void LogFile::notice(const std::string& msg, ...)
113 {
114  va_list ap;
115  va_start(ap, msg);
116  put_impl(msg, NOTICE, ap);
117  va_end(ap);
118 }
119 
120 void LogFile::warning(const std::string& msg, ...)
121 {
122  va_list ap;
123  va_start(ap, msg);
124  put_impl(msg, WARNING, ap);
125  va_end(ap);
126 }
127 
128 void LogFile::error(const std::string& msg, ...)
129 {
130  va_list ap;
131  va_start(ap, msg);
132  put_impl(msg, ERROR, ap);
133  va_end(ap);
134 }
135 
136 void LogFile::fatal(const std::string& msg, ...)
137 {
138  va_list ap;
139  va_start(ap, msg);
140  put_impl(msg, FATAL, ap);
141  va_end(ap);
142 }
143 
144 
145 void LogFile::put(Priority priority, const std::string& msg, ...)
146 {
147  va_list ap;
148  va_start(ap, msg);
149  put_impl(msg, priority, ap);
150  va_end(ap);
151 }
152 
153 int LogFile::put_impl(const std::string& msg, Priority priority, va_list ap)
154 {
155  LockGuard lockGuard(g_mutex);
156  if (g_threshold > priority) {
157  return 0;
158  }
159  Date date;
160  if (g_date.getDay() != date.getDay()) {
161  g_stream.close();
162  open();
163  }
164  std::stringstream ss;
165  ss << "[" << date.toString();
166  std::string color = "\x1b[49m\x1b[39m";
167  switch (priority) {
168  case DEBUG: color = "\x1b[49m\x1b[39m"; ss << "] [DEBUG] "; break;
169  case INFO: color = "\x1b[49m\x1b[32m"; ss << "] [INFO] "; break;
170  case NOTICE: color = "\x1b[49m\x1b[34m"; ss << "] [NOTICE] "; break;
171  case WARNING: color = "\x1b[49m\x1b[35m"; ss << "] [WARNING] "; break;
172  case ERROR: color = "\x1b[49m\x1b[31m"; ss << "] [ERROR] "; break;
173  case FATAL: color = "\x1b[41m\x1b[37m"; ss << "] [FATAL] "; break;
174  default: ss << "] [UNKNOWN] "; break;
175  }
176  static char* s = new char[1024 * 1024 * 5];
177  vsnprintf(s, 1024 * 1024 * 5, msg.c_str(), ap);
178  ss << s << std::endl;
179  std::string str = ss.str();
180  std::cerr << color << str << "\x1b[49m\x1b[39m";
181  if (g_opened) {
182  g_stream << str;
183  g_stream.flush();
184  g_filesize += str.size();
185  }
186  return (int) str.size();
187 }
Lock Guard for a Mutex instance.
Definition: LockGuard.h:47
Abstract base class for different kinds of events.