Changeset View
Changeset View
Standalone View
Standalone View
src/logging.h
- This file was added.
// Copyright (c) 2018 The Bitcoin ABC developers | |||||
// Distributed under the MIT software license, see the accompanying | |||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | |||||
#ifndef BITCOIN_LOGGING_H | |||||
#define BITCOIN_LOGGING_H | |||||
#include "tinyformat.h" | |||||
#include "univalue.h" | |||||
#include "util.h" | |||||
namespace BCLog { | |||||
class Logger; | |||||
/** | |||||
* Levels represent the severity of log lines. Loggers only emit log lines | |||||
* with a level greater than the configured threshold. | |||||
*/ | |||||
enum Level { DEBUG, INFO, WARN, ERROR, FATAL }; | |||||
/** | |||||
* A structured log entry. The class is designed to be used within a macro. | |||||
* As such, it writes its contents to a Logger instance it its destructor. | |||||
* | |||||
* This class should not be accessed directly, only through the LOG macro. | |||||
*/ | |||||
class LogLine { | |||||
friend Logger; | |||||
private: | |||||
Logger *m_logger; | |||||
UniValue m_value; | |||||
public: | |||||
explicit LogLine(Logger *logger, Level level, LogFlags category); | |||||
LogLine() = delete; | |||||
LogLine(const LogLine &other) = delete; | |||||
LogLine(LogLine &&other) = delete; | |||||
/// Destructor writes data to the logger if available. | |||||
~LogLine(); | |||||
/// Adds a primary message field with key "msg". | |||||
LogLine &Message(const std::string &message); | |||||
/// Adds a key-value field to the log line. | |||||
LogLine &With(const std::string &key, const UniValue &val); | |||||
template <typename... Args> | |||||
LogLine &With(const std::string &key, const char *fmt, | |||||
const Args &... args) { | |||||
return With(key, tfm::format(fmt, args...)); | |||||
} | |||||
template <typename... Args> | |||||
LogLine &Message(const char *fmt, const Args &... args) { | |||||
return Message(tfm::format(fmt, args...)); | |||||
} | |||||
}; | |||||
/** | |||||
* A Logger is used write structured log lines to an output channel. | |||||
*/ | |||||
class Logger { | |||||
public: | |||||
bool log_timestamps = true; | |||||
bool log_time_micros = false; | |||||
bool log_thread_id = false; | |||||
Level threshold_level = INFO; | |||||
LogFlags categories = NONE; | |||||
bool WillWriteLevel(Level level) const; | |||||
bool WillWriteCategory(LogFlags category) const; | |||||
void Write(const LogLine &log); | |||||
}; | |||||
} // namespace BCLog | |||||
extern std::unique_ptr<BCLog::Logger> g_logger; | |||||
/** | |||||
* This macro is the primary method of logging data. Methods defined on | |||||
* BC::LogLine can be chained onto the resulting value. The With() method is | |||||
* used to add key-value entries to the structured log line. The level threshold | |||||
* and accepted categories are configured on the global logger instance. | |||||
* | |||||
* Example usage: | |||||
* | |||||
* LOG(INFO, ALL) | |||||
* .Message("New block was received") | |||||
* .With("height": 525318) | |||||
* .With("tx_count": 25); | |||||
*/ | |||||
#define LOG(level, category) \ | |||||
if (g_logger && g_logger->WillWriteLevel(BCLog::level) && \ | |||||
g_logger->WillWriteCategory(BCLog::category)) \ | |||||
BCLog::LogLine(g_logger.get(), BCLog::level, BCLog::category) \ | |||||
.With("at", __func__) | |||||
#endif // BITCOIN_LOGGING_H |