Skip to content

Instantly share code, notes, and snippets.

@PeterHajdu
Created May 7, 2012 09:02
Show Gist options
  • Save PeterHajdu/2626812 to your computer and use it in GitHub Desktop.
Save PeterHajdu/2626812 to your computer and use it in GitHub Desktop.
logger
*.o
*.so
*.swp
*~
tst/test
tst/test.cpp
A logger design example. The project serves solely presentation purposes.

A logger design example. The project serves solely presentation purposes.

#include <logger/BlockGuard.hpp>
logger::BlockGuard::BlockGuard( Logger& logger, const std::string& blockId )
: m_logger( logger )
, m_blockId( blockId )
, ENTER( "Entering " )
, LEAVE( "Leaving " )
{
m_logger.logMessage( 1, ENTER + blockId );
}
logger::BlockGuard::~BlockGuard()
{
m_logger.logMessage( 1, LEAVE + m_blockId );
}
#ifndef _LOGGER_BLOCKGUARD_HPP_
#define _LOGGER_BLOCKGUARD_HPP_
#include <logger/Logger.hpp>
#include <string>
namespace logger
{
class BlockGuard
{
public:
BlockGuard( Logger& logger, const std::string& blockId );
virtual ~BlockGuard();
private:
Logger& m_logger;
const std::string m_blockId;
const std::string ENTER;
const std::string LEAVE;
};
}
#endif
#ifndef _LOGGER_DEFINITIONS_HPP_
#define _LOGGER_DEFINITIONS_HPP_
#include <logger/Logger.hpp>
#include <logger/BlockGuard.hpp>
#define TRACE_FUNCTION() logger::BlockGuard __bg__( m_logger, std::string( __FUNCTION__ ) );
#define TRACE_STREAM( level, what ) m_logger.logStream( level ) what; m_logger.flushStream();
#endif
#include <logger/Logger.hpp>
#include <logger/PlatformLogger.hpp>
logger::Logger::Logger( const std::string& className, PlatformLogger& platformLogger )
: m_className( className )
, m_platformLogger( platformLogger )
, SEPARATOR( " | " )
{
}
logger::Logger::Logger( const std::string& className, Logger& otherLogger )
: m_className( className )
, m_platformLogger( otherLogger.m_platformLogger )
, SEPARATOR( " | " )
{
}
void
logger::Logger::logMessage( const PlatformLogger::LogLevel logLevel, const std::string& message )
{
m_platformLogger.logMessage( logLevel, m_className + SEPARATOR + message );
}
std::ostream&
logger::Logger::logStream( const PlatformLogger::LogLevel logLevel )
{
m_bufferLogLevel = logLevel;
return m_messageBuffer;
}
void
logger::Logger::flushStream()
{
logMessage( m_bufferLogLevel, m_messageBuffer.str() );
m_messageBuffer.str("");
}
#ifndef _LOGGER_LOGGER_HPP_
#define _LOGGER_LOGGER_HPP_
#include <logger/PlatformLogger.hpp>
#include <memory>
#include <string>
#include <sstream>
namespace logger
{
class Logger
{
public:
Logger( const std::string& className, PlatformLogger& platformLogger );
Logger( const std::string& className, Logger& otherLogger );
void logMessage( const PlatformLogger::LogLevel logLevel, const std::string& message );
std::ostream& logStream( const PlatformLogger::LogLevel logLevel );
void flushStream();
private:
Logger( const Logger& );
Logger& operator=( const Logger& );
std::string m_className;
PlatformLogger& m_platformLogger;
PlatformLogger::LogLevel m_bufferLogLevel;
std::stringstream m_messageBuffer;
const std::string SEPARATOR;
};
}
#endif
CXXTESTDIR=tst
CXXFLAGS=-Wall -pedantic -fPIC -I$(CXXTESTDIR) -I. -Iinclude
CXX=g++
TSTSRC=tst/test.cpp
TSTFILES=tst/testLogger.hpp tst/testStreamLogger.hpp tst/testBlockGuard.hpp tst/testDefinitions.hpp
SRCDIR=src
LIBDIR=build
TSTBIN=tst/test
LIB=$(LIBDIR)/liblogger.so
OBJS=$(SRCDIR)/Logger.o $(SRCDIR)/PlatformLogger.o $(SRCDIR)/StreamLogger.o $(SRCDIR)/BlockGuard.o
$(LIB): lib
$(LIBDIR):
mkdir $(LIBDIR)
lib: $(OBJS) $(LIBDIR)
$(CXX) -shared $(OBJS) -o $(LIB)
$(TSTSRC):
cxxtestgen --error-printer -o $(TSTSRC) $(TSTFILES)
$(TSTBIN): $(LIB) $(TSTSRC)
$(CXX) $(CXXFLAGS) $(TSTSRC) -o $(TSTBIN) -L$(LIBDIR) -llogger
test: $(TSTBIN)
LD_LIBRARY_PATH=$(LIBDIR) valgrind --leak-check=full --show-reachable=yes $(TSTBIN)
default: lib
clean:
rm -rf $(LIBDIR) $(SRCDIR)/*.o $(TSTSRC) $(TSTBIN)
.PHONY: clean default
#include <logger/PlatformLogger.hpp>
logger::PlatformLogger::~PlatformLogger()
{
}
#ifndef LOGGER_PLATFORMLOGGER_HPP_
#define LOGGER_PLATFORMLOGGER_HPP_
#include <string>
namespace logger
{
class PlatformLogger
{
public:
typedef int LogLevel;
virtual void logMessage( const LogLevel logLevel, const std::string& message ) = 0;
virtual ~PlatformLogger();
};
}
#endif
#ifndef PLATFORMLOGGER_STUB_HPP
#define PLATFORMLOGGER_STUB_HPP
#include <logger/PlatformLogger.hpp>
class PlatformLoggerStub : public logger::PlatformLogger
{
public:
std::string lastMessage;
logger::PlatformLogger::LogLevel lastLevel;
PlatformLoggerStub()
: lastMessage()
, lastLevel( 0 )
{
}
virtual void logMessage( logger::PlatformLogger::LogLevel logLevel, const std::string& message )
{
lastLevel = logLevel;
lastMessage = message;
}
virtual ~PlatformLoggerStub()
{
}
};
#endif
#include "logger/StreamLogger.hpp"
#include <ostream>
logger::StreamLogger::StreamLogger( std::ostream& outputStream )
: m_stream( outputStream )
{
}
void logger::StreamLogger::logMessage(const PlatformLogger::LogLevel logLevel,
const std::string& message)
{
m_stream << message << std::endl;
}
#ifndef __STREAMLOGGER__HPP_
#define __STREAMLOGGER__HPP_
#include "logger/PlatformLogger.hpp"
#include <memory>
#include <ostream>
namespace logger
{
class StreamLogger: public PlatformLogger
{
public:
StreamLogger( std::ostream& outputStream );
void logMessage( PlatformLogger::LogLevel logLevel, const std::string& message );
private:
std::ostream& m_stream;
};
}
#endif
#include "cxxtest/TestSuite.h"
#define private public
#include <logger/Logger.hpp>
#include <logger/PlatformLogger.hpp>
#include <logger/BlockGuard.hpp>
#include "PlatformLoggerStub.hpp"
class LoggerBlockGuard : public CxxTest::TestSuite
{
private:
PlatformLoggerStub m_platformLogger;
std::string m_classname;
logger::Logger m_logger;
std::string m_message;
logger::PlatformLogger::LogLevel m_level;
public:
LoggerBlockGuard()
: m_platformLogger()
, m_classname( "simple class" )
, m_logger( m_classname, m_platformLogger )
, m_message( "simple message" )
, m_level( 1 )
{
}
void setUp()
{
}
void testConstructor( void )
{
std::string blockName( __FUNCTION__ );
{
logger::BlockGuard guard( m_logger, blockName );
TS_ASSERT_EQUALS( m_platformLogger.lastMessage, m_classname + std::string( " | Entering " ) + blockName );
}
TS_ASSERT_EQUALS( m_platformLogger.lastMessage, m_classname + std::string( " | Leaving " ) + blockName );
}
};
#include "cxxtest/TestSuite.h"
#define private public
#include <logger/Log.hpp>
#include <logger/Logger.hpp>
#include <logger/PlatformLogger.hpp>
#include <logger/BlockGuard.hpp>
#include "PlatformLoggerStub.hpp"
class DummyClass
{
public:
DummyClass( logger::Logger& logger, const std::string& testString )
: m_logger( "DummyClass", logger )
, m_testString( testString )
{
TRACE_FUNCTION()
}
void someFunction()
{
TRACE_FUNCTION()
}
void streamTest()
{
TRACE_STREAM( 2, << m_testString << " *** " );
}
private:
logger::Logger m_logger;
std::string m_testString;
};
class DefinitionsTest : public CxxTest::TestSuite
{
private:
std::stringstream m_logStream;
logger::StreamLogger m_platformLogger;
std::string m_classname;
logger::Logger m_logger;
std::string m_message;
logger::PlatformLogger::LogLevel m_level;
public:
DefinitionsTest()
: m_logStream()
, m_platformLogger( m_logStream )
, m_classname( "simple class" )
, m_logger( m_classname, m_platformLogger )
, m_message( "simple message" )
, m_level( 1 )
{
}
void setUp()
{
}
void testBasic( void )
{
DummyClass dummyClass( m_logger, "foo" );
dummyClass.someFunction();
TS_ASSERT_DIFFERS( m_logStream.str().find( "Entering someFunction" ), std::string::npos );
TS_ASSERT_DIFFERS( m_logStream.str().find( "Leaving someFunction" ), std::string::npos );
TS_ASSERT_DIFFERS( m_logStream.str().find( "DummyClass" ), std::string::npos );
}
void testStreamLog( void )
{
DummyClass dummyClass( m_logger, "foo" );
dummyClass.streamTest();
TS_ASSERT_DIFFERS( m_logStream.str().find( "foo" ), std::string::npos );
}
};
#include "cxxtest/TestSuite.h"
#define private public
#include <logger/Logger.hpp>
#include <logger/PlatformLogger.hpp>
#include "PlatformLoggerStub.hpp"
class LoggerTest : public CxxTest::TestSuite
{
private:
PlatformLoggerStub m_platformLogger;
std::string m_message;
std::string m_classname;
logger::PlatformLogger::LogLevel m_level;
public:
LoggerTest()
: m_platformLogger()
, m_message( "simple message" )
, m_classname( "simple class" )
, m_level( 1 )
{
}
void setUp()
{
m_level = logger::PlatformLogger::LogLevel(m_level+1);
m_message+=" + ";
m_classname+=" - ";
}
void testSimpleLogFunction( void )
{
logger::Logger logger( m_classname, m_platformLogger );
logger.logMessage( m_level, m_message );
TS_ASSERT_EQUALS( m_level, m_platformLogger.lastLevel );
TS_ASSERT_EQUALS( m_classname+logger.SEPARATOR+m_message, m_platformLogger.lastMessage );
}
void testAlternateConstructor( void )
{
logger::Logger originalLogger( m_classname + "something else", m_platformLogger );
logger::Logger logger( m_classname, originalLogger );
logger.logMessage( m_level, m_message );
TS_ASSERT_EQUALS( m_level, m_platformLogger.lastLevel );
TS_ASSERT_EQUALS( m_classname+logger.SEPARATOR+m_message, m_platformLogger.lastMessage );
}
void testStreamLogging( void )
{
logger::Logger logger( m_classname, m_platformLogger );
logger.logStream( m_level ) << m_message << " *** " << 12;
logger.flushStream();
TS_ASSERT( logger.m_messageBuffer.str().empty() );
TS_ASSERT_EQUALS( m_level, m_platformLogger.lastLevel );
TS_ASSERT_EQUALS( m_classname+logger.SEPARATOR+m_message+std::string(" *** 12"), m_platformLogger.lastMessage );
}
};
#include "cxxtest/TestSuite.h"
#include "logger/StreamLogger.hpp"
#include <sstream>
class StreamLoggerTestSuite : public CxxTest::TestSuite
{
public:
StreamLoggerTestSuite()
: m_msg( "Hello, my name is Test Message." )
, m_level( 1 )
{
}
void setUp()
{
}
void testLogMessage( void )
{
std::stringstream outputStream;
logger::StreamLogger streamLogger( outputStream );
streamLogger.logMessage( m_level, m_msg );
TS_ASSERT_EQUALS( outputStream.str(), m_msg + std::string( "\n" ) );
}
private:
std::string m_msg;
int m_level;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment