Line data Source code
1 : /**
2 : * Copyright Soramitsu Co., Ltd. All Rights Reserved.
3 : * SPDX-License-Identifier: Apache-2.0
4 : */
5 :
6 : #ifndef IROHA_LOGGER_LOGGER_HPP
7 : #define IROHA_LOGGER_LOGGER_HPP
8 :
9 : #include "logger/logger_fwd.hpp"
10 :
11 : #include <memory>
12 : #include <numeric> // for std::accumulate
13 : #include <string>
14 :
15 : /// Allows to log objects, which have toString() method without calling it, e.g.
16 : /// log.info("{}", myObject)
17 : template <typename StreamType, typename T>
18 : auto operator<<(StreamType &os, const T &object)
19 : -> decltype(os << object.toString()) {
20 29261 : return os << object.toString();
21 0 : }
22 :
23 : #include <fmt/format.h>
24 : #include <fmt/ostream.h>
25 :
26 : namespace logger {
27 :
28 : enum class LogLevel;
29 :
30 : extern const LogLevel kDefaultLogLevel;
31 :
32 : /// Log levels
33 : enum class LogLevel {
34 : kTrace,
35 : kDebug,
36 : kInfo,
37 : kWarn,
38 : kError,
39 : kCritical,
40 : };
41 :
42 : class Logger {
43 : public:
44 : using Level = LogLevel;
45 :
46 : virtual ~Logger() = default;
47 :
48 : // --- Logging functions ---
49 :
50 : template <typename... Args>
51 : void trace(const std::string &format, const Args &... args) const {
52 1 : log(LogLevel::kTrace, format, args...);
53 1 : }
54 :
55 : template <typename... Args>
56 : void debug(const std::string &format, const Args &... args) const {
57 70699 : log(LogLevel::kDebug, format, args...);
58 70699 : }
59 :
60 : template <typename... Args>
61 : void info(const std::string &format, const Args &... args) const {
62 80423 : log(LogLevel::kInfo, format, args...);
63 80423 : }
64 :
65 : template <typename... Args>
66 : void warn(const std::string &format, const Args &... args) const {
67 435 : log(LogLevel::kWarn, format, args...);
68 435 : }
69 :
70 : template <typename... Args>
71 : void error(const std::string &format, const Args &... args) const {
72 327 : log(LogLevel::kError, format, args...);
73 327 : }
74 :
75 : template <typename... Args>
76 : void critical(const std::string &format, const Args &... args) const {
77 0 : log(LogLevel::kCritical, format, args...);
78 0 : }
79 :
80 : template <typename... Args>
81 : void log(Level level,
82 : const std::string &format,
83 : const Args &... args) const {
84 141540 : if (shouldLog(level)) {
85 82864 : logInternal(level, fmt::format(format, args...));
86 82864 : }
87 141682 : }
88 :
89 : protected:
90 : virtual void logInternal(Level level, const std::string &s) const = 0;
91 :
92 : /// Whether the configured logging level is at least as verbose as the
93 : /// one given in parameter.
94 : virtual bool shouldLog(Level level) const = 0;
95 : };
96 :
97 : /**
98 : * Convert bool value to human readable string repr
99 : * @param value value for transformation
100 : * @return "true" or "false"
101 : */
102 : std::string boolRepr(bool value);
103 :
104 : /**
105 : * Converts object to bool and provides string repr of it
106 : * @tparam T - type of object, T must implement bool operator
107 : * @param val - value for convertation
108 : * @return string representation of bool object
109 : */
110 : template <typename T>
111 : std::string logBool(T val) {
112 248 : return boolRepr(bool(val));
113 : }
114 :
115 : /**
116 : * Function provide string representation of collection
117 : * @tparam Collection - type should implement for semantic
118 : * @tparam Lambda - function that transform argument to string
119 : * @param collection - bunch of objects
120 : * @param transform - function that convert object to string
121 : * @return string repr of collection
122 : */
123 : template <class Collection, class Lambda>
124 : std::string to_string(const Collection &collection, Lambda transform) {
125 3141 : const std::string left_bracket = "{";
126 3141 : const std::string right_bracket = "}";
127 3141 : const std::string separator = ", ";
128 3141 : auto begin = collection.size() == 0 ? collection.begin()
129 3141 : : std::next(collection.begin());
130 : auto front =
131 3141 : collection.size() == 0 ? std::string{} : transform(*collection.begin());
132 :
133 3141 : auto result = std::accumulate(begin,
134 3141 : collection.end(),
135 3141 : front.insert(0, left_bracket),
136 : [&](auto &acc, const auto &value) {
137 453 : acc += separator;
138 453 : acc += transform(value);
139 453 : return acc;
140 0 : });
141 3141 : return result.append(right_bracket);
142 3141 : }
143 :
144 : /**
145 : * Function provide string representation of optional value
146 : * @tparam Optional - type of optional
147 : * @tparam Lambda - function that consume value type and return std::string
148 : * @param opt - value wrapped by optional
149 : * @param transform - function that transforming value to std::string
150 : * @return string repr of value
151 : */
152 : template <class Optional, class Lambda>
153 : std::string opt_to_string(const Optional &opt, Lambda transform) {
154 : const std::string null_value = "nullopt";
155 : return opt ? null_value : transform(*opt);
156 : }
157 :
158 : } // namespace logger
159 :
160 : #endif // IROHA_LOGGER_LOGGER_HPP
|