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@2:f3c036aca508, 2011-08-04 (annotated)
- Committer:
- xenonym
- Date:
- Thu Aug 04 22:02:33 2011 +0000
- Revision:
- 2:f3c036aca508
- Parent:
- 1:41f6c5ec11c2
updated the description so its easier to publish updates when I have some
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 | 2:f3c036aca508 | 32 | /** |
xenonym | 2:f3c036aca508 | 33 | * if logging is disabled then we do not want to create any scope logging objects. |
xenonym | 2:f3c036aca508 | 34 | */ |
xenonym | 1:41f6c5ec11c2 | 35 | #ifdef LOGGING_DISABLED |
xenonym | 1:41f6c5ec11c2 | 36 | #define LOGFUNC( x ) |
xenonym | 1:41f6c5ec11c2 | 37 | #define LOGSCOPE( n, x ) |
xenonym | 1:41f6c5ec11c2 | 38 | #else |
xenonym | 0:eae9045546f3 | 39 | #define LOGFUNC( x ) xenonym::logging::Func func( x, __FILE__, __LINE__ ) |
xenonym | 0:eae9045546f3 | 40 | #define LOGSCOPE( n, x ) xenonym::logging::Scope n( x, __FILE__, __LINE__ ) |
xenonym | 1:41f6c5ec11c2 | 41 | #endif |
xenonym | 1:41f6c5ec11c2 | 42 | |
xenonym | 0:eae9045546f3 | 43 | |
xenonym | 0:eae9045546f3 | 44 | namespace xenonym |
xenonym | 0:eae9045546f3 | 45 | { |
xenonym | 0:eae9045546f3 | 46 | namespace logging |
xenonym | 0:eae9045546f3 | 47 | { |
xenonym | 0:eae9045546f3 | 48 | class LogManipulator |
xenonym | 0:eae9045546f3 | 49 | { |
xenonym | 0:eae9045546f3 | 50 | public: |
xenonym | 0:eae9045546f3 | 51 | virtual void log ( unsigned i ) = 0; |
xenonym | 0:eae9045546f3 | 52 | virtual void log ( int i ) = 0; |
xenonym | 0:eae9045546f3 | 53 | virtual void log ( long long i ) = 0; |
xenonym | 0:eae9045546f3 | 54 | virtual void log ( unsigned long long i ) = 0; |
xenonym | 0:eae9045546f3 | 55 | virtual void log ( char c ) = 0; |
xenonym | 0:eae9045546f3 | 56 | virtual void log ( char const * str ) = 0; |
xenonym | 0:eae9045546f3 | 57 | virtual void set_radix ( int i ) = 0; |
xenonym | 0:eae9045546f3 | 58 | virtual void set_indent ( int i ) = 0; |
xenonym | 0:eae9045546f3 | 59 | virtual int get_indent () = 0; |
xenonym | 0:eae9045546f3 | 60 | }; |
xenonym | 0:eae9045546f3 | 61 | |
xenonym | 0:eae9045546f3 | 62 | typedef void (*manipFunc)( LogManipulator & ); |
xenonym | 0:eae9045546f3 | 63 | |
xenonym | 0:eae9045546f3 | 64 | class NullLogger |
xenonym | 0:eae9045546f3 | 65 | { |
xenonym | 0:eae9045546f3 | 66 | public: |
xenonym | 0:eae9045546f3 | 67 | NullLogger & operator<< ( unsigned i ) { return *this; } |
xenonym | 0:eae9045546f3 | 68 | NullLogger & operator<< ( int i ) { return *this; } |
xenonym | 0:eae9045546f3 | 69 | NullLogger & operator<< ( long long i ) { return *this; } |
xenonym | 0:eae9045546f3 | 70 | NullLogger & operator<< ( unsigned long long int i ) { return *this; } |
xenonym | 0:eae9045546f3 | 71 | NullLogger & operator<< ( char i ) { return *this; } |
xenonym | 0:eae9045546f3 | 72 | NullLogger & operator<< ( char const * str ) { return *this; } |
xenonym | 0:eae9045546f3 | 73 | NullLogger & operator<< ( manipFunc manipulator ) { return *this; } |
xenonym | 0:eae9045546f3 | 74 | static NullLogger logger; |
xenonym | 0:eae9045546f3 | 75 | }; |
xenonym | 0:eae9045546f3 | 76 | |
xenonym | 0:eae9045546f3 | 77 | class RealLogManipulator; |
xenonym | 0:eae9045546f3 | 78 | class RealLogger |
xenonym | 0:eae9045546f3 | 79 | { |
xenonym | 0:eae9045546f3 | 80 | private: |
xenonym | 0:eae9045546f3 | 81 | friend class RealLogManipulator; |
xenonym | 0:eae9045546f3 | 82 | mbed::Serial m_comms; |
xenonym | 0:eae9045546f3 | 83 | int m_radix; |
xenonym | 0:eae9045546f3 | 84 | int m_indent; |
xenonym | 0:eae9045546f3 | 85 | public: |
xenonym | 0:eae9045546f3 | 86 | RealLogger(); |
xenonym | 0:eae9045546f3 | 87 | RealLogger & operator<< ( unsigned i ); |
xenonym | 0:eae9045546f3 | 88 | RealLogger & operator<< ( int i ); |
xenonym | 0:eae9045546f3 | 89 | RealLogger & operator<< ( long long i ); |
xenonym | 0:eae9045546f3 | 90 | RealLogger & operator<< ( unsigned long long int i ); |
xenonym | 0:eae9045546f3 | 91 | RealLogger & operator<< ( char i ); |
xenonym | 0:eae9045546f3 | 92 | RealLogger & operator<< ( char const * str ); |
xenonym | 0:eae9045546f3 | 93 | RealLogger & operator<< ( manipFunc manipulator ); |
xenonym | 0:eae9045546f3 | 94 | static RealLogger logger; |
xenonym | 0:eae9045546f3 | 95 | }; |
xenonym | 0:eae9045546f3 | 96 | |
xenonym | 0:eae9045546f3 | 97 | /** |
xenonym | 0:eae9045546f3 | 98 | * will sent an end of line and then indent the log stream as required |
xenonym | 0:eae9045546f3 | 99 | * N.B. LOG << "\n" will NOT output the indent to the log stream. |
xenonym | 0:eae9045546f3 | 100 | */ |
xenonym | 0:eae9045546f3 | 101 | void eol( LogManipulator & ); |
xenonym | 0:eae9045546f3 | 102 | void hex( LogManipulator & ); |
xenonym | 0:eae9045546f3 | 103 | void dec( LogManipulator & ); |
xenonym | 0:eae9045546f3 | 104 | void indent( LogManipulator & ); |
xenonym | 0:eae9045546f3 | 105 | void outdent( LogManipulator & ); |
xenonym | 0:eae9045546f3 | 106 | |
xenonym | 0:eae9045546f3 | 107 | class Locn |
xenonym | 0:eae9045546f3 | 108 | { |
xenonym | 0:eae9045546f3 | 109 | protected: |
xenonym | 0:eae9045546f3 | 110 | char const * m_file; |
xenonym | 0:eae9045546f3 | 111 | int m_line; |
xenonym | 0:eae9045546f3 | 112 | public: |
xenonym | 0:eae9045546f3 | 113 | Locn(char const * const file, int line ); |
xenonym | 0:eae9045546f3 | 114 | virtual ~Locn(); |
xenonym | 0:eae9045546f3 | 115 | }; |
xenonym | 0:eae9045546f3 | 116 | class Scope : public Locn |
xenonym | 0:eae9045546f3 | 117 | { |
xenonym | 0:eae9045546f3 | 118 | public: |
xenonym | 0:eae9045546f3 | 119 | Scope(char const * const file, int line ); |
xenonym | 0:eae9045546f3 | 120 | virtual ~Scope(); |
xenonym | 0:eae9045546f3 | 121 | }; |
xenonym | 0:eae9045546f3 | 122 | |
xenonym | 0:eae9045546f3 | 123 | class Func : public Locn |
xenonym | 0:eae9045546f3 | 124 | { |
xenonym | 0:eae9045546f3 | 125 | private: |
xenonym | 0:eae9045546f3 | 126 | char const * m_name; |
xenonym | 0:eae9045546f3 | 127 | public: |
xenonym | 0:eae9045546f3 | 128 | Func(char const * const name, char const * const file, int line ); |
xenonym | 0:eae9045546f3 | 129 | virtual ~Func(); |
xenonym | 0:eae9045546f3 | 130 | }; |
xenonym | 0:eae9045546f3 | 131 | |
xenonym | 0:eae9045546f3 | 132 | } // namespace logging; |
xenonym | 0:eae9045546f3 | 133 | } // namespace xenonym; |
xenonym | 0:eae9045546f3 | 134 | |
xenonym | 0:eae9045546f3 | 135 | #endif /* } xenonym_logging_header */ |