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 Logger alertLog; /*< Global logger for Alerts channel */
273 static boost::log::filter filter;
274
275public:
276 LogService() = delete;
277
284 [[nodiscard]] static std::expected<void, std::string>
285 init(config::ClioConfigDefinition const& config);
286
293 [[nodiscard]] static Logger::Pump
294 trace(SourceLocationType const& loc = CURRENT_SRC_LOCATION)
295 {
296 return generalLog.trace(loc);
297 }
298
305 [[nodiscard]] static Logger::Pump
306 debug(SourceLocationType const& loc = CURRENT_SRC_LOCATION)
307 {
308 return generalLog.debug(loc);
309 }
310
317 [[nodiscard]] static Logger::Pump
318 info(SourceLocationType const& loc = CURRENT_SRC_LOCATION)
319 {
320 return generalLog.info(loc);
321 }
322
329 [[nodiscard]] static Logger::Pump
330 warn(SourceLocationType const& loc = CURRENT_SRC_LOCATION)
331 {
332 return generalLog.warn(loc);
333 }
334
341 [[nodiscard]] static Logger::Pump
342 error(SourceLocationType const& loc = CURRENT_SRC_LOCATION)
343 {
344 return generalLog.error(loc);
345 }
346
353 [[nodiscard]] static Logger::Pump
354 fatal(SourceLocationType const& loc = CURRENT_SRC_LOCATION)
355 {
356 return generalLog.fatal(loc);
357 }
358
365 [[nodiscard]] static Logger::Pump
366 alert(SourceLocationType const& loc = CURRENT_SRC_LOCATION)
367 {
368 return alertLog.warn(loc);
369 }
370
376 [[nodiscard]] static bool
377 enabled();
378};
379
380}; // namespace util
A global logging service.
Definition Logger.hpp:270
static Logger::Pump alert(SourceLocationType const &loc=CURRENT_SRC_LOCATION)
Globally accesible Alert logger.
Definition Logger.hpp:366
static Logger::Pump fatal(SourceLocationType const &loc=CURRENT_SRC_LOCATION)
Globally accesible General logger at Severity::FTL severity.
Definition Logger.hpp:354
static Logger::Pump debug(SourceLocationType const &loc=CURRENT_SRC_LOCATION)
Globally accesible General logger at Severity::DBG severity.
Definition Logger.hpp:306
static std::expected< void, std::string > init(config::ClioConfigDefinition const &config)
Global log core initialization from a Config.
Definition Logger.cpp:115
static Logger::Pump trace(SourceLocationType const &loc=CURRENT_SRC_LOCATION)
Globally accesible General logger at Severity::TRC severity.
Definition Logger.hpp:294
static Logger::Pump error(SourceLocationType const &loc=CURRENT_SRC_LOCATION)
Globally accesible General logger at Severity::ERR severity.
Definition Logger.hpp:342
static bool enabled()
Whether the LogService is enabled or not.
Definition Logger.cpp:203
static Logger::Pump info(SourceLocationType const &loc=CURRENT_SRC_LOCATION)
Globally accesible General logger at Severity::NFO severity.
Definition Logger.hpp:318
static Logger::Pump warn(SourceLocationType const &loc=CURRENT_SRC_LOCATION)
Globally accesible General logger at Severity::WRN severity.
Definition Logger.hpp:330
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:224
Pump error(SourceLocationType const &loc=CURRENT_SRC_LOCATION) const
Interface for logging at Severity::ERR severity.
Definition Logger.cpp:229
Pump fatal(SourceLocationType const &loc=CURRENT_SRC_LOCATION) const
Interface for logging at Severity::FTL severity.
Definition Logger.cpp:234
Pump debug(SourceLocationType const &loc=CURRENT_SRC_LOCATION) const
Interface for logging at Severity::DBG severity.
Definition Logger.cpp:214
Pump trace(SourceLocationType const &loc=CURRENT_SRC_LOCATION) const
Interface for logging at Severity::TRC severity.
Definition Logger.cpp:209
Pump info(SourceLocationType const &loc=CURRENT_SRC_LOCATION) const
Interface for logging at Severity::NFO severity.
Definition Logger.cpp:219
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:73
Severity
Custom severity levels for util::Logger.
Definition Logger.hpp:77