Clio develop
The XRP Ledger API server.
Loading...
Searching...
No Matches
Logger.hpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of clio: https://github.com/XRPLF/clio
4 Copyright (c) 2022, the clio developers.
5
6 Permission to use, copy, modify, and distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#pragma once
21
22#include "util/SourceLocation.hpp"
23
24#include <boost/algorithm/string/predicate.hpp>
25#include <boost/filesystem.hpp>
26#include <boost/json.hpp>
27#include <boost/json/conversion.hpp>
28#include <boost/json/value.hpp>
29#include <boost/log/core/core.hpp>
30#include <boost/log/core/record.hpp>
31#include <boost/log/expressions/filter.hpp>
32#include <boost/log/expressions/keyword.hpp>
33#include <boost/log/expressions/predicates/channel_severity_filter.hpp>
34#include <boost/log/keywords/channel.hpp>
35#include <boost/log/keywords/severity.hpp>
36#include <boost/log/sinks/unlocked_frontend.hpp>
37#include <boost/log/sources/record_ostream.hpp>
38#include <boost/log/sources/severity_channel_logger.hpp>
39#include <boost/log/sources/severity_feature.hpp>
40#include <boost/log/sources/severity_logger.hpp>
41#include <boost/log/utility/manipulators/add_value.hpp>
42#include <boost/log/utility/setup/common_attributes.hpp>
43#include <boost/log/utility/setup/console.hpp>
44#include <boost/log/utility/setup/file.hpp>
45#include <boost/log/utility/setup/formatter_parser.hpp>
46
47#include <array>
48#include <cstddef>
49#include <expected>
50#include <optional>
51#include <ostream>
52#include <string>
53
54namespace util {
55
56namespace config {
57class ClioConfigDefinition;
58} // namespace config
59
65#ifndef COVERAGE_ENABLED
66#define LOG(x) \
67 if (auto clio_pump__ = x; not clio_pump__) { \
68 } else \
69 clio_pump__
70#else
71#define LOG(x) x
72#endif
73
77enum class Severity {
78 TRC,
79 DBG,
80 NFO,
81 WRN,
82 ERR,
83 FTL,
84};
85
87// NOLINTBEGIN(readability-identifier-naming)
88BOOST_LOG_ATTRIBUTE_KEYWORD(LogSeverity, "Severity", Severity);
89BOOST_LOG_ATTRIBUTE_KEYWORD(LogChannel, "Channel", std::string);
90// NOLINTEND(readability-identifier-naming)
100std::ostream&
101operator<<(std::ostream& stream, Severity sev);
102
111class Logger final {
112 using LoggerType = boost::log::sources::severity_channel_logger_mt<Severity, std::string>;
113 mutable LoggerType logger_;
114
115 friend class LogService; // to expose the Pump interface
116
120 class Pump final {
121 using PumpOptType = std::optional<boost::log::aux::record_pump<LoggerType>>;
122
123 boost::log::record rec_;
124 PumpOptType pump_ = std::nullopt;
125
126 public:
127 ~Pump() = default;
128
129 Pump(LoggerType& logger, Severity sev, SourceLocationType const& loc)
130 : rec_{logger.open_record(boost::log::keywords::severity = sev)}
131 {
132 if (rec_) {
133 pump_.emplace(boost::log::aux::make_record_pump(logger, rec_));
134 pump_->stream() << boost::log::add_value("SourceLocation", prettyPath(loc));
135 }
136 }
137
138 Pump(Pump&&) = delete;
139 Pump(Pump const&) = delete;
140 Pump&
141 operator=(Pump const&) = delete;
142 Pump&
143 operator=(Pump&&) = delete;
144
152 template <typename T>
153 [[maybe_unused]] Pump&
154 operator<<(T&& data)
155 {
156 if (pump_)
157 pump_->stream() << std::forward<T>(data);
158 return *this;
159 }
160
164 operator bool() const
165 {
166 return pump_.has_value();
167 }
168
169 private:
170 [[nodiscard]] static std::string
171 prettyPath(SourceLocationType const& loc, size_t maxDepth = 3);
172 };
173
174public:
175 static constexpr std::array<char const*, 8> kCHANNELS = {
176 "General",
177 "WebServer",
178 "Backend",
179 "RPC",
180 "ETL",
181 "Subscriptions",
182 "Performance",
183 "Migration",
184 };
185
195 Logger(std::string channel) : logger_{boost::log::keywords::channel = channel}
196 {
197 }
198
199 Logger(Logger const&) = default;
200 ~Logger() = default;
201
202 Logger(Logger&&) = default;
203 Logger&
204 operator=(Logger const&) = default;
205
206 Logger&
207 operator=(Logger&&) = default;
208
215 [[nodiscard]] Pump
216 trace(SourceLocationType const& loc = CURRENT_SRC_LOCATION) const;
217
224 [[nodiscard]] Pump
225 debug(SourceLocationType const& loc = CURRENT_SRC_LOCATION) const;
226
233 [[nodiscard]] Pump
234 info(SourceLocationType const& loc = CURRENT_SRC_LOCATION) const;
235
242 [[nodiscard]] Pump
243 warn(SourceLocationType const& loc = CURRENT_SRC_LOCATION) const;
244
251 [[nodiscard]] Pump
252 error(SourceLocationType const& loc = CURRENT_SRC_LOCATION) const;
253
260 [[nodiscard]] Pump
261 fatal(SourceLocationType const& loc = CURRENT_SRC_LOCATION) const;
262};
263
271 static Logger generalLog; /*< Global logger for General channel */
272 static boost::log::filter filter;
273
274public:
275 LogService() = delete;
276
283 [[nodiscard]] static std::expected<void, std::string>
284 init(config::ClioConfigDefinition const& config);
285
292 [[nodiscard]] static Logger::Pump
293 trace(SourceLocationType const& loc = CURRENT_SRC_LOCATION)
294 {
295 return generalLog.trace(loc);
296 }
297
304 [[nodiscard]] static Logger::Pump
305 debug(SourceLocationType const& loc = CURRENT_SRC_LOCATION)
306 {
307 return generalLog.debug(loc);
308 }
309
316 [[nodiscard]] static Logger::Pump
317 info(SourceLocationType const& loc = CURRENT_SRC_LOCATION)
318 {
319 return generalLog.info(loc);
320 }
321
328 [[nodiscard]] static Logger::Pump
329 warn(SourceLocationType const& loc = CURRENT_SRC_LOCATION)
330 {
331 return generalLog.warn(loc);
332 }
333
340 [[nodiscard]] static Logger::Pump
341 error(SourceLocationType const& loc = CURRENT_SRC_LOCATION)
342 {
343 return generalLog.error(loc);
344 }
345
352 [[nodiscard]] static Logger::Pump
353 fatal(SourceLocationType const& loc = CURRENT_SRC_LOCATION)
354 {
355 return generalLog.fatal(loc);
356 }
357
363 [[nodiscard]] static bool
364 enabled();
365};
366
367}; // namespace util
A global logging service.
Definition Logger.hpp:270
static Logger::Pump fatal(SourceLocationType const &loc=CURRENT_SRC_LOCATION)
Globally accessible General logger at Severity::FTL severity.
Definition Logger.hpp:353
static Logger::Pump debug(SourceLocationType const &loc=CURRENT_SRC_LOCATION)
Globally accessible General logger at Severity::DBG severity.
Definition Logger.hpp:305
static std::expected< void, std::string > init(config::ClioConfigDefinition const &config)
Global log core initialization from a config::ClioConfigDefinition.
Definition Logger.cpp:259
static Logger::Pump trace(SourceLocationType const &loc=CURRENT_SRC_LOCATION)
Globally accessible General logger at Severity::TRC severity.
Definition Logger.hpp:293
static Logger::Pump error(SourceLocationType const &loc=CURRENT_SRC_LOCATION)
Globally accessible General logger at Severity::ERR severity.
Definition Logger.hpp:341
static bool enabled()
Whether the LogService is enabled or not.
Definition Logger.cpp:296
static Logger::Pump info(SourceLocationType const &loc=CURRENT_SRC_LOCATION)
Globally accessible General logger at Severity::NFO severity.
Definition Logger.hpp:317
static Logger::Pump warn(SourceLocationType const &loc=CURRENT_SRC_LOCATION)
Globally accessible General logger at Severity::WRN severity.
Definition Logger.hpp:329
A simple thread-safe logger for the channel specified in the constructor.
Definition Logger.hpp:111
Logger(std::string channel)
Construct a new Logger object that produces loglines for the specified channel.
Definition Logger.hpp:195
Pump warn(SourceLocationType const &loc=CURRENT_SRC_LOCATION) const
Interface for logging at Severity::WRN severity.
Definition Logger.cpp:317
Pump error(SourceLocationType const &loc=CURRENT_SRC_LOCATION) const
Interface for logging at Severity::ERR severity.
Definition Logger.cpp:322
Pump fatal(SourceLocationType const &loc=CURRENT_SRC_LOCATION) const
Interface for logging at Severity::FTL severity.
Definition Logger.cpp:327
Pump debug(SourceLocationType const &loc=CURRENT_SRC_LOCATION) const
Interface for logging at Severity::DBG severity.
Definition Logger.cpp:307
Pump trace(SourceLocationType const &loc=CURRENT_SRC_LOCATION) const
Interface for logging at Severity::TRC severity.
Definition Logger.cpp:302
Pump info(SourceLocationType const &loc=CURRENT_SRC_LOCATION) const
Interface for logging at Severity::NFO severity.
Definition Logger.cpp:312
A class representing the source location of the current code.
Definition SourceLocation.hpp:52
All the config data will be stored and extracted from this class.
Definition ConfigDefinition.hpp:54
This namespace implements the data access layer and related components.
Definition AmendmentCenter.cpp:70
This namespace contains various utilities.
Definition AccountUtils.hpp:30
std::ostream & operator<<(std::ostream &stream, Severity sev)
Custom labels for Severity in log output.
Definition Logger.cpp:102
Severity
Custom severity levels for util::Logger.
Definition Logger.hpp:77