Simple logging library that outputs over the PC serial link to add logging to a file simply `include "xenonym_logging.h" ` then you can add logging with which looks slighly like c++ std::cout logging by using the LOG define or the LOGGER define thus; LOG << "this message will begin a new line" or LOGGER << "this message will append to the end of the previous log"; there is also a simple `LOGFUNC( "funcname" );` define that will log the entry and exit from a function and indent the stream so its easy to see where you are. if you want to disable the logging from a file without removing your logging all you need do is ~#define LOGGING_DISABLED and the logging will compile to nothing. also has simple manipulators hex,dec to change the output radix and eol to start a new line. i.e. <<code>> #include "xenonym_logging.h" using namespace xenonym; class Devr : public Base { public: Devr( int i ) : Base(i) { LOGFUNC( "mylib::Devr" ); ... do stuff .. LOG << "param is still " << logging::dec << i; .... do more stuff .... } virtual uint16_t something( uint16_t msg ) { LOGFUNC( "Derv::something" ); uint16_t reply = proccess( msg ); LOG << "sent:0x" << logging::hex << msg << " reply:0x"<< reply << logging::dec; return reply; } }; <</code>>
Diff: xenonym_logging.h
- Revision:
- 0:eae9045546f3
- Child:
- 1:41f6c5ec11c2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xenonym_logging.h Thu Aug 04 20:29:26 2011 +0000 @@ -0,0 +1,126 @@ +#ifndef xenonym_logging_header /* { */ +#define xenonym_logging_header + +#include <Serial.h> + +/** + * by default you will get logging, if you do no want if for a certain file define this + * and when it compiles all the logging should get compiled away as the nullLogger has + * a big set of empty inline no-virtual functions. + */ +#ifdef LOGGING_DISABLED +#define LOGGER xenonym::logging::NullLogger::logger +#else +#define LOGGER xenonym::logging::RealLogger::logger +#endif + +/** + * LOGGERALWAYS and LOGALWAYS are always logged, due to the design there is always a logger object in you app + * its just not used if you disable logging. + * this allows you to log critial messages when logging is disabled for the module. + */ +#define LOGGERALWAYS xenonym::logging::RealLogger::logger +#define LOGALWAYS xenonym::logging::RealLogger::logger << xenonym::logging::eol + +/** + * to get the indents right easily the simplist solution is to send an end-of-line (eol) + * at the BEGINNING of each log line; + * if you want the log at the end of the previous line use LOGGER << instead of the more common LOG << + */ +#define LOG LOGGER << xenonym::logging::eol + +#define LOGFUNC( x ) xenonym::logging::Func func( x, __FILE__, __LINE__ ) +#define LOGSCOPE( n, x ) xenonym::logging::Scope n( x, __FILE__, __LINE__ ) + +namespace xenonym +{ + namespace logging + { + class LogManipulator + { + public: + virtual void log ( unsigned i ) = 0; + virtual void log ( int i ) = 0; + virtual void log ( long long i ) = 0; + virtual void log ( unsigned long long i ) = 0; + virtual void log ( char c ) = 0; + virtual void log ( char const * str ) = 0; + virtual void set_radix ( int i ) = 0; + virtual void set_indent ( int i ) = 0; + virtual int get_indent () = 0; + }; + + typedef void (*manipFunc)( LogManipulator & ); + + class NullLogger + { + public: + NullLogger & operator<< ( unsigned i ) { return *this; } + NullLogger & operator<< ( int i ) { return *this; } + NullLogger & operator<< ( long long i ) { return *this; } + NullLogger & operator<< ( unsigned long long int i ) { return *this; } + NullLogger & operator<< ( char i ) { return *this; } + NullLogger & operator<< ( char const * str ) { return *this; } + NullLogger & operator<< ( manipFunc manipulator ) { return *this; } + static NullLogger logger; + }; + + class RealLogManipulator; + class RealLogger + { + private: + friend class RealLogManipulator; + mbed::Serial m_comms; + int m_radix; + int m_indent; + public: + RealLogger(); + RealLogger & operator<< ( unsigned i ); + RealLogger & operator<< ( int i ); + RealLogger & operator<< ( long long i ); + RealLogger & operator<< ( unsigned long long int i ); + RealLogger & operator<< ( char i ); + RealLogger & operator<< ( char const * str ); + RealLogger & operator<< ( manipFunc manipulator ); + static RealLogger logger; + }; + + /** + * will sent an end of line and then indent the log stream as required + * N.B. LOG << "\n" will NOT output the indent to the log stream. + */ + void eol( LogManipulator & ); + void hex( LogManipulator & ); + void dec( LogManipulator & ); + void indent( LogManipulator & ); + void outdent( LogManipulator & ); + + class Locn + { + protected: + char const * m_file; + int m_line; + public: + Locn(char const * const file, int line ); + virtual ~Locn(); + }; + class Scope : public Locn + { + public: + Scope(char const * const file, int line ); + virtual ~Scope(); + }; + + class Func : public Locn + { + private: + char const * m_name; + public: + Func(char const * const name, char const * const file, int line ); + virtual ~Func(); + }; + + } // namespace logging; +} // namespace xenonym; + +#endif /* } xenonym_logging_header */