Bitcoin Core  0.19.99
P2P Digital Currency
logging.h
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2020 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 #ifndef BITCOIN_LOGGING_H
7 #define BITCOIN_LOGGING_H
8 
9 #include <fs.h>
10 #include <tinyformat.h>
11 
12 #include <atomic>
13 #include <cstdint>
14 #include <list>
15 #include <mutex>
16 #include <string>
17 #include <vector>
18 
19 static const bool DEFAULT_LOGTIMEMICROS = false;
20 static const bool DEFAULT_LOGIPS = false;
21 static const bool DEFAULT_LOGTIMESTAMPS = true;
22 static const bool DEFAULT_LOGTHREADNAMES = false;
23 extern const char * const DEFAULT_DEBUGLOGFILE;
24 
25 extern bool fLogIPs;
26 
28 {
29  std::string category;
30  bool active;
31 };
32 
33 namespace BCLog {
34  enum LogFlags : uint32_t {
35  NONE = 0,
36  NET = (1 << 0),
37  TOR = (1 << 1),
38  MEMPOOL = (1 << 2),
39  HTTP = (1 << 3),
40  BENCH = (1 << 4),
41  ZMQ = (1 << 5),
42  WALLETDB = (1 << 6),
43  RPC = (1 << 7),
44  ESTIMATEFEE = (1 << 8),
45  ADDRMAN = (1 << 9),
46  SELECTCOINS = (1 << 10),
47  REINDEX = (1 << 11),
48  CMPCTBLOCK = (1 << 12),
49  RAND = (1 << 13),
50  PRUNE = (1 << 14),
51  PROXY = (1 << 15),
52  MEMPOOLREJ = (1 << 16),
53  LIBEVENT = (1 << 17),
54  COINDB = (1 << 18),
55  QT = (1 << 19),
56  LEVELDB = (1 << 20),
57  VALIDATION = (1 << 21),
58  ALL = ~(uint32_t)0,
59  };
60 
61  class Logger
62  {
63  private:
64  mutable std::mutex m_cs; // Can not use Mutex from sync.h because in debug mode it would cause a deadlock when a potential deadlock was detected
65  FILE* m_fileout = nullptr; // GUARDED_BY(m_cs)
66  std::list<std::string> m_msgs_before_open; // GUARDED_BY(m_cs)
67  bool m_buffering{true};
68 
74  std::atomic_bool m_started_new_line{true};
75 
77  std::atomic<uint32_t> m_categories{0};
78 
79  std::string LogTimestampStr(const std::string& str);
80 
82  std::list<std::function<void(const std::string&)>> m_print_callbacks /* GUARDED_BY(m_cs) */ {};
83 
84  public:
85  bool m_print_to_console = false;
86  bool m_print_to_file = false;
87 
88  bool m_log_timestamps = DEFAULT_LOGTIMESTAMPS;
89  bool m_log_time_micros = DEFAULT_LOGTIMEMICROS;
90  bool m_log_threadnames = DEFAULT_LOGTHREADNAMES;
91 
92  fs::path m_file_path;
93  std::atomic<bool> m_reopen_file{false};
94 
96  void LogPrintStr(const std::string& str);
97 
99  bool Enabled() const
100  {
101  std::lock_guard<std::mutex> scoped_lock(m_cs);
102  return m_buffering || m_print_to_console || m_print_to_file || !m_print_callbacks.empty();
103  }
104 
106  std::list<std::function<void(const std::string&)>>::iterator PushBackCallback(std::function<void(const std::string&)> fun)
107  {
108  std::lock_guard<std::mutex> scoped_lock(m_cs);
109  m_print_callbacks.push_back(std::move(fun));
110  return --m_print_callbacks.end();
111  }
112 
114  void DeleteCallback(std::list<std::function<void(const std::string&)>>::iterator it)
115  {
116  std::lock_guard<std::mutex> scoped_lock(m_cs);
117  m_print_callbacks.erase(it);
118  }
119 
121  bool StartLogging();
123  void DisconnectTestLogger();
124 
125  void ShrinkDebugFile();
126 
127  uint32_t GetCategoryMask() const { return m_categories.load(); }
128 
129  void EnableCategory(LogFlags flag);
130  bool EnableCategory(const std::string& str);
131  void DisableCategory(LogFlags flag);
132  bool DisableCategory(const std::string& str);
133 
134  bool WillLogCategory(LogFlags category) const;
135 
136  bool DefaultShrinkDebugFile() const;
137  };
138 
139 } // namespace BCLog
140 
142 
145 {
146  return LogInstance().WillLogCategory(category);
147 }
148 
150 std::string ListLogCategories();
151 
153 std::vector<CLogCategoryActive> ListActiveLogCategories();
154 
156 bool GetLogCategory(BCLog::LogFlags& flag, const std::string& str);
157 
158 // Be conservative when using LogPrintf/error or other things which
159 // unconditionally log to debug.log! It should not be the case that an inbound
160 // peer can fill up a user's disk with debug.log entries.
161 
162 template <typename... Args>
163 static inline void LogPrintf(const char* fmt, const Args&... args)
164 {
165  if (LogInstance().Enabled()) {
166  std::string log_msg;
167  try {
168  log_msg = tfm::format(fmt, args...);
169  } catch (tinyformat::format_error& fmterr) {
170  /* Original format string will have newline so don't add one here */
171  log_msg = "Error \"" + std::string(fmterr.what()) + "\" while formatting log message: " + fmt;
172  }
173  LogInstance().LogPrintStr(log_msg);
174  }
175 }
176 
177 // Use a macro instead of a function for conditional logging to prevent
178 // evaluating arguments when logging for the category is not enabled.
179 #define LogPrint(category, ...) \
180  do { \
181  if (LogAcceptCategory((category))) { \
182  LogPrintf(__VA_ARGS__); \
183  } \
184  } while (0)
185 
186 #endif // BITCOIN_LOGGING_H
std::mutex m_cs
Definition: logging.h:64
fs::path m_file_path
Definition: logging.h:92
Definition: timer.h:17
bool fLogIPs
Definition: logging.cpp:35
static const bool DEFAULT_LOGTHREADNAMES
Definition: logging.h:22
std::vector< CLogCategoryActive > ListActiveLogCategories()
Returns a vector of the active log categories.
Definition: logging.cpp:200
static const bool DEFAULT_LOGTIMEMICROS
Definition: logging.h:19
static void LogPrintf(const char *fmt, const Args &... args)
Definition: logging.h:163
BCLog::Logger & LogInstance()
Definition: logging.cpp:14
std::list< std::function< void(const std::string &)> >::iterator PushBackCallback(std::function< void(const std::string &)> fun)
Connect a slot to the print signal and return the connection.
Definition: logging.h:106
void LogPrintStr(const std::string &str)
Send a string to the log output.
Definition: logging.cpp:262
void format(std::ostream &out, const char *fmt, const Args &... args)
Format list of arguments to the stream according to given format string.
Definition: tinyformat.h:1062
uint32_t GetCategoryMask() const
Definition: logging.h:127
bool WillLogCategory(LogFlags category) const
Definition: logging.cpp:124
static bool LogAcceptCategory(BCLog::LogFlags category)
Return true if log accepts specified category.
Definition: logging.h:144
std::string ListLogCategories()
Returns a string with the log categories.
Definition: logging.cpp:185
void DeleteCallback(std::list< std::function< void(const std::string &)>>::iterator it)
Delete a connection.
Definition: logging.h:114
LogFlags
Definition: logging.h:34
std::string category
Definition: logging.h:29
std::list< std::string > m_msgs_before_open
Definition: logging.h:66
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:170
static const bool DEFAULT_LOGIPS
Definition: logging.h:20
const char *const DEFAULT_DEBUGLOGFILE
Definition: logging.cpp:12
bool Enabled() const
Returns whether logs will be written to any output.
Definition: logging.h:99
auto it
Definition: validation.cpp:362
static const bool DEFAULT_LOGTIMESTAMPS
Definition: logging.h:21