namespace Log {
#include <ctime>
#include <string>
#include <boost\scoped_ptr.hpp>
#ifndef LOG_PREPEND_TIMESTAMP_DEFAULT
#define LOG_PREPEND_TIMESTAMP_DEFAULT false
#endif
enum LogLevel_t { logFatal = 0, logError = 1, logWarning = 2, logVerbose = 3, logDebug = 4 };
std::string LogLevelToString( const LogLevel_t level ) {
static const char* const buffer[] = { "Fatal", "Error", "Warning", "Verbose", "Debug" };
return buffer[level];
}
class Log: public boost::noncopyable {
protected:
boost::scoped_ptr< std::ostringstream > Output_String;
bool m_Prepending_Timestamp;
size_t m_LinesOutputted;
public:
Log():
Output_String( new std::ostringstream ),
m_Prepending_Timestamp( LOG_PREPEND_TIMESTAMP_DEFAULT ),
m_LinesOutputted( 0 ) {}
void UsingTimestamp( bool Prepending_Timestamp = true ) {
m_Prepending_Timestamp = Prepending_Timestamp;
}
std::ostringstream& Get( const LogLevel_t level ) {
// Write line number
++m_LinesOutputted;
*Output_String << m_LinesOutputted << " | ";
if( m_Prepending_Timestamp == true ) {
//prepare a timestamp
time_t now = time( NULL );
std::string formatted_time( asctime( localtime( &now ) ) ); /* &now can be replaced with the above call when r-value references work (maybe) saving a stack var */
formatted_time.erase(( formatted_time.length( ) - 1 ), 1 ); /* Removes the \n(newline) that asctime adds for better formatting */
// Write timestamp to stream
*Output_String << formatted_time << " || ";
}
// Write Logging level(severity) to stream
*Output_String << LogLevelToString( level ) << " || ";
return *Output_String;
}
void Flush() {
*Output_String << std::endl;
fprintf( stdout, "%s", Output_String->str( ).c_str( ) );
fflush( stdout );
Output_String.reset( new std::ostringstream ); /* streams have lots of internal state clean streams are good */
}
~Log() {
*Output_String << std::endl;
fprintf( stdout, "%s", Output_String->str( ).c_str( ) );
fflush( stdout );
}
};
如何在没有宏的情况下实现阈值?
如果我用一个支票包裹get的主体,我仍然必须返回stringstream。
我可以将返回类型更改为指针而不是引用然后返回NULL但是然后每个logger语句都必须对返回的字符串流进行空检查