11 #ifndef logger_logManager_hpp
12 #define logger_logManager_hpp
22 #include <mx/app/appConfigurator.hpp>
28 #include "../common/defaults.hpp"
30 #include "generated/logTypes.hpp"
31 #include "generated/logStdFormat.hpp"
72 template<
class _parentT,
class _logFileT>
84 std::string m_configSection {
"logger"};
92 bool m_logShutdown {
false};
100 int m_logThreadPrio {0};
102 bool m_logThreadRunning {
false};
196 template<
typename logT>
198 const typename logT::messageT &
msg,
209 template<
typename logT>
212 const typename logT::messageT &
msg,
220 template<
typename logT>
221 void log(
const typename logT::messageT &
msg,
229 template<
typename logT>
231 const typename logT::messageT &
msg,
239 template<
typename logT>
246 template<
typename logT>
253 template<
class parentT,
class logFileT>
258 template<
class parentT,
class logFileT>
261 m_logShutdown =
true;
263 if(m_logThread.joinable()) m_logThread.join();
266 if( !m_logQueue.empty() ) logThreadExec();
270 template<
class parentT,
class logFileT>
276 template<
class parentT,
class logFileT>
282 template<
class parentT,
class logFileT>
285 if(wp == 0)
return -1;
292 template<
class parentT,
class logFileT>
298 template<
class parentT,
class logFileT>
308 template<
class parentT,
class logFileT>
314 template<
class parentT,
class logFileT>
317 if(newPrio > 98)
return -1;
318 if(newPrio < 0) newPrio = 0;
320 m_logThreadPrio = newPrio;
324 template<
class parentT,
class logFileT>
327 return m_logThreadPrio;
330 template<
class parentT,
class logFileT>
333 return m_logThreadRunning;
336 template<
class parentT,
class logFileT>
339 config.add(m_configSection+
".logDir",
"L",
"logDir",mx::app::argType::Required, m_configSection,
"logDir",
false,
"string",
"The directory for log files");
340 config.add(m_configSection+
".logExt",
"",
"logExt",mx::app::argType::Required, m_configSection,
"logExt",
false,
"string",
"The extension for log files");
341 config.add(m_configSection+
".maxLogSize",
"",
"maxLogSize",mx::app::argType::Required, m_configSection,
"maxLogSize",
false,
"string",
"The maximum size of log files");
342 config.add(m_configSection+
".writePause",
"",
"writePause",mx::app::argType::Required, m_configSection,
"writePause",
false,
"unsigned long",
"The log thread pause time in ns");
343 config.add(m_configSection+
".logThreadPrio",
"",
"logThreadPrio", mx::app::argType::Required, m_configSection,
"logThreadPrio",
false,
"int",
"The log thread priority");
344 config.add(m_configSection+
".logLevel",
"l",
"logLevel",mx::app::argType::Required, m_configSection,
"logLevel",
false,
"string",
"The log level");
349 template<
class parentT,
class logFileT>
354 config(tmp, m_configSection+
".logDir");
355 if(tmp !=
"") this->logPath(tmp);
359 config(tmp, m_configSection+
".logLevel");
369 std::cerr <<
"Unkown log level specified. Using default (INFO)\n";
377 config(this->m_logExt, m_configSection+
".logExt");
380 config(this->m_maxLogSize, m_configSection+
".maxLogSize");
383 config(m_writePause, m_configSection+
".writePause");
386 config(m_logThreadPrio, m_configSection+
".logThreadPrio");
391 template<
class parentT,
class logFileT>
397 template<
class parentT,
class logFileT>
402 m_logThread = std::thread( _logThreadStart,
this);
404 catch(
const std::exception & e )
406 log<software_error>({__FILE__,__LINE__, 0, 0, std::string(
"Exception on log thread start: ") + e.what()});
411 log<software_error>({__FILE__,__LINE__, 0, 0,
"Unkown exception on log thread start"});
415 if(!m_logThread.joinable())
417 log<software_error>({__FILE__, __LINE__, 0, 0,
"Log thread did not start"});
423 sp.sched_priority = m_logThreadPrio;
425 int rv = pthread_setschedparam( m_logThread.native_handle(), SCHED_OTHER, &sp);
429 log<software_error>({__FILE__, __LINE__, 0, rv, std::string(
"Error setting thread params: ") + strerror(rv)});
437 template<
class parentT,
class logFileT>
441 m_logThreadRunning =
true;
443 std::unique_lock<std::mutex>
lock(m_qMutex, std::defer_lock);
445 while(!m_logShutdown || !m_logQueue.empty())
447 std::list<bufferPtrT>::iterator beg,
it, er, end;
452 beg = m_logQueue.begin();
453 end = m_logQueue.end();
463 if( this->writeLog( *
it ) < 0)
465 m_logThreadRunning =
false;
471 m_parent->logMessage( *
it );
484 m_logQueue.erase(er);
494 if(m_logQueue.empty() && !m_logShutdown) std::this_thread::sleep_for( std::chrono::duration<unsigned long, std::nano>(m_writePause));
497 m_logThreadRunning =
false;
500 template<
class parentT,
class logFileT>
501 template<
typename logT>
503 const typename logT::messageT &
msg,
511 return logHeader::createLog<logT>(logBuffer, ts,
msg, level);
514 template<
class parentT,
class logFileT>
515 template<
typename logT>
518 const typename logT::messageT &
msg,
522 return logHeader::createLog<logT>(logBuffer, ts,
msg, level);
525 template<
class parentT,
class logFileT>
526 template<
typename logT>
534 if(level > m_logLevel)
return;
538 createLog<logT>(logBuffer,
msg, level);
541 std::lock_guard<std::mutex> guard(m_qMutex);
542 m_logQueue.push_back(logBuffer);
547 template<
class parentT,
class logFileT>
548 template<
typename logT>
550 const typename logT::messageT &
msg,
557 if(level > m_logLevel)
return;
561 createLog<logT>(logBuffer, ts,
msg, level);
564 std::lock_guard<std::mutex> guard(m_qMutex);
565 m_logQueue.push_back(logBuffer);
569 template<
class parentT,
class logFileT>
570 template<
typename logT>
576 template<
class parentT,
class logFileT>
577 template<
typename logT>
Flatlogs single include file.
#define MAGAOX_default_writePause
The default logger writePause.
int8_t logPrioT
The type of the log priority code.
std::shared_ptr< char > bufferPtrT
The log entry buffer smart pointer.
static int logLevel(bufferPtrT &logBuffer, const logPrioT &lvl)
Set the level of a log entry in a logBuffer header.
Empty type for resolving logs with no message.
std::unique_lock< std::mutex > lock(m_indiMutex)
constexpr static logPrioT LOG_INFO
Informational. The info log level is the lowest level recorded during normal operations.
constexpr static logPrioT LOG_UNKNOWN
Used to denote an unkown log type for internal error handling.
constexpr static logPrioT LOG_DEFAULT
Used to denote "use the default level for this log type".
constexpr static logPrioT LOG_NOTICE
A normal but significant condition.
logPrioT logLevelFromString(const std::string &str)
Get the log priority from a string, which might have the number or the name.
The standard MagAOX log manager, used for both process logs and telemetry streams.
int logThreadStart()
Start the logger thread.
int loadConfig(mx::app::appConfigurator &config)
Load the logger section from an application configurator.
void log(const typename logT::messageT &msg, logPrioT level=logPrio::LOG_DEFAULT)
Make a log entry, including a message.
void log(timespecX &ts, logPrioT level=logPrio::LOG_DEFAULT)
Make a log entry with no message.
parentT * parent()
Get the logger parent.
static int createLog(bufferPtrT &logBuffer, const typename logT::messageT &msg, const logPrioT &level)
Create a log formatted log entry, filling in a buffer.
unsigned long writePause()
Get the current value of writePause.
int setupConfig(mx::app::appConfigurator &config)
Setup an application configurator for the logger section.
int logThreadPrio()
Get the current value of logThreadPrio.
std::thread m_logThread
A separate thread for actually writing to the file.
void parent(parentT *p)
Set the logger parent.
std::list< bufferPtrT > m_logQueue
Log entries are stored here, and writen to the file by the log thread.
void log(logPrioT level=logPrio::LOG_DEFAULT)
Make a log entry with no message.
logPrioT logLevel()
Get the current value of logLevel.
void log(timespecX &ts, const typename logT::messageT &msg, logPrioT level=logPrio::LOG_DEFAULT)
Make a log entry, including a message.
void logThreadExec()
Execute the logger thread.
int logThreadPrio(int newPrio)
Set a new value of logThreadPrio.
int writePause(const unsigned long &wp)
Set a new value of writePause.
int logLevel(logPrioT newLev)
Set a new value of logLevel.
std::mutex m_qMutex
Mutex for accessing the m_logQueue.
static int createLog(bufferPtrT &logBuffer, const timespecX &ts, const typename logT::messageT &msg, const logPrioT &level)
Create a log formatted log entry, filling in a buffer.
logManager()
Default c'tor.
bool logThreadRunning()
Get status of the log thread running flag.
static void _logThreadStart(logManager *l)
Thread starter, called by logThreadStart on thread construction. Calls logThreadExec.
A fixed-width timespec structure.
void gettime()
Fill the the timespecX with the current time.