NeoN
A framework for CFD software
Loading...
Searching...
No Matches
logging.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2025 - 2026 NeoN authors
2//
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
7#include <chrono>
8#include <source_location>
9#include <memory>
10#include <string>
11#include <string_view>
12
13#include <fmt/core.h>
14#include <fmt/chrono.h>
15
17
18namespace NeoN::Logging
19{
20
21
31
33{
35 File
36};
37
42{
43
44public:
45
46 LogEvent(std::source_location locationIn, Level levelIn, std::string_view messageIn)
47 : location(locationIn), level(levelIn), message(messageIn)
48 {
49 creationTS = std::chrono::steady_clock::now();
50 }
51
52 std::source_location location; // where log message was created
53
54 Level level; // the level the event represents e.g. Trace, Debug, ...
55
56 std::string message; // log message
57
58 std::chrono::time_point<std::chrono::steady_clock> creationTS; // store time of constructor call
59
61 std::string toJson(std::string_view delim)
62 {
63 auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(
64 std::chrono::steady_clock::now() - creationTS
65 );
66
67 return fmt::format(
68 fmt::runtime(
69 "{{\n\"message\": \"{}\",\n\"sourceLocation\": \"{}:{}\",\n\"timeStarted\": "
70 "\"{}\",\n\"duration\": \"{:m}ms\"\n}}{}"
71 ),
72 message,
73 location.file_name(),
74 location.line(),
75 creationTS.time_since_epoch(),
76 duration,
77 delim
78 );
79 }
80};
81
88
90 std::string sv, [[maybe_unused]] Level level, [[maybe_unused]] std::string logName = "NeoN"
91);
92
93[[noreturn]] void terminate();
94
95namespace detail
96{
97
107bool shouldLog(Level level, std::string logName = "NeoN");
108
109/* @brief Log a fatal message (rank-tagged) and terminate the program.
110 *
111 * In MPI runs this aborts the communicator so peers do not deadlock on a
112 * collective. Used by NF_ERROR_EXIT / NF_ASSERT (core/error.hpp) and error().
113 */
114[[noreturn]] void logFatal(const std::string& message);
115
116}
117
119template<typename... Args>
120void info(std::string formatString, Args... args)
121{
122 if (!detail::shouldLog(Level::Info)) return;
123 logImpl(fmt::format(fmt::runtime(formatString), args...), Level::Info);
124}
125
127template<typename... Args>
128void warn(std::string formatString, Args... args)
129{
130 if (!detail::shouldLog(Level::Warning)) return;
131 logImpl(fmt::format(fmt::runtime(formatString), args...), Level::Warning);
132}
133
135template<typename... Args>
136void debug(std::string formatString, Args... args)
137{
138 if (!detail::shouldLog(Level::Debug)) return;
139 logImpl(fmt::format(fmt::runtime(formatString), args...), Level::Debug);
140}
141
142namespace detail
143{
149{
150 std::string_view fmt;
151 std::source_location loc;
152 FatalFormat(const char* f, std::source_location l = std::source_location::current())
153 : fmt(f), loc(l)
154 {}
155 FatalFormat(std::string_view f, std::source_location l = std::source_location::current())
156 : fmt(f), loc(l)
157 {}
158 FatalFormat(const std::string& f, std::source_location l = std::source_location::current())
159 : fmt(f), loc(l)
160 {}
161};
162}
163
165template<typename... Args>
166[[noreturn]] void error(detail::FatalFormat fmtLoc, Args... args)
167{
168 auto message = fmt::format(fmt::runtime(fmtLoc.fmt), args...);
169 detail::logFatal(fmt::format("{}:{} {}", fmtLoc.loc.file_name(), fmtLoc.loc.line(), message));
170}
171
175{
176
177 Target target_;
178
179public:
180
181 BaseLogger() : target_(Target::Console) {};
182
183 BaseLogger(Target target) : target_(target) {};
184
185 virtual ~BaseLogger() = default;
186
187 virtual void log(std::string) const = 0;
188
189 Target getTarget() const { return target_; };
190};
191
193inline void log(std::shared_ptr<BaseLogger> logger, LogEvent& event, std::string_view delim = ",")
194{
195 if (logger != nullptr)
196 {
197 // console output
198 auto formattedMessage =
199 logger->getTarget() == Target::Console ? event.message : event.toJson(delim);
200
201 logger->log(formattedMessage);
202 }
203}
204
205
208class Logger : public BaseLogger
209{
210
211public:
212
213 Logger(std::string name, Level level, Target target);
214
216
217 void log(std::string sv) const override;
218
219private:
220
221 // name of the logger in the spdlog registry
222 std::string name_;
223
224 Level level_;
225};
226
229{
230
231private:
232
233 std::shared_ptr<BaseLogger> logger_;
234
235public:
236
237 void setLogger(const std::shared_ptr<BaseLogger> logger);
238
239 std::shared_ptr<const BaseLogger> getLogger() const;
240};
241
242template<typename CallClass>
243void setLogger(CallClass& cls, std::shared_ptr<BaseLogger> logger)
244{
245 cls.setLogger(logger);
246}
247}
virtual ~BaseLogger()=default
BaseLogger(Target target)
Definition logging.hpp:183
Target getTarget() const
Definition logging.hpp:189
virtual void log(std::string) const =0
A class to represent a LogEvent.
Definition logging.hpp:42
std::string toJson(std::string_view delim)
convert event to a json string
Definition logging.hpp:61
LogEvent(std::source_location locationIn, Level levelIn, std::string_view messageIn)
Definition logging.hpp:46
std::source_location location
Definition logging.hpp:52
std::chrono::time_point< std::chrono::steady_clock > creationTS
Definition logging.hpp:58
Logger(std::string name, Level level, Target target)
void log(std::string sv) const override
a Logging Mixin class that allows to attach logger to certain classes
Definition logging.hpp:229
void setLogger(const std::shared_ptr< BaseLogger > logger)
std::shared_ptr< const BaseLogger > getLogger() const
bool shouldLog(Level level, std::string logName="NeoN")
Returns whether a message at the given level would actually be emitted by the named logger.
void logFatal(const std::string &message)
void setLogger(CallClass &cls, std::shared_ptr< BaseLogger > logger)
Definition logging.hpp:243
void log(std::shared_ptr< BaseLogger > logger, LogEvent &event, std::string_view delim=",")
convenience function to call log on logger with std::format
Definition logging.hpp:193
void setNeonDefaultPattern()
void info(std::string formatString, Args... args)
convenience function to call spdlogs info with std::format
Definition logging.hpp:120
void error(detail::FatalFormat fmtLoc, Args... args)
Log a fatal formatted message (with the caller's file:line) and abort.
Definition logging.hpp:166
void terminate()
void warn(std::string formatString, Args... args)
convenience function to call spdlogs warn with std::format
Definition logging.hpp:128
void debug(std::string formatString, Args... args)
convenience function to call spdlogs debug with std::format
Definition logging.hpp:136
void logImpl(std::string sv, Level level, std::string logName="NeoN")
const std::string & name(const NeoN::Document &doc)
Retrieves the name of a Document.
FatalFormat(const std::string &f, std::source_location l=std::source_location::current())
Definition logging.hpp:158
FatalFormat(const char *f, std::source_location l=std::source_location::current())
Definition logging.hpp:152
FatalFormat(std::string_view f, std::source_location l=std::source_location::current())
Definition logging.hpp:155