Belle II Software development
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
21using namespace Belle2;
22
23bool LogFile::g_stderr = true;
24bool LogFile::g_opened = false;
25std::string LogFile::g_filepath;
26std::string LogFile::g_linkpath;
27std::ofstream LogFile::g_stream;
28unsigned int LogFile::g_filesize = 0;
29Mutex LogFile::g_mutex;
30LogFile::Priority LogFile::g_threshold;
31std::string LogFile::g_filename;
32Date LogFile::g_date;
33
34LogFile::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
53void 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
71void 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
89void LogFile::close()
90{
91 if (!g_opened) return;
92 g_stream.close();
93 g_opened = false;
94}
95
96void 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
104void 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
112void 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
120void 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
128void 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
136void 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
145void 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
153int 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.