ChainCLI
A modern C++20 command-line interface library
Loading...
Searching...
No Matches
logger.h
1/*
2 * Copyright 2025 Dominik Czekai
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18#include <functional>
19#include <memory>
20#include <unordered_map>
21#include <vector>
22
23#include "handler.h"
24#include "log_streambuffer.h"
25
26namespace cli::logging
27{
28
31{
32public:
33 virtual ~AbstractLogger() = default;
34
37 virtual void setLevel(LogLevel lvl) = 0;
38
41 virtual void addHandler(std::unique_ptr<AbstractHandler> handlerPtr) = 0;
42
44 virtual void removeAllHandlers() = 0;
45
49 virtual void log(LogLevel lvl, const std::string &message) const = 0;
50
54 virtual std::ostream &getStream(LogLevel lvl) = 0;
55
62 template <typename... Args> void log(LogLevel lvl, const std::string &fmt, Args &&...args) const
63 {
64 std::string formatted = std::vformat(fmt, std::make_format_args(args...));
65 log(lvl, formatted);
66 }
67
68#pragma region LogLevelShortcuts
69
74 template <typename... Args> void trace(const std::string &fmt, Args &&...args)
75 {
76 log(LogLevel::TRACE, fmt, std::forward<Args>(args)...);
77 }
78
83 template <typename... Args> void verbose(const std::string &fmt, Args &&...args)
84 {
85 log(LogLevel::VERBOSE, fmt, std::forward<Args>(args)...);
86 }
87
92 template <typename... Args> void debug(const std::string &fmt, Args &&...args)
93 {
94 log(LogLevel::DEBUG, fmt, std::forward<Args>(args)...);
95 }
96
101 template <typename... Args> void success(const std::string &fmt, Args &&...args)
102 {
103 log(LogLevel::SUCCESS, fmt, std::forward<Args>(args)...);
104 }
105
110 template <typename... Args> void info(const std::string &fmt, Args &&...args)
111 {
112 log(LogLevel::INFO, fmt, std::forward<Args>(args)...);
113 }
114
119 template <typename... Args> void warning(const std::string &fmt, Args &&...args)
120 {
121 log(LogLevel::WARNING, fmt, std::forward<Args>(args)...);
122 }
123
128 template <typename... Args> void error(const std::string &fmt, Args &&...args)
129 {
130 log(LogLevel::ERROR, fmt, std::forward<Args>(args)...);
131 }
132
133#pragma endregion LogLevelShortcuts
134
135#pragma region LogStreamShortcuts
136
139 std::ostream &trace() { return getStream(LogLevel::TRACE); }
140
143 std::ostream &verbose() { return getStream(LogLevel::VERBOSE); }
144
147 std::ostream &debug() { return getStream(LogLevel::DEBUG); }
148
151 std::ostream &success() { return getStream(LogLevel::SUCCESS); }
152
155 std::ostream &info() { return getStream(LogLevel::INFO); }
156
159 std::ostream &warning() { return getStream(LogLevel::WARNING); }
160
163 std::ostream &error() { return getStream(LogLevel::ERROR); }
164
165#pragma endregion LogStreamShortcuts
166};
167
169class Logger : public AbstractLogger
170{
171public:
172 ~Logger() override = default;
173 // Non-copyable
174 Logger(const Logger &) = delete;
175 Logger &operator=(const Logger &) = delete;
176
177 Logger(Logger &&) = default;
178 Logger &operator=(Logger &&) = default;
179
182 explicit Logger(LogLevel lvl = LogLevel::TRACE);
183
186 void setLevel(LogLevel lvl) override;
187
190 void addHandler(std::unique_ptr<AbstractHandler> handlerPtr) override;
191
193 void removeAllHandlers() override { handlers.clear(); }
194
195 void log(LogLevel lvl, const std::string& msg) const override;
196
197 std::ostream& getStream(LogLevel lvl) override;
198
199private:
200 LogLevel minLevel;
201 std::vector<std::unique_ptr<AbstractHandler>> handlers;
202
203 // Per-level stream buffers & streams
204 std::unordered_map<LogLevel, std::unique_ptr<LogStreamBuf>> buffers;
205 std::unordered_map<LogLevel, std::unique_ptr<std::ostream>> streams;
206};
207} // namespace cli::logging
Abstract base class for logger implementations.
Definition logger.h:31
virtual void removeAllHandlers()=0
Remove all log handlers.
virtual void setLevel(LogLevel lvl)=0
Set the minimum log level for this logger.
std::ostream & trace()
Get the stream for the TRACE log level.
Definition logger.h:139
void warning(const std::string &fmt, Args &&...args)
Log a message at the WARNING level.
Definition logger.h:119
void verbose(const std::string &fmt, Args &&...args)
Log a message at the VERBOSE level.
Definition logger.h:83
void trace(const std::string &fmt, Args &&...args)
Log a message at the TRACE level.
Definition logger.h:74
virtual void log(LogLevel lvl, const std::string &message) const =0
Log a message at the specified log level.
void info(const std::string &fmt, Args &&...args)
Log a message at the INFO level.
Definition logger.h:110
void debug(const std::string &fmt, Args &&...args)
Log a message at the DEBUG level.
Definition logger.h:92
std::ostream & verbose()
Get the stream for the VERBOSE log level.
Definition logger.h:143
std::ostream & error()
Get the stream for the ERROR log level.
Definition logger.h:163
std::ostream & success()
Get the stream for the SUCCESS log level.
Definition logger.h:151
void log(LogLevel lvl, const std::string &fmt, Args &&...args) const
Log a message at the specified log level using a format string to print the passed arguments.
Definition logger.h:62
std::ostream & debug()
Get the stream for the DEBUG log level.
Definition logger.h:147
void error(const std::string &fmt, Args &&...args)
Log a message at the ERROR level.
Definition logger.h:128
std::ostream & warning()
Get the stream for the WARNING log level.
Definition logger.h:159
virtual std::ostream & getStream(LogLevel lvl)=0
Get the stream for the specified log level.
std::ostream & info()
Get the stream for the INFO log level.
Definition logger.h:155
virtual void addHandler(std::unique_ptr< AbstractHandler > handlerPtr)=0
Add a log handler.
void success(const std::string &fmt, Args &&...args)
Log a message at the SUCCESS level.
Definition logger.h:101
Logger class for handling log messages.
Definition logger.h:170
void removeAllHandlers() override
Remove all log handlers.
Definition logger.h:193
std::ostream & getStream(LogLevel lvl) override
Get the stream for the specified log level.
Definition logger.cpp:66
void addHandler(std::unique_ptr< AbstractHandler > handlerPtr) override
Add a log handler.
Definition logger.cpp:49
void log(LogLevel lvl, const std::string &msg) const override
Log a message at the specified log level.
Definition logger.cpp:54
void setLevel(LogLevel lvl) override
Set the minimum log level for this logger.
Definition logger.cpp:40