|
Boost Users : |
From: Stephen Torri (storri_at_[hidden])
Date: 2007-05-17 11:56:59
Here is the latest form using what I believe is the Meyer form of the
singleton. What I was using earlier was from the GoF book on patterns.
They use a pointer and instead of a static variable. I would appreciate
any comments on this code. The intent is to provide a single-threaded
tracing capability which is logged to a file.
----------- HEADER -----------------
#ifndef LIBREVERSE_TRACE_H
#define LIBREVERSE_TRACE_H
#include <boost/cstdint.hpp>
#include <boost/shared_ptr.hpp>
#include <fstream>
#include "Reverse.h"
namespace libreverse { namespace trace {
/* Idea taken from http://www.codeproject.com/debug/xytrace.asp
* (28 Jan 2002 - Xiangyang Liu)
*
* I have modified this so that we don't use varargs and use
constant types
*/
class Trace_State {
public:
typedef boost::shared_ptr<Trace_State> ptr_t;
static Trace_State& Instance();
void set_Trace_File_Prefix ( std::string name );
void set_Trace_Level ( boost::uint32_t level );
void open_Trace_File ( void );
std::string get_ID_String ( void );
void close_Trace_File ( void );
boost::uint32_t get_Trace_Level ( void ) const;
void write_Message ( boost::uint32_t level, std::string msg );
private:
Trace_State();
virtual ~Trace_State();
std::string m_file_prefix;
boost::uint32_t m_trace_level;
std::ofstream m_log_stream;
};
class Trace {
public:
static bool write_Trace ( boost::uint32_t level,
std::string message );
};
} /* namespace trace */
} /* namespace trace */
#endif /* LIBREVERSE_TRACE_H */
--------- SOURCE -------------
#include "Trace.h"
#include <boost/format.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <sstream>
#ifndef WIN32
#include <unistd.h>
#else
#include <windows.h>
#endif /* WIN32 */
namespace libreverse { namespace trace {
Trace_State& Trace_State::Instance()
{
static Trace_State instance_obj;
return instance_obj;
}
void
Trace_State::set_Trace_File_Prefix ( std::string name )
{
assert ( ! name.empty() );
// Lock the resource
// Close the present file
m_file_prefix = name;
// Unlock the resource
}
void
Trace_State::set_Trace_Level ( boost::uint32_t level )
{
// Lock the resource
// Change level
m_trace_level = level;
// Unlock the resource
}
void
Trace_State::open_Trace_File ( void )
{
if ( ! m_log_stream.is_open() )
{
// Create file name
std::stringstream name;
name << boost::format("%s_%s.txt")
% m_file_prefix
% this->get_ID_String();
m_log_stream.open ( (name.str()).c_str() );
}
}
std::string
Trace_State::get_ID_String ( void )
{
// Create id string
std::stringstream name;
// Get current time
boost::posix_time::ptime now =
boost::posix_time::second_clock::local_time();
std::tm tm_ref = boost::posix_time::to_tm ( now );
boost::gregorian::date today = now.date();
name << boost::format ( "%s_%02d:%02d:%02d" )
% boost::gregorian::to_iso_extended_string ( today )
% tm_ref.tm_hour
% tm_ref.tm_min
% tm_ref.tm_sec;
return name.str();
}
void
Trace_State::close_Trace_File ( void )
{
if ( m_log_stream.is_open() )
{
m_log_stream.close();
}
}
boost::uint32_t
Trace_State::get_Trace_Level ( void ) const
{
boost::uint32_t level = 0;
// Lock the resource
// get the level
level = m_trace_level;
// unlock the resource
// return the level
return level;
}
void
Trace_State::write_Message ( boost::uint32_t level, std::string
msg )
{
// Write ID
m_log_stream << boost::format("%s_%d: " )
% this->get_ID_String()
#ifndef WIN32
% getpid()
#else
% GetCurrentProcessId()
#endif /* WIN32 */
<< std::flush;
// Write message prefix
if ( level == libreverse::api::TraceLevel::TraceWarn )
{
m_log_stream << "(WW) ";
}
else if ( level == libreverse::api::TraceLevel::TraceError )
{
m_log_stream << "(EE) ";
}
else if ( level == libreverse::api::TraceLevel::TraceInfo )
{
m_log_stream << "(II) ";
}
else if ( level == libreverse::api::TraceLevel::TraceDebug )
{
m_log_stream << "(DEBUG) ";
}
else if ( level == libreverse::api::TraceLevel::TraceDetail )
{
m_log_stream << "(DETAIL) ";
}
else if ( level == libreverse::api::TraceLevel::TraceData )
{
m_log_stream << "(DATA) ";
}
else
{
// We should not be here
abort();
}
// Write to the file
m_log_stream << msg << std::endl << std::flush;
// Unlock the resource
}
Trace_State::Trace_State()
: m_file_prefix ( "Trace" ),
m_trace_level ( libreverse::api::TraceLevel::TraceNone )
{}
Trace_State::~Trace_State()
{
this->close_Trace_File();
}
#ifdef LIBREVERSE_DEBUG
bool
Trace::write_Trace ( boost::uint32_t level,
std::string message )
{
// If the level is equal to or greater than the present
// level we record out message.
if ( ( Trace_State::Instance().get_Trace_Level() != 0 ) &&
( level <=
Trace_State::Instance().get_Trace_Level() ) )
{
Trace_State::Instance().write_Message ( level,
message );
}
return true;
}
#else
bool
Trace::write_Trace ( boost::uint32_t,
std::string )
{
return true;
}
#endif
} /* namespace trace */
} /* namespace trace */
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net