From aa82dc64b397b6ca0d336d91638d4f4b849e3667 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Tue, 26 Jun 2007 05:10:58 +0000 Subject: Fixed a minor bug in FString, and added the Logger and a test...it's cool, and a decent replacement for multilog now that we use runit. --- src/fstring.h | 1 + src/logger.cpp | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/logger.h | 112 ++++++++++++++++++++++++++++++++++++++++++++++ src/tests/logger.cpp | 28 ++++++++++++ 4 files changed, 264 insertions(+) create mode 100644 src/logger.cpp create mode 100644 src/logger.h create mode 100644 src/tests/logger.cpp (limited to 'src') diff --git a/src/fstring.h b/src/fstring.h index 9d88bd4..fe34804 100644 --- a/src/fstring.h +++ b/src/fstring.h @@ -128,6 +128,7 @@ namespace Bu */ void append( const chr *pData ) { + if( !pData ) return; long nLen; for( nLen = 0; pData[nLen] != (chr)0; nLen++ ); if( nLen == 0 ) diff --git a/src/logger.cpp b/src/logger.cpp new file mode 100644 index 0000000..848dfb1 --- /dev/null +++ b/src/logger.cpp @@ -0,0 +1,123 @@ +#include "bu/logger.h" +#include +#include +#include + +Bu::Logger::Logger() +{ +} + +Bu::Logger::~Logger() +{ +} + +void Bu::Logger::log( int nLevel, const char *sFile, const char *sFunction, int nLine, const char *sFormat, ...) +{ + if( (nLevel&nLevelMask) == 0 ) + return; + + va_list ap; + va_start( ap, sFormat ); + char *text; + vasprintf( &text, sFormat, ap ); + va_end(ap); + + time_t t = time(NULL); + + char *line = NULL; + struct tm *pTime; + pTime = localtime( &t ); + asprintf( + &line, + sLogFormat.getStr(), + pTime->tm_year+1900, + pTime->tm_mon+1, + pTime->tm_mday, + pTime->tm_hour, + pTime->tm_min, + pTime->tm_sec, + nLevel, + sFile, + nLine, + text, + sFunction + ); + write( fileno(stdout), line, strlen(line) ); + free( text ); + free( line ); +} + +void Bu::Logger::setFormat( const Bu::FString &str ) +{ + sLogFormat = ""; + + static char fmts[][4]={ + {'y', 'd', '0', '1'}, + {'m', 'd', '0', '2'}, + {'d', 'd', '0', '3'}, + {'h', 'd', '0', '4'}, + {'M', 'd', '0', '5'}, + {'s', 'd', '0', '6'}, + {'L', 'd', '0', '7'}, + {'f', 's', '0', '8'}, + {'l', 'd', '0', '9'}, + {'t', 's', '1', '0'}, + {'F', 's', '1', '1'}, + {'\0', '\0', '\0', '\0'}, + }; + + for( const char *s = str.getStr(); *s; s++ ) + { + if( *s == '%' ) + { + sLogFormat += '%'; + s++; + for( int l = 0;; l++ ) + { + if( fmts[l][0] == '\0' ) + { + sLogFormat += *s; + break; + } + else if( *s == fmts[l][0] ) + { + sLogFormat += fmts[l][2]; + sLogFormat += fmts[l][3]; + sLogFormat += '$'; + sLogFormat += fmts[l][1]; + break; + } + } + } + else + { + sLogFormat += *s; + } + } + sLogFormat += '\n'; + + write( fileno(stdout), sLogFormat.getStr(), sLogFormat.getSize() ); +} + +void Bu::Logger::setMask( int n ) +{ + nLevelMask = n; +} + +void Bu::Logger::setLevel( int n ) +{ + int j; + for( j = 31; j > 0; j-- ) + { + if( (n&(1<= 0; j-- ) + { + n |= (1< + { + friend class Bu::Singleton; + private: + Logger(); + virtual ~Logger(); + + public: + void log( int nLevel, const char *sFile, const char *sFunction, int nLine, const char *sFormat, ...); + + void setFormat( const Bu::FString &str ); + void setMask( int n ); + void setLevel( int n ); + + private: + Bu::FString sLogFormat; + int nLevelMask; + }; +} + +/** + * Use Bu::Logger to log a message at the given level and with the given message + * using printf style formatting, and include extra data such as the current + * file, line number, and function. + */ +#define lineLog( nLevel, sFrmt, ...) \ + Bu::Logger::getInstance().log( nLevel, __FILE__, __PRETTY_FUNCTION__, __LINE__, sFrmt, ##__VA_ARGS__ ) + +/** + * Set the Bu::Logger logging mask directly. See Bu::Logger::setMask for + * details. + */ +#define setLogMask( nLevel ) \ + Bu::Logger::getInstance().setMask( nLevel ) + +/** + * Set the Bu::Logger format. See Bu::Logger::setFormat for details. + */ +#define setLogFormat( sFrmt ) \ + Bu::Logger::getInstance().setFormat( sFrmt ) + +/** + * Set the Bu::Logger logging mask simulating levels. See Bu::Logger::setLevel + * for details. + */ +#define setLogLevel( nLevel ) \ + Bu::Logger::getInstance().setLevel( nLevel ) + +#endif diff --git a/src/tests/logger.cpp b/src/tests/logger.cpp new file mode 100644 index 0000000..a271443 --- /dev/null +++ b/src/tests/logger.cpp @@ -0,0 +1,28 @@ +#include "bu/logger.h" +#include +#include + +class Thing +{ + public: + Thing() + { + lineLog( 2, "Want a thing?"); + } + + void go( int i ) + { + lineLog( 1, "GO!!!!"); + } +}; + +int main() +{ + setLogLevel( 4 ); + setLogFormat("%L: %y-%m-%d %h:%M:%s %f:%l:%F: %t"); + lineLog( 5, "Hey, error: %s", strerror( errno ) ); + + Thing gh; + gh.go( 6); +} + -- cgit v1.2.3