BSHA3  0.17.99
P2P Blockchain, based on Bitcoin
logging.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2018 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include <logging.h>
7 #include <utiltime.h>
8 
9 const char * const DEFAULT_DEBUGLOGFILE = "debug.log";
10 
25 
26 bool fLogIPs = DEFAULT_LOGIPS;
27 
28 static int FileWriteStr(const std::string &str, FILE *fp)
29 {
30  return fwrite(str.data(), 1, str.size(), fp);
31 }
32 
34 {
35  std::lock_guard<std::mutex> scoped_lock(m_file_mutex);
36 
37  assert(m_fileout == nullptr);
38  assert(!m_file_path.empty());
39 
41  if (!m_fileout) {
42  return false;
43  }
44 
45  setbuf(m_fileout, nullptr); // unbuffered
46  // dump buffered messages from before we opened the log
47  while (!m_msgs_before_open.empty()) {
48  FileWriteStr(m_msgs_before_open.front(), m_fileout);
49  m_msgs_before_open.pop_front();
50  }
51 
52  return true;
53 }
54 
56 {
57  m_categories |= flag;
58 }
59 
60 bool BCLog::Logger::EnableCategory(const std::string& str)
61 {
62  BCLog::LogFlags flag;
63  if (!GetLogCategory(flag, str)) return false;
64  EnableCategory(flag);
65  return true;
66 }
67 
69 {
70  m_categories &= ~flag;
71 }
72 
73 bool BCLog::Logger::DisableCategory(const std::string& str)
74 {
75  BCLog::LogFlags flag;
76  if (!GetLogCategory(flag, str)) return false;
77  DisableCategory(flag);
78  return true;
79 }
80 
82 {
83  return (m_categories.load(std::memory_order_relaxed) & category) != 0;
84 }
85 
87 {
88  return m_categories == BCLog::NONE;
89 }
90 
92 {
94  std::string category;
95 };
96 
98 {
99  {BCLog::NONE, "0"},
100  {BCLog::NONE, "none"},
101  {BCLog::NET, "net"},
102  {BCLog::TOR, "tor"},
103  {BCLog::MEMPOOL, "mempool"},
104  {BCLog::HTTP, "http"},
105  {BCLog::BENCH, "bench"},
106  {BCLog::ZMQ, "zmq"},
107  {BCLog::DB, "db"},
108  {BCLog::RPC, "rpc"},
109  {BCLog::ESTIMATEFEE, "estimatefee"},
110  {BCLog::ADDRMAN, "addrman"},
111  {BCLog::SELECTCOINS, "selectcoins"},
112  {BCLog::REINDEX, "reindex"},
113  {BCLog::CMPCTBLOCK, "cmpctblock"},
114  {BCLog::RAND, "rand"},
115  {BCLog::PRUNE, "prune"},
116  {BCLog::PROXY, "proxy"},
117  {BCLog::MEMPOOLREJ, "mempoolrej"},
118  {BCLog::LIBEVENT, "libevent"},
119  {BCLog::COINDB, "coindb"},
120  {BCLog::QT, "qt"},
121  {BCLog::LEVELDB, "leveldb"},
122  {BCLog::ALL, "1"},
123  {BCLog::ALL, "all"},
124 };
125 
126 bool GetLogCategory(BCLog::LogFlags& flag, const std::string& str)
127 {
128  if (str == "") {
129  flag = BCLog::ALL;
130  return true;
131  }
132  for (const CLogCategoryDesc& category_desc : LogCategories) {
133  if (category_desc.category == str) {
134  flag = category_desc.flag;
135  return true;
136  }
137  }
138  return false;
139 }
140 
141 std::string ListLogCategories()
142 {
143  std::string ret;
144  int outcount = 0;
145  for (const CLogCategoryDesc& category_desc : LogCategories) {
146  // Omit the special cases.
147  if (category_desc.flag != BCLog::NONE && category_desc.flag != BCLog::ALL) {
148  if (outcount != 0) ret += ", ";
149  ret += category_desc.category;
150  outcount++;
151  }
152  }
153  return ret;
154 }
155 
156 std::vector<CLogCategoryActive> ListActiveLogCategories()
157 {
158  std::vector<CLogCategoryActive> ret;
159  for (const CLogCategoryDesc& category_desc : LogCategories) {
160  // Omit the special cases.
161  if (category_desc.flag != BCLog::NONE && category_desc.flag != BCLog::ALL) {
162  CLogCategoryActive catActive;
163  catActive.category = category_desc.category;
164  catActive.active = LogAcceptCategory(category_desc.flag);
165  ret.push_back(catActive);
166  }
167  }
168  return ret;
169 }
170 
171 std::string BCLog::Logger::LogTimestampStr(const std::string &str)
172 {
173  std::string strStamped;
174 
175  if (!m_log_timestamps)
176  return str;
177 
178  if (m_started_new_line) {
179  int64_t nTimeMicros = GetTimeMicros();
180  strStamped = FormatISO8601DateTime(nTimeMicros/1000000);
181  if (m_log_time_micros) {
182  strStamped.pop_back();
183  strStamped += strprintf(".%06dZ", nTimeMicros%1000000);
184  }
185  int64_t mocktime = GetMockTime();
186  if (mocktime) {
187  strStamped += " (mocktime: " + FormatISO8601DateTime(mocktime) + ")";
188  }
189  strStamped += ' ' + str;
190  } else
191  strStamped = str;
192 
193  if (!str.empty() && str[str.size()-1] == '\n')
194  m_started_new_line = true;
195  else
196  m_started_new_line = false;
197 
198  return strStamped;
199 }
200 
201 void BCLog::Logger::LogPrintStr(const std::string &str)
202 {
203  std::string strTimestamped = LogTimestampStr(str);
204 
205  if (m_print_to_console) {
206  // print to console
207  fwrite(strTimestamped.data(), 1, strTimestamped.size(), stdout);
208  fflush(stdout);
209  }
210  if (m_print_to_file) {
211  std::lock_guard<std::mutex> scoped_lock(m_file_mutex);
212 
213  // buffer if we haven't opened the log yet
214  if (m_fileout == nullptr) {
215  m_msgs_before_open.push_back(strTimestamped);
216  }
217  else
218  {
219  // reopen the log file, if requested
220  if (m_reopen_file) {
221  m_reopen_file = false;
222  FILE* new_fileout = fsbridge::fopen(m_file_path, "a");
223  if (new_fileout) {
224  setbuf(new_fileout, nullptr); // unbuffered
225  fclose(m_fileout);
226  m_fileout = new_fileout;
227  }
228  }
229  FileWriteStr(strTimestamped, m_fileout);
230  }
231  }
232 }
233 
235 {
236  // Amount of debug.log to save at end when shrinking (must fit in memory)
237  constexpr size_t RECENT_DEBUG_HISTORY_SIZE = 10 * 1000000;
238 
239  assert(!m_file_path.empty());
240 
241  // Scroll debug.log if it's getting too big
242  FILE* file = fsbridge::fopen(m_file_path, "r");
243 
244  // Special files (e.g. device nodes) may not have a size.
245  size_t log_size = 0;
246  try {
247  log_size = fs::file_size(m_file_path);
248  } catch (const fs::filesystem_error&) {}
249 
250  // If debug.log file is more than 10% bigger the RECENT_DEBUG_HISTORY_SIZE
251  // trim it down by saving only the last RECENT_DEBUG_HISTORY_SIZE bytes
252  if (file && log_size > 11 * (RECENT_DEBUG_HISTORY_SIZE / 10))
253  {
254  // Restart the file with some of the end
255  std::vector<char> vch(RECENT_DEBUG_HISTORY_SIZE, 0);
256  if (fseek(file, -((long)vch.size()), SEEK_END)) {
257  LogPrintf("Failed to shrink debug log file: fseek(...) failed\n");
258  fclose(file);
259  return;
260  }
261  int nBytes = fread(vch.data(), 1, vch.size(), file);
262  fclose(file);
263 
264  file = fsbridge::fopen(m_file_path, "w");
265  if (file)
266  {
267  fwrite(vch.data(), 1, nBytes, file);
268  fclose(file);
269  }
270  }
271  else if (file != nullptr)
272  fclose(file);
273 }
void EnableCategory(LogFlags flag)
Definition: logging.cpp:55
FILE * fopen(const fs::path &p, const char *mode)
Definition: fs.cpp:13
fs::path m_file_path
Definition: logging.h:85
#define strprintf
Definition: tinyformat.h:1066
std::string ListLogCategories()
Returns a string with the log categories.
Definition: logging.cpp:141
UniValue ret(UniValue::VARR)
Definition: rpcwallet.cpp:1140
BCLog::LogFlags flag
Definition: logging.cpp:93
int64_t GetTimeMicros()
Definition: utiltime.cpp:48
void LogPrintStr(const std::string &str)
Send a string to the log output.
Definition: logging.cpp:201
std::string category
Definition: logging.cpp:94
bool push_back(const UniValue &val)
Definition: univalue.cpp:108
void DisableCategory(LogFlags flag)
Definition: logging.cpp:68
bool WillLogCategory(LogFlags category) const
Definition: logging.cpp:81
bool GetLogCategory(BCLog::LogFlags &flag, const std::string &str)
Return true if str parses as a log category and set the flag.
Definition: logging.cpp:126
std::mutex m_file_mutex
Definition: logging.h:63
FILE * m_fileout
Definition: logging.h:62
std::string FormatISO8601DateTime(int64_t nTime)
ISO 8601 formatting is preferred.
Definition: utiltime.cpp:79
const CLogCategoryDesc LogCategories[]
Definition: logging.cpp:97
bool fLogIPs
Definition: logging.cpp:26
LogFlags
Definition: logging.h:33
std::string category
Definition: logging.h:28
std::list< std::string > m_msgs_before_open
Definition: logging.h:64
bool OpenDebugLog()
Definition: logging.cpp:33
int64_t GetMockTime()
Definition: utiltime.cpp:35
const char *const DEFAULT_DEBUGLOGFILE
Definition: logging.cpp:9
std::vector< CLogCategoryActive > ListActiveLogCategories()
Returns a vector of the active log categories.
Definition: logging.cpp:156
BCLog::Logger *const g_logger
NOTE: the logger instances is leaked on exit.
Definition: logging.cpp:24
void ShrinkDebugFile()
Definition: logging.cpp:234
std::string LogTimestampStr(const std::string &str)
Definition: logging.cpp:171
bool DefaultShrinkDebugFile() const
Definition: logging.cpp:86