7 #ifndef H_POTTU_CONTEXTBASE
8 #define H_POTTU_CONTEXTBASE
11 #include <fmt/chrono.h>
12 #include <fmt/color.h>
29 LOGLEVEL_WARNING = 30,
31 LOGLEVEL_CRITICAL = 50
53 const std::lock_guard<std::mutex> lock(_getMutex());
54 std::unique_ptr<ContextBase> &ctx = _getActiveRef();
56 throw std::runtime_error(
"Context is already registered." );
61 static std::mutex &_getMutex() noexcept {
67 static std::unique_ptr<ContextBase> &_getActiveRef() noexcept {
68 static std::unique_ptr<ContextBase> ctx;
81 const std::lock_guard<std::mutex> lock(_getMutex());
82 std::unique_ptr<ContextBase> &ctx = _getActiveRef();
97 const char *loglevelToStr( uint8_t level )
const noexcept {
98 if( level < LOGLEVEL_DEBUG )
100 else if( level < LOGLEVEL_INFO )
102 else if( level < LOGLEVEL_WARNING )
104 else if( level < LOGLEVEL_ERROR )
106 else if( level < LOGLEVEL_CRITICAL )
112 const fmt::text_style &getStyleForLevel( uint8_t level )
const noexcept {
113 if( level < LOGLEVEL_DEBUG )
115 else if( level < LOGLEVEL_INFO )
117 else if( level < LOGLEVEL_WARNING )
119 else if( level < LOGLEVEL_ERROR )
121 else if( level < LOGLEVEL_CRITICAL )
128 static void logDebug(
const std::string &message, uint64_t token=0 ) {
129 getActive().handleLogMsg(
"", LOGLEVEL_DEBUG, message );
132 static void logInfo(
const std::string &message, uint64_t token=0 ) {
133 getActive().handleLogMsg(
"", LOGLEVEL_INFO, message );
136 static void logWarning(
const std::string &message, uint64_t token=0 ) {
137 getActive().handleLogMsg(
"", LOGLEVEL_WARNING, message );
140 static void logError(
const std::string &message, uint64_t token=0 ) {
141 getActive().handleLogMsg(
"", LOGLEVEL_ERROR, message );
144 static void logCritical(
const std::string &message, uint64_t token=0 ) {
145 getActive().handleLogMsg(
"", LOGLEVEL_CRITICAL, message );
149 inline void printStatistics() noexcept;
151 virtual
void handleLogMsg( const std::
string &sender, uint8_t level, const std::
string &message ) noexcept {
152 const std::lock_guard<std::mutex> lock(_getMutex());
153 auto t = std::chrono::system_clock::now();
155 fmt::print( getStyleForLevel(level),
"{:12} {:10} {:%H:%M:%S} {:4}", sender, loglevelToStr(level), t, message );
158 fmt::print(
"{:12} {:10} {:%H:%M:%S} {:4}\n", sender, loglevelToStr(level), t, message );
163 bool useStyles{
true};
164 fmt::text_style styles[6] = {
165 {fg(fmt::color::gray)},
166 {fg(fmt::color::gray)},
168 {fmt::emphasis::bold | bg(fmt::color::black) | fg(fmt::color::yellow)},
169 {fg(fmt::color::red)},
170 {fmt::emphasis::bold | fg(fmt::color::red)}
173 std::vector<std::unique_ptr<ContextHandle>> _handles;
192 void logDebug(
const std::string &message, uint64_t token=0 ) { _ctx.handleLogMsg( _name, LOGLEVEL_DEBUG, message ); }
193 void logInfo(
const std::string &message, uint64_t token=0 ) { _ctx.handleLogMsg( _name, LOGLEVEL_INFO, message ); }
194 void logWarning(
const std::string &message, uint64_t token=0 ) { _ctx.handleLogMsg( _name, LOGLEVEL_WARNING, message ); }
195 void logError(
const std::string &message, uint64_t token=0 ) { _ctx.handleLogMsg( _name, LOGLEVEL_ERROR, message ); }
196 void logCritical(
const std::string &message, uint64_t token=0 ) { _ctx.handleLogMsg( _name, LOGLEVEL_CRITICAL, message ); }
198 const std::string &getName()
const noexcept {
return _name; }
200 double getTotalRunTime()
const noexcept {
return ( std::chrono::duration<double>( _runsDuration ) ).count(); }
201 uint64_t getNumOfRuns()
const noexcept {
return _runsFinished; }
220 friend class ProcessInstance;
222 void startProcess() noexcept {
224 _runStart = std::chrono::steady_clock::now();
227 void stopProcess() noexcept {
230 const auto t = std::chrono::steady_clock::now();
231 _runsDuration += t-_runStart;
237 bool _running{
false};
238 uint64_t _runsFinished{0};
239 std::chrono::steady_clock::duration _runsDuration{std::chrono::steady_clock::duration(0)};
240 std::chrono::steady_clock::time_point _runStart;
248 const std::lock_guard<std::mutex> lock(_getMutex());
251 _handles.push_back( std::make_unique<ContextHandle>( *
this, name ) );
252 return _handles.back().get();
256 inline void ContextBase::printStatistics() noexcept {
259 const std::lock_guard<std::mutex> lock(_getMutex());
260 msg += fmt::format(
"Statistics collected:\n" );
261 msg += fmt::format(
" name runs time [s]\n" );
262 for(
const auto &h : _handles ) {
263 if( h->getNumOfRuns() )
264 msg += fmt::format(
" {:32} {:12} {:10.3f}\n", h->getName(), h->getNumOfRuns(), h->getTotalRunTime() );
269 handleLogMsg(
"Context", LOGLEVEL_INFO, msg );
Definition: ContextBase.hpp:203
Handle to context used by specific class.
Definition: ContextBase.hpp:188
Definition: mainpage.dox:6
Default context for printing and collecting statistics.
Definition: ContextBase.hpp:41
ContextHandle * createHandle(const std::string &name) noexcept
Creates a new named handle to the active context.
Definition: ContextBase.hpp:247
static void logInfo(const std::string &message, uint64_t token=0)
Sends log message with level DEBUG from anonymous source.
Definition: ContextBase.hpp:132
static ContextBase & getActive() noexcept
Returns active Context.
Definition: ContextBase.hpp:80
static void logCritical(const std::string &message, uint64_t token=0)
Sends log message with level DEBUG from anonymous source.
Definition: ContextBase.hpp:144
static void registerContext(ContextBase *context)
Registers a context for the whole application.
Definition: ContextBase.hpp:52
static void logWarning(const std::string &message, uint64_t token=0)
Sends log message with level DEBUG from anonymous source.
Definition: ContextBase.hpp:136
static void logDebug(const std::string &message, uint64_t token=0)
Sends log message with level DEBUG from anonymous source.
Definition: ContextBase.hpp:128
static void logError(const std::string &message, uint64_t token=0)
Sends log message with level DEBUG from anonymous source.
Definition: ContextBase.hpp:140