Merge branch 'ngcore' into 'master'

logging in archive not compile time based

See merge request jschoeberl/netgen!115
This commit is contained in:
Joachim Schöberl 2019-01-16 18:31:00 +00:00
commit ceef45d3ac
8 changed files with 192 additions and 149 deletions

View File

@ -106,7 +106,7 @@ namespace ngcore
protected: protected:
bool shallow_to_python = false; bool shallow_to_python = false;
std::map<std::string, VersionInfo> version_map = GetLibraryVersions(); std::map<std::string, VersionInfo> version_map = GetLibraryVersions();
std::shared_ptr<spdlog::logger> logger = GetLogger("Archive"); std::shared_ptr<Logger> logger = GetLogger("Archive");
public: public:
Archive() = delete; Archive() = delete;
Archive(const Archive&) = delete; Archive(const Archive&) = delete;
@ -211,6 +211,7 @@ namespace ngcore
// don't use it that often anyway) // don't use it that often anyway)
Archive& operator& (std::vector<bool>& v) Archive& operator& (std::vector<bool>& v)
{ {
logger->debug("In special archive for std::vector<bool>");
size_t size; size_t size;
if(Output()) if(Output())
size = v.size(); size = v.size();
@ -295,11 +296,11 @@ namespace ngcore
{ {
if(Output()) if(Output())
{ {
NETGEN_DEBUG_LOG(logger, "Store shared ptr of type " + Demangle(typeid(T).name())); logger->debug("Store shared ptr of type {}", Demangle(typeid(T).name()));
// save -2 for nullptr // save -2 for nullptr
if(!ptr) if(!ptr)
{ {
NETGEN_DEBUG_LOG(logger, "Storing nullptr"); logger->debug("Storing nullptr");
return (*this) << -2; return (*this) << -2;
} }
@ -308,8 +309,9 @@ namespace ngcore
// Downcasting is only possible for our registered classes // Downcasting is only possible for our registered classes
if(typeid(T) != typeid(*ptr)) if(typeid(T) != typeid(*ptr))
{ {
NETGEN_DEBUG_LOG(logger, "Typids are different: " + Demangle(typeid(T).name()) + " vs. " + logger->debug("Typids are different: {} vs {}",
Demangle(typeid(*ptr).name())); Demangle(typeid(T).name()),
Demangle(typeid(*ptr).name()));
if(!IsRegistered(Demangle(typeid(*ptr).name()))) if(!IsRegistered(Demangle(typeid(*ptr).name())))
throw Exception(std::string("Archive error: Polymorphic type ") throw Exception(std::string("Archive error: Polymorphic type ")
+ Demangle(typeid(*ptr).name()) + Demangle(typeid(*ptr).name())
@ -318,7 +320,7 @@ namespace ngcore
// if there was a true downcast we have to store more information // if there was a true downcast we have to store more information
if(reg_ptr != static_cast<void*>(ptr.get())) if(reg_ptr != static_cast<void*>(ptr.get()))
{ {
NETGEN_DEBUG_LOG(logger, "Multiple/Virtual inheritance involved, need to cast pointer"); logger->debug("Multiple/Virtual inheritance involved, need to cast pointer");
neededDowncast = true; neededDowncast = true;
} }
} }
@ -326,8 +328,8 @@ namespace ngcore
// if not found store -1 and the pointer // if not found store -1 and the pointer
if(pos == shared_ptr2nr.end()) if(pos == shared_ptr2nr.end())
{ {
NETGEN_DEBUG_LOG(logger, "Didn't find the shared_ptr, create new registry entry at " + logger->debug("Didn't find the shared_ptr, create new registry entry at {}",
std::to_string(shared_ptr_count)); shared_ptr_count);
auto p = ptr.get(); auto p = ptr.get();
(*this) << -1; (*this) << -1;
(*this) & neededDowncast & p; (*this) & neededDowncast & p;
@ -338,27 +340,27 @@ namespace ngcore
return *this; return *this;
} }
// if found store the position and if it has to be downcasted and how // if found store the position and if it has to be downcasted and how
NETGEN_DEBUG_LOG(logger, "Found shared_ptr at position " + std::to_string(pos->second)); logger->debug("Found shared_ptr at position {}", pos->second);
(*this) << pos->second << neededDowncast; (*this) << pos->second << neededDowncast;
if(neededDowncast) if(neededDowncast)
(*this) << Demangle(typeid(*ptr).name()); (*this) << Demangle(typeid(*ptr).name());
} }
else // Input else // Input
{ {
NETGEN_DEBUG_LOG(logger, "Reading shared_ptr of type " + Demangle(typeid(T).name())); logger->debug("Reading shared_ptr of type {}", Demangle(typeid(T).name()));
int nr; int nr;
(*this) & nr; (*this) & nr;
// -2 restores a nullptr // -2 restores a nullptr
if(nr == -2) if(nr == -2)
{ {
NETGEN_DEBUG_LOG(logger, "Reading a nullptr"); logger->debug("Reading a nullptr");
ptr = nullptr; ptr = nullptr;
return *this; return *this;
} }
// -1 restores a new shared ptr by restoring the inner pointer and creating a shared_ptr to it // -1 restores a new shared ptr by restoring the inner pointer and creating a shared_ptr to it
if (nr == -1) if (nr == -1)
{ {
NETGEN_DEBUG_LOG(logger, "Createing new shared_ptr"); logger->debug("Createing new shared_ptr");
T* p = nullptr; T* p = nullptr;
bool neededDowncast; bool neededDowncast;
(*this) & neededDowncast & p; (*this) & neededDowncast & p;
@ -366,7 +368,7 @@ namespace ngcore
// if we did downcast we need to store a shared_ptr<void> to the true object // if we did downcast we need to store a shared_ptr<void> to the true object
if(neededDowncast) if(neededDowncast)
{ {
NETGEN_DEBUG_LOG(logger, "Shared pointer needed downcasting"); logger->debug("Shared pointer needed downcasting");
std::string name; std::string name;
(*this) & name; (*this) & name;
auto info = GetArchiveRegister(name); auto info = GetArchiveRegister(name);
@ -378,19 +380,19 @@ namespace ngcore
} }
else else
{ {
NETGEN_DEBUG_LOG(logger, "Shared pointer didn't need downcasting"); logger->debug("Shared pointer didn't need downcasting");
nr2shared_ptr.push_back(ptr); nr2shared_ptr.push_back(ptr);
} }
} }
else else
{ {
NETGEN_DEBUG_LOG(logger, "Reading already existing pointer at entry " + std::to_string(nr)); logger->debug("Reading already existing pointer at entry {}", nr);
auto other = nr2shared_ptr[nr]; auto other = nr2shared_ptr[nr];
bool neededDowncast; bool neededDowncast;
(*this) & neededDowncast; (*this) & neededDowncast;
if(neededDowncast) if(neededDowncast)
{ {
NETGEN_DEBUG_LOG(logger, "Shared pointer needed pointer downcast"); logger->debug("Shared pointer needed pointer downcast");
// if there was a downcast we can expect the class to be registered (since archiving // if there was a downcast we can expect the class to be registered (since archiving
// wouldn't have worked else) // wouldn't have worked else)
std::string name; std::string name;
@ -404,7 +406,7 @@ namespace ngcore
} }
else else
{ {
NETGEN_DEBUG_LOG(logger, "Shared pointer didn't need pointer casts"); logger->debug("Shared pointer didn't need pointer casts");
ptr = std::static_pointer_cast<T>(other); ptr = std::static_pointer_cast<T>(other);
} }
} }
@ -418,18 +420,19 @@ namespace ngcore
{ {
if (Output()) if (Output())
{ {
NETGEN_DEBUG_LOG(logger, "Store pointer of type " + Demangle(typeid(T).name())); logger->debug("Store pointer of type {}",Demangle(typeid(T).name()));
// if the pointer is null store -2 // if the pointer is null store -2
if (!p) if (!p)
{ {
NETGEN_DEBUG_LOG(logger, "Storing nullptr"); logger->debug("Storing nullptr");
return (*this) << -2; return (*this) << -2;
} }
auto reg_ptr = static_cast<void*>(p); auto reg_ptr = static_cast<void*>(p);
if(typeid(T) != typeid(*p)) if(typeid(T) != typeid(*p))
{ {
NETGEN_DEBUG_LOG(logger, "Typeids are different: " + Demangle(typeid(T).name()) + " vs. " + logger->debug("Typeids are different: {} vs {}",
Demangle(typeid(*p).name())); Demangle(typeid(T).name()),
Demangle(typeid(*p).name()));
if(!IsRegistered(Demangle(typeid(*p).name()))) if(!IsRegistered(Demangle(typeid(*p).name())))
throw Exception(std::string("Archive error: Polymorphic type ") throw Exception(std::string("Archive error: Polymorphic type ")
+ Demangle(typeid(*p).name()) + Demangle(typeid(*p).name())
@ -437,20 +440,20 @@ namespace ngcore
reg_ptr = GetArchiveRegister(Demangle(typeid(*p).name())).downcaster(typeid(T), static_cast<void*>(p)); reg_ptr = GetArchiveRegister(Demangle(typeid(*p).name())).downcaster(typeid(T), static_cast<void*>(p));
if(reg_ptr != static_cast<void*>(p)) if(reg_ptr != static_cast<void*>(p))
{ {
NETGEN_DEBUG_LOG(logger, "Multiple/Virtual inheritance involved, need to cast pointer"); logger->debug("Multiple/Virtual inheritance involved, need to cast pointer");
} }
} }
auto pos = ptr2nr.find(reg_ptr); auto pos = ptr2nr.find(reg_ptr);
// if the pointer is not found in the map create a new entry // if the pointer is not found in the map create a new entry
if (pos == ptr2nr.end()) if (pos == ptr2nr.end())
{ {
NETGEN_DEBUG_LOG(logger, "Didn't find pointer, create new registry entry at " + logger->debug("Didn't find pointer, create new registry entry at {}",
std::to_string(ptr_count)); ptr_count);
ptr2nr[reg_ptr] = ptr_count++; ptr2nr[reg_ptr] = ptr_count++;
if(typeid(*p) == typeid(T)) if(typeid(*p) == typeid(T))
if (std::is_constructible<T>::value) if (std::is_constructible<T>::value)
{ {
NETGEN_DEBUG_LOG(logger, "Store standard class pointer (no virt. inh,...)"); logger->debug("Store standard class pointer (no virt. inh,...)");
return (*this) << -1 & (*p); return (*this) << -1 & (*p);
} }
else else
@ -466,7 +469,7 @@ namespace ngcore
throw Exception(std::string("Archive error: Polymorphic type ") throw Exception(std::string("Archive error: Polymorphic type ")
+ Demangle(typeid(*p).name()) + Demangle(typeid(*p).name())
+ " not registered for archive"); + " not registered for archive");
NETGEN_DEBUG_LOG(logger, "Store a possibly more complicated pointer"); logger->debug("Store a possibly more complicated pointer");
return (*this) << -3 << Demangle(typeid(*p).name()) & (*p); return (*this) << -3 << Demangle(typeid(*p).name()) & (*p);
} }
} }
@ -474,39 +477,37 @@ namespace ngcore
{ {
(*this) & pos->second; (*this) & pos->second;
bool downcasted = !(reg_ptr == static_cast<void*>(p) ); bool downcasted = !(reg_ptr == static_cast<void*>(p) );
NETGEN_DEBUG_LOG(logger, "Store a the existing position in registry at " + logger->debug("Store a the existing position in registry at {}", pos->second);
std::to_string(pos->second)); logger->debug("Pointer {} downcasting", downcasted ? "needs" : "doesn't need");
NETGEN_DEBUG_LOG(logger, std::string("Pointer ") + (downcasted ? "needs " : "doesn't need ") +
"downcasting");
// store if the class has been downcasted and the name // store if the class has been downcasted and the name
(*this) << downcasted << Demangle(typeid(*p).name()); (*this) << downcasted << Demangle(typeid(*p).name());
} }
} }
else else
{ {
NETGEN_DEBUG_LOG(logger, "Reading pointer of type " + Demangle(typeid(T).name())); logger->debug("Reading pointer of type {}", Demangle(typeid(T).name()));
int nr; int nr;
(*this) & nr; (*this) & nr;
if (nr == -2) // restore a nullptr if (nr == -2) // restore a nullptr
{ {
NETGEN_DEBUG_LOG(logger, "Loading a nullptr"); logger->debug("Loading a nullptr");
p = nullptr; p = nullptr;
} }
else if (nr == -1) // create a new pointer of standard type (no virtual or multiple inheritance,...) else if (nr == -1) // create a new pointer of standard type (no virtual or multiple inheritance,...)
{ {
NETGEN_DEBUG_LOG(logger, "Load a new pointer to a simple class"); logger->debug("Load a new pointer to a simple class");
p = detail::constructIfPossible<T>(); p = detail::constructIfPossible<T>();
nr2ptr.push_back(p); nr2ptr.push_back(p);
(*this) & *p; (*this) & *p;
} }
else if(nr == -3) // restore one of our registered classes that can have multiple inheritance,... else if(nr == -3) // restore one of our registered classes that can have multiple inheritance,...
{ {
NETGEN_DEBUG_LOG(logger, "Load a new pointer to a potentially more complicated class " logger->debug("Load a new pointer to a potentially more complicated class "
"(allows for multiple/virtual inheritance,...)"); "(allows for multiple/virtual inheritance,...)");
// As stated above, we want this special behaviour only for our classes that implement DoArchive // As stated above, we want this special behaviour only for our classes that implement DoArchive
std::string name; std::string name;
(*this) & name; (*this) & name;
NETGEN_DEBUG_LOG(logger, "Name = " + name); logger->debug("Name = {}", name);
auto info = GetArchiveRegister(name); auto info = GetArchiveRegister(name);
// the creator creates a new object of type name, and returns a void* pointing // the creator creates a new object of type name, and returns a void* pointing
// to T (which may have an offset) // to T (which may have an offset)
@ -518,13 +519,11 @@ namespace ngcore
} }
else else
{ {
NETGEN_DEBUG_LOG(logger, "Restoring pointer to already existing object at registry position " + logger->debug("Restoring pointer to already existing object at registry position {}", nr);
std::to_string(nr));
bool downcasted; bool downcasted;
std::string name; std::string name;
(*this) & downcasted & name; (*this) & downcasted & name;
NETGEN_DEBUG_LOG(logger, std::string(downcasted ? "Downcasted" : "Not downcasted") + logger->debug("{} object of type {}", downcasted ? "Downcasted" : "Not downcasted", name);
" object of type " + name);
if(downcasted) if(downcasted)
{ {
// if the class has been downcasted we can assume it is in the register // if the class has been downcasted we can assume it is in the register

View File

@ -1,15 +1,29 @@
#include "logging.hpp" #include "logging.hpp"
#ifdef NETGEN_USE_SPDLOG #ifdef NETGEN_USE_SPDLOG
#include <spdlog/spdlog.h>
#include <spdlog/sinks/ansicolor_sink.h> #include <spdlog/sinks/ansicolor_sink.h>
#include <spdlog/sinks/basic_file_sink.h> #include <spdlog/sinks/basic_file_sink.h>
#else // NETGEN_USE_SPDLOG
#include <iostream>
#endif // NETGEN_USE_SPDLOG #endif // NETGEN_USE_SPDLOG
namespace ngcore namespace ngcore
{ {
void Logger::log(level::level_enum level, std::string && s)
{
#ifdef NETGEN_USE_SPDLOG
logger->log(spdlog::level::level_enum(level), s);
#else // NETGEN_USE_SPDLOG
if(level>level::debug)
std::clog << s << '\n';
#endif // NETGEN_USE_SPDLOG
}
#ifdef NETGEN_USE_SPDLOG #ifdef NETGEN_USE_SPDLOG
namespace detail namespace detail
{ {
@ -28,12 +42,12 @@ namespace ngcore
} }
} // namespace detail } // namespace detail
std::shared_ptr<spdlog::logger> GetLogger(const std::string& name) std::shared_ptr<Logger> GetLogger(const std::string& name)
{ {
auto logger = spdlog::get(name); auto logger = spdlog::get(name);
if(!logger) if(!logger)
logger = detail::CreateDefaultLogger(name); logger = detail::CreateDefaultLogger(name);
return logger; return std::make_shared<Logger>(logger);
} }
void SetLoggingLevel(spdlog::level::level_enum level, const std::string& name) void SetLoggingLevel(spdlog::level::level_enum level, const std::string& name)
@ -49,7 +63,7 @@ namespace ngcore
auto sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(filename); auto sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(filename);
sink->set_level(level); sink->set_level(level);
if(!logger.empty()) if(!logger.empty())
GetLogger(logger)->sinks().push_back(sink); GetLogger(logger)->logger->sinks().push_back(sink);
else else
{ {
detail::GetDefaultSinks().push_back(sink); detail::GetDefaultSinks().push_back(sink);
@ -62,7 +76,7 @@ namespace ngcore
auto sink = std::make_shared<spdlog::sinks::ansicolor_stdout_sink_mt>(); auto sink = std::make_shared<spdlog::sinks::ansicolor_stdout_sink_mt>();
sink->set_level(level); sink->set_level(level);
if(!logger.empty()) if(!logger.empty())
GetLogger(logger)->sinks().push_back(sink); GetLogger(logger)->logger->sinks().push_back(sink);
else else
{ {
detail::GetDefaultSinks().push_back(sink); detail::GetDefaultSinks().push_back(sink);
@ -73,7 +87,7 @@ namespace ngcore
void ClearLoggingSinks(const std::string& logger) void ClearLoggingSinks(const std::string& logger)
{ {
if(!logger.empty()) if(!logger.empty())
GetLogger(logger)->sinks().clear(); GetLogger(logger)->logger->sinks().clear();
else else
{ {
detail::GetDefaultSinks().clear(); detail::GetDefaultSinks().clear();
@ -84,26 +98,40 @@ namespace ngcore
void FlushOnLoggingLevel(spdlog::level::level_enum level, const std::string& logger) void FlushOnLoggingLevel(spdlog::level::level_enum level, const std::string& logger)
{ {
if(!logger.empty()) if(!logger.empty())
GetLogger(logger)->flush_on(level); GetLogger(logger)->logger->flush_on(level);
else else
spdlog::flush_on(level); spdlog::flush_on(level);
} }
#else // NETGEN_USE_SPDLOG #else // NETGEN_USE_SPDLOG
} //namespace ngcore
namespace spdlog
{
class logger
{
public:
logger() = default;
};
} // namespace spdlog
namespace ngcore
{
// Dummy functions if no spdlog is available // Dummy functions if no spdlog is available
std::shared_ptr<spdlog::logger> GetLogger(const std::string& /*unused*/) std::shared_ptr<Logger> GetLogger(const std::string& /*unused*/)
{ {
return std::make_shared<spdlog::logger>(); return std::make_shared<Logger>(std::make_shared<spdlog::logger>());
} }
void SetLoggingLevel(spdlog::level::level_enum /*unused*/, const std::string& /*unused*/) {}
void AddFileSink(const std::string& /*unused*/, spdlog::level::level_enum /*unused*/, void SetLoggingLevel(level::level_enum /*unused*/, const std::string& /*unused*/) {}
const std::string& /*unused*/) void AddFileSink(const std::string& /*unused*/, level::level_enum /*unused*/,
const std::string& /*unused*/)
{} {}
void AddConsoleSink(spdlog::level::level_enum /*unused*/, const std::string& /*unused*/) {} void AddConsoleSink(level::level_enum /*unused*/, const std::string& /*unused*/) {}
void ClearLoggingSinks(const std::string& /*unused*/) {} void ClearLoggingSinks(const std::string& /*unused*/) {}
void FlushOnLoggingLevel(spdlog::level::level_enum /*unused*/, const std::string& /*unused*/) {} void FlushOnLoggingLevel(level::level_enum /*unused*/, const std::string& /*unused*/) {}
} //namespace ngcore
#endif // NETGEN_USE_SPDLOG #endif // NETGEN_USE_SPDLOG
} //namespace ngcore

View File

@ -1,108 +1,124 @@
#ifndef NETGEN_CORE_LOGGING_HPP #ifndef NETGEN_CORE_LOGGING_HPP
#define NETGEN_CORE_LOGGING_HPP #define NETGEN_CORE_LOGGING_HPP
#undef NETGEN_USE_SPDLOG
#include <iostream>
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
#include "exception.hpp"
#include "ngcore_api.hpp" #include "ngcore_api.hpp"
#include "utils.hpp"
#ifdef NETGEN_USE_SPDLOG #ifdef NETGEN_USE_SPDLOG
#include <spdlog/fmt/fmt.h>
#include <spdlog/fmt/ostr.h> // to be able to parse anything to logger that implements operator << ostream
#ifdef NETGEN_LOG_DEBUG #ifdef NETGEN_LOG_DEBUG
#define SPDLOG_DEBUG_ON #define SPDLOG_DEBUG_ON
#endif // NETGEN_LOG_DEBUG
#include <spdlog/logger.h>
#include <spdlog/sinks/sink.h>
#include <spdlog/spdlog.h>
#define NETGEN_DEBUG_LOG(logger, ...) SPDLOG_DEBUG(logger, __VA_ARGS__) #define NETGEN_DEBUG_LOG(logger, ...) SPDLOG_DEBUG(logger, __VA_ARGS__)
#endif // NETGEN_LOG_DEBUG
#endif // NETGEN_USE_SPDLOG
#else // NETGEN_USE_SPDLOG #ifndef NETGEN_DEBUG_LOG
#define NETGEN_DEBUG_LOG(logger, ...)
#include <iostream> #endif // NETGEN_DEBUG_LOG
namespace spdlog namespace spdlog
{ {
// Dummys if Netgen is compiled with USE_SPDLOG=OFF. class logger;
namespace level } // namespace spdlog
{
enum level_enum
{
trace = 0,
debug = 1,
info = 2,
warn = 3,
err = 4,
critical = 5,
off = 6
};
} // namespace level
class logger
{
public:
void log_helper() {}
template<typename T>
void log_helper( T t) { std::clog << t; }
template<typename T, typename ... Args>
void log_helper( T t, Args ... args)
{
std::clog << t;
log_helper(args...);
std::clog << ", ";
}
template<typename ... Args>
void log( level::level_enum level, const char* fmt, Args ... args)
{
std::clog << level << ": " << fmt << "\t Arguments: ";
log_helper(args...);
std::clog << "\n";
}
template<typename ... Args>
void trace( const char* fmt, Args ... args) { log(level::level_enum::trace, fmt, args...); }
template<typename ... Args>
void debug( const char* fmt, Args ... args) { log(level::level_enum::debug, fmt, args...); }
template<typename ... Args>
void info( const char* fmt, Args ... args) { log(level::level_enum::info, fmt, args...); }
template<typename ... Args>
void warn( const char* fmt, Args ... args) { log(level::level_enum::warn, fmt, args...); }
template<typename ... Args>
void error( const char* fmt, Args ... args) { log(level::level_enum::err, fmt, args...); }
template<typename ... Args>
void critical( const char* fmt, Args ... args) { log(level::level_enum::critical, fmt, args...); }
};
namespace sinks
{
class sink {};
} // namespace sinks
} //namespace spdlog
#define NETGEN_DEBUG_LOG(logger, ...)
#endif // NETGEN_USE_SPDLOG
namespace ngcore namespace ngcore
{ {
namespace detail namespace level
{ {
std::vector<std::shared_ptr<spdlog::sinks::sink>>& GetDefaultSinks(); enum level_enum
inline std::shared_ptr<spdlog::logger> CreateDefaultLogger(const std::string& name); {
} //namespace detail trace = 0,
debug = 1,
info = 2,
warn = 3,
err = 4,
critical = 5,
off = 6
};
} // namespace level
NGCORE_API std::shared_ptr<spdlog::logger> GetLogger(const std::string& name); class Logger
NGCORE_API void SetLoggingLevel(spdlog::level::level_enum level, const std::string& name); {
NGCORE_API void AddFileSink(const std::string& filename, spdlog::level::level_enum level, const std::string& logger); public:
NGCORE_API void AddConsoleSink(spdlog::level::level_enum level, const std::string& logger); std::shared_ptr<spdlog::logger> logger;
Logger(std::shared_ptr<spdlog::logger> l) : logger(std::move(l)) {}
void NGCORE_API log( level::level_enum level, std::string && s);
#ifdef NETGEN_USE_SPDLOG
template<typename ... Args>
void log( level::level_enum level, const char* str, Args ... args)
{
log(level, fmt::format(str, args...));
}
#else // NETGEN_USE_SPDLOG
template<typename T>
std::string replace(std::string s, const T & t)
{
auto p0 = s.find_first_of('{');
auto p1 = s.find_first_of('}', p0);
if(p0==std::string::npos || p1==std::string::npos)
throw Exception("invalid format string");
s.replace(p0, p1-p0+1, ToString(t));
return s;
}
std::string log_helper(std::string s)
{
return s;
}
template<typename T>
std::string log_helper(std::string s, const T &t)
{
return replace(s,t);
}
template<typename T, typename ... Args>
std::string log_helper( std::string s, const T &t, Args ... args)
{
return log_helper(replace(s,t), args...);
}
template<typename ... Args>
void log( level::level_enum level, const char* str, Args ... args)
{
log(level, log_helper(std::string(str), args...));
}
#endif // NETGEN_USE_SPDLOG
template<typename ... Args>
void trace( const char* str, Args ... args) { log(level::level_enum::trace, str, args...); }
template<typename ... Args>
void debug( const char* str, Args ... args) { log(level::level_enum::debug, str, args...); }
template<typename ... Args>
void info( const char* str, Args ... args) { log(level::level_enum::info, str, args...); }
template<typename ... Args>
void warn( const char* str, Args ... args) { log(level::level_enum::warn, str, args...); }
template<typename ... Args>
void error( const char* str, Args ... args) { log(level::level_enum::err, str, args...); }
template<typename ... Args>
void critical( const char* str, Args ... args) { log(level::level_enum::critical, str, args...); }
};
NGCORE_API std::shared_ptr<Logger> GetLogger(const std::string& name);
NGCORE_API void SetLoggingLevel(level::level_enum level, const std::string& name);
NGCORE_API void AddFileSink(const std::string& filename, level::level_enum level, const std::string& logger);
NGCORE_API void AddConsoleSink(level::level_enum level, const std::string& logger);
NGCORE_API void ClearLoggingSinks(const std::string& logger); NGCORE_API void ClearLoggingSinks(const std::string& logger);
NGCORE_API void FlushOnLoggingLevel(spdlog::level::level_enum level, const std::string& logger); NGCORE_API void FlushOnLoggingLevel(level::level_enum level, const std::string& logger);
} // namespace ngcore } // namespace ngcore
#endif // NETGEN_CORE_LOGGING_HPP #endif // NETGEN_CORE_LOGGING_HPP

View File

@ -92,7 +92,7 @@ namespace ngcore
FILE * ctrace_stream; FILE * ctrace_stream;
TTimePoint start_time; TTimePoint start_time;
std::shared_ptr<spdlog::logger> logger = GetLogger("PajeTrace"); std::shared_ptr<Logger> logger = GetLogger("PajeTrace");
double ConvertTime(TTimePoint t) { double ConvertTime(TTimePoint t) {

View File

@ -18,7 +18,7 @@ namespace ngcore
using TClock = std::chrono::system_clock; using TClock = std::chrono::system_clock;
protected: protected:
std::shared_ptr<spdlog::logger> logger = GetLogger("PajeTrace"); std::shared_ptr<Logger> logger = GetLogger("PajeTrace");
private: private:
NGCORE_API static size_t max_tracefile_size; NGCORE_API static size_t max_tracefile_size;
NGCORE_API static bool trace_thread_counter; NGCORE_API static bool trace_thread_counter;

View File

@ -13,7 +13,7 @@ namespace ngcore
size_t NgProfiler::dummy_thread_flops[NgProfiler::SIZE]; size_t NgProfiler::dummy_thread_flops[NgProfiler::SIZE];
size_t * NgProfiler::thread_flops = NgProfiler::dummy_thread_flops; // NOLINT size_t * NgProfiler::thread_flops = NgProfiler::dummy_thread_flops; // NOLINT
std::shared_ptr<spdlog::logger> NgProfiler::logger = GetLogger("Profiler"); // NOLINT std::shared_ptr<Logger> NgProfiler::logger = GetLogger("Profiler"); // NOLINT
NgProfiler :: NgProfiler() NgProfiler :: NgProfiler()
{ {

View File

@ -34,7 +34,7 @@ namespace ngcore
NGCORE_API static TTimePoint * thread_times; NGCORE_API static TTimePoint * thread_times;
NGCORE_API static TTimePoint * thread_flops; NGCORE_API static TTimePoint * thread_flops;
NGCORE_API static std::shared_ptr<spdlog::logger> logger; NGCORE_API static std::shared_ptr<Logger> logger;
NGCORE_API static size_t dummy_thread_times[NgProfiler::SIZE]; NGCORE_API static size_t dummy_thread_times[NgProfiler::SIZE];
NGCORE_API static size_t dummy_thread_flops[NgProfiler::SIZE]; NGCORE_API static size_t dummy_thread_flops[NgProfiler::SIZE];
private: private:

View File

@ -8,14 +8,14 @@ using namespace ngcore;
PYBIND11_MODULE(pyngcore, m) // NOLINT PYBIND11_MODULE(pyngcore, m) // NOLINT
{ {
py::enum_<spdlog::level::level_enum>(m, "LOG_LEVEL", "Logging level") py::enum_<level::level_enum>(m, "LOG_LEVEL", "Logging level")
.value("Trace", spdlog::level::trace) .value("Trace", level::trace)
.value("Debug", spdlog::level::debug) .value("Debug", level::debug)
.value("Info", spdlog::level::info) .value("Info", level::info)
.value("Warn", spdlog::level::warn) .value("Warn", level::warn)
.value("Error", spdlog::level::err) .value("Error", level::err)
.value("Critical", spdlog::level::critical) .value("Critical", level::critical)
.value("Off", spdlog::level::off); .value("Off", level::off);
m.def("SetLoggingLevel", &SetLoggingLevel, py::arg("level"), py::arg("logger")="", m.def("SetLoggingLevel", &SetLoggingLevel, py::arg("level"), py::arg("logger")="",
"Set logging level, if name is given only to the specific logger, else set the global logging level"); "Set logging level, if name is given only to the specific logger, else set the global logging level");