45#include "input_output/FGXMLElement.h"
49thread_local FGLogger_ptr GlobalLogger = std::make_shared<FGLogConsole>();
51void SetLogger(FGLogger_ptr logger) { GlobalLogger = logger; }
52FGLogger_ptr
GetLogger(
void) {
return GlobalLogger; }
54const char highint[5] = {27,
'[',
'1',
'm',
'\0' };
55const char halfint[5] = {27,
'[',
'2',
'm',
'\0' };
56const char normint[6] = {27,
'[',
'2',
'2',
'm',
'\0' };
57const char reset[5] = {27,
'[',
'0',
'm',
'\0' };
58const char underon[5] = {27,
'[',
'4',
'm',
'\0' };
59const char underoff[6] = {27,
'[',
'2',
'4',
'm',
'\0' };
60const char fgblue[6] = {27,
'[',
'3',
'4',
'm',
'\0' };
61const char fgcyan[6] = {27,
'[',
'3',
'6',
'm',
'\0' };
62const char fgred[6] = {27,
'[',
'3',
'1',
'm',
'\0' };
63const char fggreen[6] = {27,
'[',
'3',
'2',
'm',
'\0' };
64const char fgdef[6] = {27,
'[',
'3',
'9',
'm',
'\0' };
74 void FileLocation(
const std::string& filename,
int line)
override {
75 this->filename = filename;
78 void Message(
const std::string& message)
override;
79 void Format(LogFormat format)
override;
80 const char* c_str(
void)
const noexcept {
return logMessageBuffer; }
81 ~BufferLogger()
override;
86 std::string_view messageItem;
87 LogFormat format = LogFormat::DEFAULT;
90 char logMessageBuffer[1024];
91 size_t bufferUsed = 0;
92 std::vector<MessageToken> tokens;
100 if (message.empty())
return;
102 size_t available =
sizeof(logMessageBuffer) - bufferUsed - 1;
103 size_t toCopy = std::min(message.size(), available);
107 char* currentPos = logMessageBuffer + bufferUsed;
108 memcpy(currentPos, message.c_str(), toCopy);
109 bufferUsed += toCopy;
110 logMessageBuffer[bufferUsed] =
'\0';
112 auto& new_token = tokens.emplace_back();
113 new_token.messageItem = std::string_view(currentPos, toCopy);
121 auto& new_token = tokens.emplace_back();
122 new_token.format = format;
127BufferLogger::~BufferLogger()
129 if (tokens.empty())
return;
131 GlobalLogger->SetLevel(log_level);
133 if (line > 0) GlobalLogger->FileLocation(filename, line);
135 for (
const auto& token : tokens) {
136 if (token.messageItem.empty()) {
137 GlobalLogger->Format(token.format);
140 GlobalLogger->Message(std::string(token.messageItem));
142 GlobalLogger->Flush();
147FGLogging::FGLogging(LogLevel level)
148 : logger(GlobalLogger)
150 logger->SetLevel(level);
155void FGLogging::Flush(
void)
157 std::string message = buffer.str();
159 if (!message.empty()) {
160 logger->Message(message);
169FGLogging& FGLogging::operator<<(LogFormat format)
171 std::string message = buffer.str();
173 if (!message.empty()) {
174 logger->Message(message);
178 logger->Format(format);
184FGXMLLogging::FGXMLLogging(Element* el, LogLevel level)
187 logger->FileLocation(el->GetFileName(), el->GetLineNumber());
193 if (log_level >= min_level || log_level == LogLevel::STDOUT) {
197 case LogLevel::DEBUG:
199 case LogLevel::STDOUT:
216 if (!highlighting)
return;
221 buffer.append(fgred);
223 case LogFormat::BLUE:
224 buffer.append(fgblue);
226 case LogFormat::GREEN:
227 buffer.append(fggreen);
229 case LogFormat::CYAN:
230 buffer.append(fgcyan);
232 case LogFormat::BOLD:
233 buffer.append(highint);
235 case LogFormat::NORMAL:
236 buffer.append(normint);
238 case LogFormat::UNDERLINE_ON:
239 buffer.append(underon);
241 case LogFormat::UNDERLINE_OFF:
242 buffer.append(underoff);
244 case LogFormat::DEFAULT:
245 buffer.append(fgdef);
247 case LogFormat::RESET:
249 buffer.append(reset);
256LogException::LogException()
259 logger->SetLevel(LogLevel::FATAL);
264LogException::LogException(LogException& other)
265: BaseException(
""), FGLogging(other.logger)
272const char* LogException::what() const noexcept
279 const_cast<LogException*
>(
this)->Flush();
280 return static_cast<BufferLogger*
>(logger.get())->c_str();
285XMLLogException::XMLLogException(Element* el)
288 logger->FileLocation(el->GetFileName(), el->GetLineNumber());
void Message(const std::string &message) override
Appends message text. May be called multiple times per log record.
void FileLocation(const std::string &filename, int line) override
Optionally provides source filename and line for contextual diagnostics.
void Format(LogFormat format) override
Applies a formatting hint to subsequent output.
int GetLineNumber(void) const
Returns the line number at which the element has been defined.
const std::string & GetFileName(void) const
Returns the name of the file in which the element has been read.
void Flush(void) override
Ends the current log record and commits any buffered output.
void Format(LogFormat format) override
Applies a formatting hint to subsequent output.
Logging backend interface.
Main namespace for the JSBSim Flight Dynamics Model.
FGLogger_ptr GetLogger(void)
Returns the active logger for the current thread.
void SetLogger(FGLogger_ptr logger)
Sets the active logger for the current thread.