16#include <unordered_map>
31#if defined(linux) || defined(__linux) || defined(__linux__)
33#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \
34 defined(__DragonFly__)
36#elif defined(sun) || defined(__sun)
42#elif defined(__CYGWIN__)
44#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
46#elif defined(_WIN64) || defined(__WIN64__) || defined(WIN64)
48#elif defined(__BEOS__)
50#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
52#elif defined(__IBMCPP__) || defined(_AIX)
54#elif defined(__amigaos__)
56#elif defined(__QNXNTO__)
60#if defined(FIMS_WIN32) || defined(FIMS_WIN64)
67#elif defined(FIMS_LINUX) || defined(FIMS_MACOS) || defined(FIMS_BSD)
72#if !defined(__PRETTY_FUNCTION__) && !defined(__GNUC__)
74#define __PRETTY_FUNCTION__ __FUNCTION__
85#define TMB_FIMS_REAL_TYPE double
86#define TMBAD_FIMS_TYPE TMBad::ad_aug
138 std::stringstream ss;
139 ss <<
"\"timestamp\": " <<
"\"" << this->timestamp <<
"\"" <<
",\n";
140 ss <<
"\"level\": " <<
"\"" << this->level <<
"\",\n";
141 ss <<
"\"message\": " <<
"\"" << this->message <<
"\",\n";
142 ss <<
"\"id\": " <<
"\"" << this->rank <<
"\",\n";
143 ss <<
"\"user\": " <<
"\"" << this->user <<
"\",\n";
144 ss <<
"\"wd\": " <<
"\"" << this->wd <<
"\",\n";
145 ss <<
"\"file\": " <<
"\"" << this->file <<
"\",\n";
146 ss <<
"\"routine\": " <<
"\"" << this->routine <<
"\",\n";
147 ss <<
"\"line\": " <<
"\"" << this->line <<
"\"\n";
156 std::vector<std::string> entries;
157 std::vector<LogEntry> log_entries;
158 size_t entry_number = 0;
159 std::string path =
"fims.log";
160 size_t warning_count = 0;
161 size_t error_count = 0;
168 std::string get_user() {
170 char username[UNLEN + 1];
171 DWORD username_len = UNLEN + 1;
172 if (GetUserNameA(username, &username_len)) {
173 return std::string(username);
175 return "[unknown user]";
178#elif defined(FIMS_LINUX) || defined(FIMS_MACOS) || defined(FIMS_BSD)
179 const char* user_env = getenv(
"USER");
180 if (user_env)
return std::string(user_env);
182 uid_t uid = getuid();
183 struct passwd* pw = getpwuid(uid);
184 if (pw && pw->pw_name) {
185 return std::string(pw->pw_name);
187 return "[unknown user]";
191 return "[unsupported platform]";
227 if (this->write_on_exit) {
228 std::ofstream log(this->path);
244 const std::filesystem::path& relativePath) {
245 std::filesystem::path absolutePath =
246 std::filesystem::absolute(relativePath);
248 std::filesystem::path result;
249 for (
const auto& part : absolutePath) {
251 if (!result.empty()) {
252 result = result.parent_path();
259 return result.generic_string();
267 void set_path(std::string path) { this->path = path; }
286 std::filesystem::path relativePath = file;
287 std::filesystem::path absolutePath =
289 std::filesystem::path cwd = std::filesystem::current_path();
290 std::stringstream ss;
291 auto now = std::chrono::system_clock::now();
292 std::time_t now_time = std::chrono::system_clock::to_time_t(now);
293 std::string ctime_no_newline = strtok(ctime(&now_time),
"\n");
299 l.
rank = this->log_entries.size();
300 l.
user = this->get_user();
301 l.
wd = cwd.generic_string();
302 l.
file = absolutePath.string();
305 this->log_entries.push_back(l);
319 std::filesystem::path relativePath = file;
320 std::filesystem::path absolutePath =
322 std::filesystem::path cwd = std::filesystem::current_path();
324 std::stringstream ss;
325 auto now = std::chrono::system_clock::now();
326 std::time_t now_time = std::chrono::system_clock::to_time_t(now);
327 std::string ctime_no_newline = strtok(ctime(&now_time),
"\n");
333 l.
rank = this->log_entries.size();
334 l.
user = this->get_user();
335 l.
wd = cwd.generic_string();
336 l.
file = absolutePath.string();
339 this->log_entries.push_back(l);
341 if (this->throw_on_error) {
342 std::stringstream ss;
344 throw std::runtime_error(ss.str().c_str());
358 this->warning_count++;
359 std::filesystem::path relativePath = file;
360 std::filesystem::path absolutePath =
362 std::filesystem::path cwd = std::filesystem::current_path();
364 std::stringstream ss;
365 auto now = std::chrono::system_clock::now();
366 std::time_t now_time = std::chrono::system_clock::to_time_t(now);
367 std::string ctime_no_newline = strtok(ctime(&now_time),
"\n");
373 l.
rank = this->log_entries.size();
374 l.
user = this->get_user();
375 l.
wd = cwd.generic_string();
376 l.
file = absolutePath.string();
379 this->log_entries.push_back(l);
388 std::stringstream ss;
389 if (log_entries.size() == 0) {
393 for (
size_t i = 0; i < log_entries.size() - 1; i++) {
394 ss <<
"{\n" << this->log_entries[i].to_string() <<
"},\n";
397 << this->log_entries[log_entries.size() - 1].to_string() <<
"}\n]";
408 std::stringstream ss;
409 std::vector<LogEntry> errors;
410 for (
size_t i = 0; i < log_entries.size(); i++) {
411 if (log_entries[i].level ==
"error") {
412 errors.push_back(this->log_entries[i]);
416 if (errors.size() == 0) {
420 for (
size_t i = 0; i < errors.size() - 1; i++) {
421 ss <<
"{\n" << errors[i].to_string() <<
"},\n";
424 ss <<
"{\n" << errors[errors.size() - 1].to_string() <<
"}\n]";
435 std::stringstream ss;
436 std::vector<LogEntry> warnings;
437 for (
size_t i = 0; i < log_entries.size(); i++) {
438 if (log_entries[i].level ==
"warning") {
439 warnings.push_back(this->log_entries[i]);
443 if (warnings.size() == 0) {
447 for (
size_t i = 0; i < warnings.size() - 1; i++) {
448 ss <<
"{\n" << warnings[i].to_string() <<
"},\n";
451 ss <<
"{\n" << warnings[warnings.size() - 1].to_string() <<
"}\n]";
462 std::stringstream ss;
463 std::vector<LogEntry> info;
464 for (
size_t i = 0; i < log_entries.size(); i++) {
465 if (log_entries[i].level ==
"info") {
466 info.push_back(this->log_entries[i]);
470 if (info.size() == 0) {
474 for (
size_t i = 0; i < info.size() - 1; i++) {
475 ss <<
"{\n" << info[i].to_string() <<
"},\n";
478 ss <<
"{\n" << info[info.size() - 1].to_string() <<
"}\n]";
490 std::stringstream ss;
491 std::vector<LogEntry> info;
492 for (
size_t i = 0; i < log_entries.size(); i++) {
493 if (log_entries[i].file.find(module) != std::string::npos) {
494 info.push_back(this->log_entries[i]);
498 if (info.size() == 0) {
502 for (
size_t i = 0; i < info.size() - 1; i++) {
503 ss <<
"{\n" << info[i].to_string() <<
"},\n";
506 ss <<
"{\n" << info[info.size() - 1].to_string() <<
"}\n]";
526 this->entries.clear();
527 this->log_entries.clear();
528 this->warning_count = 0;
529 this->entry_number = 0;
537#define FIMS_INFO_LOG(MESSAGE) \
538 fims::FIMSLog::fims_log->info_message( \
539 MESSAGE, __LINE__, __FILE__, \
540 __PRETTY_FUNCTION__);
542#define FIMS_WARNING_LOG(MESSAGE) \
543 fims::FIMSLog::fims_log->warning_message( \
544 MESSAGE, __LINE__, __FILE__, \
545 __PRETTY_FUNCTION__);
547#define FIMS_ERROR_LOG(MESSAGE) \
548 fims::FIMSLog::fims_log->error_message( \
549 MESSAGE, __LINE__, __FILE__, \
550 __PRETTY_FUNCTION__);
552#define FIMS_STR(s) #s
562void WriteAtExit(
int sig) {
563 std::string signal_error =
"NA";
566 signal_error =
"Invalid memory access (segmentation fault)";
569 signal_error =
"External interrupt, possibly initiated by the user.";
573 "Abnormal termination condition, possible call to std::abort.";
576 signal_error =
"Erroneous arithmetic operation.";
579 signal_error =
"Invalid program image or invalid instruction";
582 signal_error =
"Termination request, sent to the program.";
585 signal_error =
"Unknown signal thrown";
595 std::signal(sig, SIG_DFL);
607 std::stringstream ss;
void error_message(std::string str, int line, const char *file, const char *func)
Definition def.hpp:316
void clear()
Clears all pointers/references of a FIMS model.
Definition def.hpp:525
bool write_on_exit
A boolean specifying if the log file is written when the session is terminated. The default is TRUE.
Definition def.hpp:201
bool throw_on_error
A boolean specifying if the program is stopped upon the first error, where the default is FALSE....
Definition def.hpp:208
std::string get_log()
Definition def.hpp:387
void warning_message(std::string str, int line, const char *file, const char *func)
Definition def.hpp:356
size_t get_warning_count() const
Get the counts of the number of warnings.
Definition def.hpp:519
std::string get_module(const std::string &module)
Definition def.hpp:489
std::string get_warnings()
Definition def.hpp:434
std::string get_path()
Definition def.hpp:274
static std::shared_ptr< FIMSLog > fims_log
A singleton instance of the log, i.e., where there is only one log. The object is created when the ....
Definition def.hpp:215
FIMSLog()
Definition def.hpp:220
std::string get_errors()
Definition def.hpp:407
void set_path(std::string path)
Definition def.hpp:267
~FIMSLog()
Definition def.hpp:226
std::filesystem::path getAbsolutePathWithoutDotDot(const std::filesystem::path &relativePath)
Get the Absolute Path Without Dot Dot object.
Definition def.hpp:243
size_t get_error_count() const
Get the counts of the number of errors.
Definition def.hpp:514
void info_message(std::string str, int line, const char *file, const char *func)
Definition def.hpp:284
std::string get_info()
Definition def.hpp:461
std::string to_string(T v)
Definition def.hpp:615
std::string wd
Definition def.hpp:120
size_t rank
Definition def.hpp:112
std::string file
Definition def.hpp:123
std::string routine
Definition def.hpp:129
std::string level
Definition def.hpp:107
std::string message
Definition def.hpp:103
int line
Definition def.hpp:132
std::string timestamp
Definition def.hpp:98
std::string to_string()
Definition def.hpp:137
std::string user
Definition def.hpp:115