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