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>>
xenonym_logging.h@0:eae9045546f3, 2011-08-04 (annotated)
- Committer:
- xenonym
- Date:
- Thu Aug 04 20:29:26 2011 +0000
- Revision:
- 0:eae9045546f3
- Child:
- 1:41f6c5ec11c2
First released library
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
xenonym | 0:eae9045546f3 | 1 | #ifndef xenonym_logging_header /* { */ |
xenonym | 0:eae9045546f3 | 2 | #define xenonym_logging_header |
xenonym | 0:eae9045546f3 | 3 | |
xenonym | 0:eae9045546f3 | 4 | #include <Serial.h> |
xenonym | 0:eae9045546f3 | 5 | |
xenonym | 0:eae9045546f3 | 6 | /** |
xenonym | 0:eae9045546f3 | 7 | * by default you will get logging, if you do no want if for a certain file define this |
xenonym | 0:eae9045546f3 | 8 | * and when it compiles all the logging should get compiled away as the nullLogger has |
xenonym | 0:eae9045546f3 | 9 | * a big set of empty inline no-virtual functions. |
xenonym | 0:eae9045546f3 | 10 | */ |
xenonym | 0:eae9045546f3 | 11 | #ifdef LOGGING_DISABLED |
xenonym | 0:eae9045546f3 | 12 | #define LOGGER xenonym::logging::NullLogger::logger |
xenonym | 0:eae9045546f3 | 13 | #else |
xenonym | 0:eae9045546f3 | 14 | #define LOGGER xenonym::logging::RealLogger::logger |
xenonym | 0:eae9045546f3 | 15 | #endif |
xenonym | 0:eae9045546f3 | 16 | |
xenonym | 0:eae9045546f3 | 17 | /** |
xenonym | 0:eae9045546f3 | 18 | * LOGGERALWAYS and LOGALWAYS are always logged, due to the design there is always a logger object in you app |
xenonym | 0:eae9045546f3 | 19 | * its just not used if you disable logging. |
xenonym | 0:eae9045546f3 | 20 | * this allows you to log critial messages when logging is disabled for the module. |
xenonym | 0:eae9045546f3 | 21 | */ |
xenonym | 0:eae9045546f3 | 22 | #define LOGGERALWAYS xenonym::logging::RealLogger::logger |
xenonym | 0:eae9045546f3 | 23 | #define LOGALWAYS xenonym::logging::RealLogger::logger << xenonym::logging::eol |
xenonym | 0:eae9045546f3 | 24 | |
xenonym | 0:eae9045546f3 | 25 | /** |
xenonym | 0:eae9045546f3 | 26 | * to get the indents right easily the simplist solution is to send an end-of-line (eol) |
xenonym | 0:eae9045546f3 | 27 | * at the BEGINNING of each log line; |
xenonym | 0:eae9045546f3 | 28 | * if you want the log at the end of the previous line use LOGGER << instead of the more common LOG << |
xenonym | 0:eae9045546f3 | 29 | */ |
xenonym | 0:eae9045546f3 | 30 | #define LOG LOGGER << xenonym::logging::eol |
xenonym | 0:eae9045546f3 | 31 | |
xenonym | 0:eae9045546f3 | 32 | #define LOGFUNC( x ) xenonym::logging::Func func( x, __FILE__, __LINE__ ) |
xenonym | 0:eae9045546f3 | 33 | #define LOGSCOPE( n, x ) xenonym::logging::Scope n( x, __FILE__, __LINE__ ) |
xenonym | 0:eae9045546f3 | 34 | |
xenonym | 0:eae9045546f3 | 35 | namespace xenonym |
xenonym | 0:eae9045546f3 | 36 | { |
xenonym | 0:eae9045546f3 | 37 | namespace logging |
xenonym | 0:eae9045546f3 | 38 | { |
xenonym | 0:eae9045546f3 | 39 | class LogManipulator |
xenonym | 0:eae9045546f3 | 40 | { |
xenonym | 0:eae9045546f3 | 41 | public: |
xenonym | 0:eae9045546f3 | 42 | virtual void log ( unsigned i ) = 0; |
xenonym | 0:eae9045546f3 | 43 | virtual void log ( int i ) = 0; |
xenonym | 0:eae9045546f3 | 44 | virtual void log ( long long i ) = 0; |
xenonym | 0:eae9045546f3 | 45 | virtual void log ( unsigned long long i ) = 0; |
xenonym | 0:eae9045546f3 | 46 | virtual void log ( char c ) = 0; |
xenonym | 0:eae9045546f3 | 47 | virtual void log ( char const * str ) = 0; |
xenonym | 0:eae9045546f3 | 48 | virtual void set_radix ( int i ) = 0; |
xenonym | 0:eae9045546f3 | 49 | virtual void set_indent ( int i ) = 0; |
xenonym | 0:eae9045546f3 | 50 | virtual int get_indent () = 0; |
xenonym | 0:eae9045546f3 | 51 | }; |
xenonym | 0:eae9045546f3 | 52 | |
xenonym | 0:eae9045546f3 | 53 | typedef void (*manipFunc)( LogManipulator & ); |
xenonym | 0:eae9045546f3 | 54 | |
xenonym | 0:eae9045546f3 | 55 | class NullLogger |
xenonym | 0:eae9045546f3 | 56 | { |
xenonym | 0:eae9045546f3 | 57 | public: |
xenonym | 0:eae9045546f3 | 58 | NullLogger & operator<< ( unsigned i ) { return *this; } |
xenonym | 0:eae9045546f3 | 59 | NullLogger & operator<< ( int i ) { return *this; } |
xenonym | 0:eae9045546f3 | 60 | NullLogger & operator<< ( long long i ) { return *this; } |
xenonym | 0:eae9045546f3 | 61 | NullLogger & operator<< ( unsigned long long int i ) { return *this; } |
xenonym | 0:eae9045546f3 | 62 | NullLogger & operator<< ( char i ) { return *this; } |
xenonym | 0:eae9045546f3 | 63 | NullLogger & operator<< ( char const * str ) { return *this; } |
xenonym | 0:eae9045546f3 | 64 | NullLogger & operator<< ( manipFunc manipulator ) { return *this; } |
xenonym | 0:eae9045546f3 | 65 | static NullLogger logger; |
xenonym | 0:eae9045546f3 | 66 | }; |
xenonym | 0:eae9045546f3 | 67 | |
xenonym | 0:eae9045546f3 | 68 | class RealLogManipulator; |
xenonym | 0:eae9045546f3 | 69 | class RealLogger |
xenonym | 0:eae9045546f3 | 70 | { |
xenonym | 0:eae9045546f3 | 71 | private: |
xenonym | 0:eae9045546f3 | 72 | friend class RealLogManipulator; |
xenonym | 0:eae9045546f3 | 73 | mbed::Serial m_comms; |
xenonym | 0:eae9045546f3 | 74 | int m_radix; |
xenonym | 0:eae9045546f3 | 75 | int m_indent; |
xenonym | 0:eae9045546f3 | 76 | public: |
xenonym | 0:eae9045546f3 | 77 | RealLogger(); |
xenonym | 0:eae9045546f3 | 78 | RealLogger & operator<< ( unsigned i ); |
xenonym | 0:eae9045546f3 | 79 | RealLogger & operator<< ( int i ); |
xenonym | 0:eae9045546f3 | 80 | RealLogger & operator<< ( long long i ); |
xenonym | 0:eae9045546f3 | 81 | RealLogger & operator<< ( unsigned long long int i ); |
xenonym | 0:eae9045546f3 | 82 | RealLogger & operator<< ( char i ); |
xenonym | 0:eae9045546f3 | 83 | RealLogger & operator<< ( char const * str ); |
xenonym | 0:eae9045546f3 | 84 | RealLogger & operator<< ( manipFunc manipulator ); |
xenonym | 0:eae9045546f3 | 85 | static RealLogger logger; |
xenonym | 0:eae9045546f3 | 86 | }; |
xenonym | 0:eae9045546f3 | 87 | |
xenonym | 0:eae9045546f3 | 88 | /** |
xenonym | 0:eae9045546f3 | 89 | * will sent an end of line and then indent the log stream as required |
xenonym | 0:eae9045546f3 | 90 | * N.B. LOG << "\n" will NOT output the indent to the log stream. |
xenonym | 0:eae9045546f3 | 91 | */ |
xenonym | 0:eae9045546f3 | 92 | void eol( LogManipulator & ); |
xenonym | 0:eae9045546f3 | 93 | void hex( LogManipulator & ); |
xenonym | 0:eae9045546f3 | 94 | void dec( LogManipulator & ); |
xenonym | 0:eae9045546f3 | 95 | void indent( LogManipulator & ); |
xenonym | 0:eae9045546f3 | 96 | void outdent( LogManipulator & ); |
xenonym | 0:eae9045546f3 | 97 | |
xenonym | 0:eae9045546f3 | 98 | class Locn |
xenonym | 0:eae9045546f3 | 99 | { |
xenonym | 0:eae9045546f3 | 100 | protected: |
xenonym | 0:eae9045546f3 | 101 | char const * m_file; |
xenonym | 0:eae9045546f3 | 102 | int m_line; |
xenonym | 0:eae9045546f3 | 103 | public: |
xenonym | 0:eae9045546f3 | 104 | Locn(char const * const file, int line ); |
xenonym | 0:eae9045546f3 | 105 | virtual ~Locn(); |
xenonym | 0:eae9045546f3 | 106 | }; |
xenonym | 0:eae9045546f3 | 107 | class Scope : public Locn |
xenonym | 0:eae9045546f3 | 108 | { |
xenonym | 0:eae9045546f3 | 109 | public: |
xenonym | 0:eae9045546f3 | 110 | Scope(char const * const file, int line ); |
xenonym | 0:eae9045546f3 | 111 | virtual ~Scope(); |
xenonym | 0:eae9045546f3 | 112 | }; |
xenonym | 0:eae9045546f3 | 113 | |
xenonym | 0:eae9045546f3 | 114 | class Func : public Locn |
xenonym | 0:eae9045546f3 | 115 | { |
xenonym | 0:eae9045546f3 | 116 | private: |
xenonym | 0:eae9045546f3 | 117 | char const * m_name; |
xenonym | 0:eae9045546f3 | 118 | public: |
xenonym | 0:eae9045546f3 | 119 | Func(char const * const name, char const * const file, int line ); |
xenonym | 0:eae9045546f3 | 120 | virtual ~Func(); |
xenonym | 0:eae9045546f3 | 121 | }; |
xenonym | 0:eae9045546f3 | 122 | |
xenonym | 0:eae9045546f3 | 123 | } // namespace logging; |
xenonym | 0:eae9045546f3 | 124 | } // namespace xenonym; |
xenonym | 0:eae9045546f3 | 125 | |
xenonym | 0:eae9045546f3 | 126 | #endif /* } xenonym_logging_header */ |