FERS 0.1.0
The Flexible Extensible Radar Simulator
Loading...
Searching...
No Matches
logging.h
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-only
2//
3// Copyright (c) 2024-present FERS Contributors (see AUTHORS.md).
4//
5// See the GNU GPLv2 LICENSE file in the FERS project root for more information.
6
7/**
8 * @file logging.h
9 * @brief Header file for the logging system.
10 *
11 * This file defines a logging system with multiple log levels, supporting thread-safe logging
12 * to a file or standard output, and allowing formatted log messages with source location details.
13 * The logging system is customizable with log levels and file output for effective debugging
14 * and tracking of events in an application.
15 */
16
17#pragma once
18
19#define LOG(level, ...) log(level, std::source_location::current(), __VA_ARGS__)
20
21#include <atomic>
22#include <cstdint>
23#include <expected>
24#include <format>
25#include <fstream>
26#include <mutex>
27#include <optional>
28#include <source_location>
29#include <string>
30#include <utility>
31
32namespace logging
33{
34 /**
35 * @class Level
36 * @brief Enum class representing the log levels.
37 */
38 enum class Level : std::uint8_t
39 {
40 TRACE, ///< Trace level for detailed debugging information.
41 DEBUG, ///< Debug level for general debugging information.
42 INFO, ///< Info level for informational messages.
43 WARNING, ///< Warning level for potentially harmful situations.
44 ERROR, ///< Error level for error events.
45 FATAL, ///< Fatal level for severe error events.
46 OFF ///< Special level to disable all logging.
47 };
48
49 /**
50 * @class Logger
51 * @brief Thread-safe logger class for handling logging operations.
52 */
53 class Logger
54 {
55 public:
56 using Callback = void (*)(Level level, const std::string& line, void* user_data);
57
58 /**
59 * @brief Sets the logging level.
60 *
61 * @param level The logging level to set.
62 */
63 void setLevel(Level level) noexcept;
64
65 /**
66 * @brief Gets the current logging level.
67 *
68 * @return The current minimum logging level.
69 */
70 [[nodiscard]] Level getLevel() const noexcept;
71
72 /**
73 * @brief Sets an optional callback that receives each formatted log line.
74 *
75 * @param callback Callback to invoke after a log line is accepted, or nullptr to disable.
76 * @param user_data Opaque caller data passed back to the callback.
77 */
78 void setCallback(Callback callback, void* user_data) noexcept;
79
80 /**
81 * @brief Logs a message with a specific log level and source location.
82 *
83 * @param level The log level.
84 * @param message The message to log.
85 * @param location The source location of the log call.
86 */
87 void log(Level level, const std::string& message,
88 const std::source_location& location = std::source_location::current()) noexcept;
89
90 /**
91 * @brief Logs a formatted message with a specific log level and source location.
92 *
93 * @tparam Args Variadic template for format arguments.
94 * @param level The log level.
95 * @param location The source location of the log call.
96 * @param formatStr The format string.
97 * @param args The format arguments.
98 */
99 template <typename... Args>
100 void log(const Level level, const std::source_location& location, const std::string& formatStr,
101 const Args&... args) noexcept
102 {
103 if (level != Level::OFF && level >= getLevel())
104 {
105 const std::string message = std::vformat(formatStr, std::make_format_args(args...));
106 log(level, message, location);
107 }
108 }
109
110 /**
111 * @brief Sets the log file path to log messages to a file.
112 *
113 * @param filePath The path to the log file.
114 * @return std::expected indicating success or error message on failure.
115 */
116 std::expected<void, std::string> logToFile(const std::string& filePath) noexcept;
117
118 private:
119 std::atomic<Level> _log_level{Level::INFO}; ///< Current log level.
120 std::optional<std::ofstream> _log_file; ///< Output file stream for logging to a file.
121 Callback _callback = nullptr; ///< Optional callback for UI/session log streaming.
122 void* _callback_user_data = nullptr; ///< Opaque data passed to the callback.
123 std::mutex _log_mutex; ///< Mutex for thread-safe logging.
124
125 /**
126 * @brief Gets the current timestamp as a string.
127 *
128 * @return The current timestamp.
129 */
130 static std::string getCurrentTimestamp() noexcept;
131 };
132
133 /**
134 * @brief Externally available logger object.
135 */
136 extern Logger logger;
137
138 /**
139 * @brief Converts a log level enum value to its string representation.
140 *
141 * @param level The log level.
142 * @return A string representing the log level.
143 */
144 inline std::string getLevelString(const Level level) noexcept
145 {
146 switch (level)
147 {
148 case Level::TRACE:
149 return "TRACE";
150 case Level::DEBUG:
151 return "DEBUG";
152 case Level::INFO:
153 return "INFO";
154 case Level::WARNING:
155 return "WARNING";
156 case Level::ERROR:
157 return "ERROR";
158 case Level::FATAL:
159 return "FATAL";
160 case Level::OFF:
161 return "OFF";
162 default:
163 return "UNKNOWN";
164 }
165 }
166
167 /**
168 * @brief Logs a formatted message with a specific log level and source location.
169 *
170 * @tparam Args Variadic template for format arguments.
171 * @param level The log level.
172 * @param location The source location of the log call.
173 * @param formatStr The format string.
174 * @param args The format arguments.
175 */
176 template <typename... Args>
177 void log(Level level, const std::source_location& location, const std::string& formatStr, Args&&... args) noexcept
178 {
179 logger.log(level, location, formatStr, std::forward<Args>(args)...);
180 }
181}
Enum class representing the log levels.
Thread-safe logger class for handling logging operations.
Definition logging.h:54
void log(Level level, const std::string &message, const std::source_location &location=std::source_location::current()) noexcept
Logs a message with a specific log level and source location.
Definition logging.cpp:45
std::expected< void, std::string > logToFile(const std::string &filePath) noexcept
Sets the log file path to log messages to a file.
Definition logging.cpp:90
void setCallback(Callback callback, void *user_data) noexcept
Sets an optional callback that receives each formatted log line.
Definition logging.cpp:83
void setLevel(Level level) noexcept
Sets the logging level.
Definition logging.cpp:25
void(*)(Level level, const std::string &line, void *user_data) Callback
Definition logging.h:56
Level getLevel() const noexcept
Gets the current logging level.
Definition logging.cpp:27
@ WARNING
Warning level for potentially harmful situations.
@ FATAL
Fatal level for severe error events.
@ TRACE
Trace level for detailed debugging information.
@ INFO
Info level for informational messages.
@ OFF
Special level to disable all logging.
@ ERROR
Error level for error events.
@ DEBUG
Debug level for general debugging information.
std::string getLevelString(const Level level) noexcept
Converts a log level enum value to its string representation.
Definition logging.h:144
Logger logger
Externally available logger object.
Definition logging.cpp:23