(XCore) SysLog

Files CCore/inc/sys/SysLog.h CCore/src/sys/SysLog.cpp

XCore uses SysLog to log some operations, like synchronization object operations. You may use it to log your own messages. By default, SysLog is disabled. To enable it you have to uncomment the following line in the SysLog.h files and rebuild CCore:


//#define CCORE_SYS_LOG_ENABLE

SysLog can be used in any context, including interrupt context, but you must be aware of the log message argument types: they must be lightweight types, there should be no memory allocation or other resource allocation operations in constructors, destructors, copy constructors, etc.

To log a message use the function Sys::Log:


template <class ... TT>
void Sys::Log(Sys::LogCategory cat,const char *format,const TT & ... tt); 

This function does nothing, if SysLog is disabled.

The following software entities are located in the Sys namespace. You can use them to access SysLog features, even if you disable SysLog. "Disabling" does not mean the complete SysLog removal, it just make the function Sys::Log doing nothing.

LogSource

This enum describe a log message source. There are reserved values for system sources and other can be used by user.


enum LogSource
 {
  LogSourceCRT,
  
  LogSourceTask,
  LogSourceMutex,
  LogSourceSem,
  LogSourceEvent,
  LogSourceAntiSem,
  LogSourceResSem,
  LogSourceMultiSem,
  LogSourceMultiEvent,
  
  LogSourceUserMin = 10,
  LogSourceUserMax = 31
 };
 
const char * GetTextDesc(LogSource src); 
 

LogType

This enum describe a log message type. There are four common types: LogDebug, LogEvent, LogError, LogAlert. Other can be used by user.


enum LogType
 {
  LogDebug,
  LogEvent,
  LogError,
  LogAlert,
  
  LogTypeUserMin = 10,
  LogTypeUserMax = 31
 };
 
const char * GetTextDesc(LogType type); 

LogCategory and LogFilter

LogCategory and LogFilter are built on LogSource and LogType. To create a LogCategory value you can use the operator |.


using LogCategory = LogCategory_enum<LogSource,LogType> ;

using LogFilter = LogFilter_enum<LogSource,LogType> ;

/* functions */  
 
inline LogCategory operator | (LogSource src,LogType type) { return LogCategory(src,type); }
 

LogAccess

LogAccess is used to add a new message to the log.


class LogAccess : FastMutexBase::Lock
 {
   void *mem;
 
  public:
  
   LogAccess(LogCategory cat,ulen msg_len);
   
   ~LogAccess();
   
   operator void * () const { return mem; }
   
   void commit(LogMsgBase<LogCategory,LogStamp> *msg);
 };

Below is an example how to add a message.


template <class ... TT>
void Log(LogCategory cat,const char *format,const TT & ... tt) 
 {
  using MsgType = LogMsg<LogCategory,LogStamp,TT...> ;
  
  LogAccess access(cat,sizeof (MsgType));
 
  if( access )
    {
     MsgType *msg=new(PlaceAt(access)) MsgType(cat,format,tt...);
     
     access.commit(msg);
    } 
 }

LogFilterAccess

LogFilterAccess can be used to access the internal input SysLog message filter.


class LogFilterAccess : FastMutexBase::Lock
 {
   LogFilter *filter;
 
  public:
  
   LogFilterAccess();
   
   ~LogFilterAccess() {}
   
   LogFilter * getPtr() const { return filter; }
   
   LogFilter & operator * () const { return *getPtr(); }
   
   LogFilter * operator -> () const { return getPtr(); }
 };

The object of this class must be a local object with a short life-time.


*Sys::LogFilterAccess()=filter;

filter=*Sys::LogFilterAccess();

Sys::LogFilterAccess()->disable(Sys::LogDebug);

LogCursor

LogCursor can be used to iterate over the SysLog content. It iterates the last count messages. LogCursor implements the Cursor interface.


class LogCursor : NoCopy
 {
   const LogMsgBase<LogCategory,LogStamp> *cur;
   ulen count;
 
  public:
  
   explicit LogCursor(ulen count);
   
   ~LogCursor();
   
   // object ptr
   
   bool operator + () const { return cur!=0; }
   
   bool operator ! () const { return cur==0; }
   
   const LogMsgBase<LogCategory,LogStamp> * getPtr() const { return cur; }
   
   const LogMsgBase<LogCategory,LogStamp> & operator * () const { return *cur; }
    
   const LogMsgBase<LogCategory,LogStamp> * operator -> () const { return cur; }
   
   // cursor
   
   void operator ++ ();
 };

PrintLog

PrintLog can be used to print the SysLog content. It prints the last count messages. You can provide a filter to exclude messages from the printing.


class PrintLog
 {
   ulen count;
   LogFilter filter;
   
  public:
  
   explicit PrintLog(ulen count_,LogFilter filter_=LogFilter()) : count(count_),filter(filter_) {}
   
   void print(PrintBase &out) const;
 };

Target support for SysLog

SysLog is created on an earlier stage of the system initialization. It uses IntLock to serialize the log access. SysLog stores messages in the reserved memory region, provided by the target. The function AllocLogSpace(), declared in the target header SysMemSpace.h, is called once during the SysLog initialization.


/* functions */

 // one-time call , aligned

Space AllocHeapSpace();

Space AllocHeapSpace_int();

Space AllocHeapSpace_shared();

Space AllocLogSpace();

Space AllocVideoSpace();