1
0
forked from 0ad/0ad
0ad/source/network/NetLog.cpp
janwas c0ed950657 had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).

it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.

after several hours, the code now requires fewer casts and less
guesswork.

other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.

This was SVN commit r5942.
2008-05-11 18:48:32 +00:00

1108 lines
29 KiB
C++

/**
*-----------------------------------------------------------------------------
* FILE : NetLog.cpp
* PROJECT : 0 A.D.
* DESCRIPTION : Network subsystem logging classes implementation
*-----------------------------------------------------------------------------
*/
// INCLUDES
#include "precompiled.h"
#include "NetLog.h"
#include "ps/CConsole.h"
#include "lib/file/path.h"
#include <stdio.h>
#include <stdarg.h>
#include <time.h>
//-----------------------------------------------------------------------------
// Name: CNetLogEvent()
// Desc: Constructor
//-----------------------------------------------------------------------------
CNetLogEvent::CNetLogEvent(
LogLevel level,
const CStr& message,
const CStr& loggerName )
{
m_Level = level;
m_Message = message;
m_LoggerName = loggerName;
}
//-----------------------------------------------------------------------------
// Name: ~CNetLogEvent()
// Desc: Destructor
//-----------------------------------------------------------------------------
CNetLogEvent::~CNetLogEvent( void )
{
}
//-----------------------------------------------------------------------------
// Name: CNetLogSink()
// Desc: Constructor
//-----------------------------------------------------------------------------
CNetLogSink::CNetLogSink( void )
{
m_Active = false;
}
//-----------------------------------------------------------------------------
// Name: ~CNetLogSink()
// Desc: Destructor
//-----------------------------------------------------------------------------
CNetLogSink::~CNetLogSink( void )
{
}
//-----------------------------------------------------------------------------
// Name: SetName()
// Desc: Set the name for the sink
//-----------------------------------------------------------------------------
void CNetLogSink::SetName( const CStr& name )
{
m_Name = name;
}
//-----------------------------------------------------------------------------
// Name: SetLevel()
// Desc: Set the level for the sink
//-----------------------------------------------------------------------------
void CNetLogSink::SetLevel( LogLevel level )
{
m_Level = level;
}
//-----------------------------------------------------------------------------
// Name: SetHeader()
// Desc: Set new header text
//-----------------------------------------------------------------------------
void CNetLogSink::SetHeader( const CStr& header )
{
m_Header = header;
}
//-----------------------------------------------------------------------------
// Name: SetFooter()
// Desc: Set new footer text
//-----------------------------------------------------------------------------
void CNetLogSink::SetFooter( const CStr& footer )
{
m_Footer = footer;
}
//-----------------------------------------------------------------------------
// Name: Activate()
// Desc: Activates the sink
//-----------------------------------------------------------------------------
void CNetLogSink::Activate( void )
{
CScopeLock lock( m_Mutex );
if ( !m_Active )
{
OnActivate();
m_Active = true;
}
}
//-----------------------------------------------------------------------------
// Name: Close()
// Desc: Closes the sink
//-----------------------------------------------------------------------------
void CNetLogSink::Close( void )
{
CScopeLock lock( m_Mutex );
OnClose();
}
//-----------------------------------------------------------------------------
// Name: DoSink()
// Desc: Perform event logging
//-----------------------------------------------------------------------------
void CNetLogSink::DoSink( const CNetLogEvent& event )
{
CScopeLock lock( m_Mutex );
// Not activated? Nothing to log
if ( !m_Active ) return;
if ( TestEvent( event ) )
{
Sink( event );
}
}
//-----------------------------------------------------------------------------
// Name: DoBulkSink()
// Desc: Perform logging for a list of events
//-----------------------------------------------------------------------------
void CNetLogSink::DoBulkSink( const CNetLogEvent* pEvents, size_t eventCount )
{
unsigned* pIndices = NULL;
size_t indexCount = 0;
size_t i;
CScopeLock lock( m_Mutex );
// Validate parameters
if ( !pEvents ) return;
// Not activated? Nothing to log
if ( m_Closed ) return;
// Allocate new array which will store the events that will be logged
pIndices = new unsigned[ eventCount ];
if ( !pIndices )
{
throw std::bad_alloc();
return;
}
// Filter each event and store the index for
// those passing the filter test
for ( i = 0; i < eventCount; i++ )
{
if ( TestEvent( pEvents[ i ] ) )
{
pIndices[ indexCount++ ] = i;
}
}
// Log each event
for ( i = 0; i < indexCount; i++ )
{
Sink( pEvents[ pIndices[ i ] ] );
}
delete [] pIndices;
}
//-----------------------------------------------------------------------------
// Name: CNetLogSink()
// Desc: Test if the event can be logged
//-----------------------------------------------------------------------------
bool CNetLogSink::TestEvent( const CNetLogEvent& event )
{
return ( event.GetLevel() >= m_Level );
}
//-----------------------------------------------------------------------------
// Name: WriteHeader()
// Desc: Writes a header
//-----------------------------------------------------------------------------
void CNetLogSink::WriteHeader( void )
{
if ( !m_Header.empty() )
{
Write( m_Header );
}
}
//-----------------------------------------------------------------------------
// Name: WriteFooter()
// Desc: Writes a footer
//-----------------------------------------------------------------------------
void CNetLogSink::WriteFooter( void )
{
if ( !m_Footer.empty() )
{
Write( m_Footer );
}
}
//-----------------------------------------------------------------------------
// Name: OnActivate()
// Desc: Called on activation
//-----------------------------------------------------------------------------
void CNetLogSink::OnActivate( void )
{
// Does nothing by default
}
//-----------------------------------------------------------------------------
// Name: OnClose()
// Desc: Called on sink closure
//-----------------------------------------------------------------------------
void CNetLogSink::OnClose( void )
{
// Does nothing by default
}
//-----------------------------------------------------------------------------
// Name: CNetLogFileSink()
// Desc: Constructor
//-----------------------------------------------------------------------------
CNetLogFileSink::CNetLogFileSink( void )
{
// Get string time
CStr time;
CNetLogger::GetStringTime( time );
// Make relative path
Path path("../logs/net_log");
path /= time+".txt";
m_FileName = path.external_file_string();
m_Append = true;
}
//-----------------------------------------------------------------------------
// Name: CNetLogFileSink()
// Desc: Constructor
//-----------------------------------------------------------------------------
CNetLogFileSink::CNetLogFileSink( const CStr& filename )
{
m_FileName = filename;
m_Append = true;
}
//-----------------------------------------------------------------------------
// Name: CNetLogFileSink()
// Desc: Constructor
//-----------------------------------------------------------------------------
CNetLogFileSink::CNetLogFileSink( const CStr& filename, bool append )
{
m_FileName = filename;
m_Append = append;
}
//-----------------------------------------------------------------------------
// Name: ~CNetLogFileSink()
// Desc: Destructor
//-----------------------------------------------------------------------------
CNetLogFileSink::~CNetLogFileSink( void )
{
}
//-----------------------------------------------------------------------------
// Name: Activate()
// Desc: Open the file which will be used for logging
//-----------------------------------------------------------------------------
void CNetLogFileSink::OnActivate( void )
{
OpenFile( m_FileName, m_Append );
WriteHeader();
}
//-----------------------------------------------------------------------------
// Name: OnClose()
// Desc: Closes the file used for logging
//-----------------------------------------------------------------------------
void CNetLogFileSink::OnClose( void )
{
WriteFooter();
CloseFile();
}
//-----------------------------------------------------------------------------
// Name: Sink()
// Desc: Log the event to file
//-----------------------------------------------------------------------------
void CNetLogFileSink::Sink( const CNetLogEvent& event )
{
Write( event.GetMessage() );
}
//-----------------------------------------------------------------------------
// Name: Write()
// Desc: Writes a message to log file
//-----------------------------------------------------------------------------
void CNetLogFileSink::Write( const CStr& message )
{
// File not opened?
if ( !m_File.is_open() )
{
OpenFile( m_FileName, m_Append );
// If still not opened, ignore message
if ( !m_File.is_open() ) return;
}
// Write message
if ( !message.empty() )
{
m_File << message;
}
}
//-----------------------------------------------------------------------------
// Name: Write()
// Desc: Writes a character to the file
//-----------------------------------------------------------------------------
void CNetLogFileSink::Write( char c )
{
// File not opened?
if ( !m_File.is_open() )
{
OpenFile( m_FileName, m_Append );
// If still not opened, ignore character
if ( !m_File.is_open() ) return;
}
// Write character
m_File << c;
}
//-----------------------------------------------------------------------------
// Name: OpenFile()
// Desc: Open the file where the logging will output
//-----------------------------------------------------------------------------
void CNetLogFileSink::OpenFile( const CStr& fileName, bool append )
{
// Close any open file
if ( m_File.is_open() ) m_File.close();
// Open the file and log start
m_File.open( fileName.c_str(), append ? std::ios::app : std::ios::out );
if ( !m_File.is_open() )
{
// throw std::ios_base::failure
return;
}
m_FileName = fileName;
m_Append = append;
}
//-----------------------------------------------------------------------------
// Name: CloseFile()
// Desc: Closes the opened file
//-----------------------------------------------------------------------------
void CNetLogFileSink::CloseFile( void )
{
if ( m_File.is_open() )
{
m_File.flush();
m_File.close();
}
}
//-----------------------------------------------------------------------------
// Name: CNetLogConsoleSink()
// Desc: Constructor
//-----------------------------------------------------------------------------
CNetLogConsoleSink::CNetLogConsoleSink( void )
{
}
//-----------------------------------------------------------------------------
// Name: ~CNetLogConsoleSink()
// Desc: Destructor
//-----------------------------------------------------------------------------
CNetLogConsoleSink::~CNetLogConsoleSink( void )
{
}
//-----------------------------------------------------------------------------
// Name: Activate()
// Desc: Activates the game console
//-----------------------------------------------------------------------------
void CNetLogConsoleSink::OnActivate( void )
{
WriteHeader();
}
//-----------------------------------------------------------------------------
// Name: OnClose()
// Desc: Toggles off game console
//-----------------------------------------------------------------------------
void CNetLogConsoleSink::OnClose( void )
{
WriteFooter();
}
//-----------------------------------------------------------------------------
// Name: Sink()
// Desc: Log the event to file
//-----------------------------------------------------------------------------
void CNetLogConsoleSink::Sink( const CNetLogEvent& event )
{
Write( event.GetMessage() );
}
//-----------------------------------------------------------------------------
// Name: Write()
// Desc: Writes a message to game console
//-----------------------------------------------------------------------------
void CNetLogConsoleSink::Write( const CStr& message )
{
// Do we have a valid console?
if ( !g_Console ) return;
// Write message
if ( !message.empty() )
{
g_Console->InsertMessage( message.FromUTF8().c_str() );
}
}
//-----------------------------------------------------------------------------
// Name: Write()
// Desc: Writes a character to the file
//-----------------------------------------------------------------------------
void CNetLogConsoleSink::Write( char c )
{
// Do we have a valid console?
if ( !g_Console ) return;
// Write character
Write( CStr( c ) );
}
//-----------------------------------------------------------------------------
// Name: CNetLogger()
// Desc: Constructor
//-----------------------------------------------------------------------------
CNetLogger::CNetLogger( const CStr& name )
{
m_Name = name;
m_Level = LOG_LEVEL_ALL;
}
//-----------------------------------------------------------------------------
// Name: ~CNetLogger()
// Desc: Destructor
//-----------------------------------------------------------------------------
CNetLogger::~CNetLogger( void )
{
}
//-----------------------------------------------------------------------------
// Name: SetLevel()
// Desc: Set logger level
//-----------------------------------------------------------------------------
void CNetLogger::SetLevel( LogLevel level )
{
m_Level = level;
}
//-----------------------------------------------------------------------------
// Name: IsDebugEnabled()
// Desc: Check if enabled for DEBUG level
//-----------------------------------------------------------------------------
bool CNetLogger::IsDebugEnabled( void ) const
{
return ( LOG_LEVEL_DEBUG >= m_Level );
}
//-----------------------------------------------------------------------------
// Name: IsErrorEnabled()
// Desc: Check if enabled for ERROR level
//-----------------------------------------------------------------------------
bool CNetLogger::IsErrorEnabled( void ) const
{
return ( LOG_LEVEL_ERROR >= m_Level );
}
//-----------------------------------------------------------------------------
// Name: IsFatalEnabled()
// Desc: Check if enabled for FATAL level
//-----------------------------------------------------------------------------
bool CNetLogger::IsFatalEnabled( void ) const
{
return ( LOG_LEVEL_FATAL >= m_Level );
}
//-----------------------------------------------------------------------------
// Name: IsInfoEnabled()
// Desc: Check if enabled for INFO level
//-----------------------------------------------------------------------------
bool CNetLogger::IsInfoEnabled( void ) const
{
return ( LOG_LEVEL_INFO >= m_Level );
}
//-----------------------------------------------------------------------------
// Name: IsWarnEnabled()
// Desc: Check if enabled for WARN level
//-----------------------------------------------------------------------------
bool CNetLogger::IsWarnEnabled( void ) const
{
return ( LOG_LEVEL_WARN >= m_Level );
}
//-----------------------------------------------------------------------------
// Name: Debug()
// Desc: Log a message with DEBUG level
//-----------------------------------------------------------------------------
void CNetLogger::Debug( const CStr& message )
{
if ( IsDebugEnabled() )
{
// Get timestamp as a string
CStr timer;
GetStringTimeStamp( timer );
CStr eventMessage = "DEBUG";
eventMessage += " - ";
eventMessage += timer;
eventMessage += " ";
eventMessage += message;
eventMessage += "\n";
CNetLogEvent newEvent( LOG_LEVEL_DEBUG, eventMessage, m_Name );
CallSinks( newEvent );
}
}
//-----------------------------------------------------------------------------
// Name: Debug()
// Desc: Log a formatted message with DEBUG level
//-----------------------------------------------------------------------------
void CNetLogger::DebugFormat( const char* pFormat, ... )
{
if ( IsDebugEnabled() )
{
char buffer[ 512 ] = { 0 };
CStr timer;
va_list args;
// Get timestamp as a string
GetStringTimeStamp( timer );
// Get arguments as a string
va_start ( args, pFormat );
vsnprintf ( buffer, 512, pFormat, args );
va_end ( args );
// Format message (e.g. ERROR - Hello World)
CStr eventMessage = "DEBUG";
eventMessage += " - ";
eventMessage += timer;
eventMessage += " ";
eventMessage += buffer;
eventMessage += "\n";
CNetLogEvent newEvent( LOG_LEVEL_DEBUG, eventMessage, m_Name );
CallSinks( newEvent );
}
}
//-----------------------------------------------------------------------------
// Name: Error()
// Desc: Log a message with ERROR level
//-----------------------------------------------------------------------------
void CNetLogger::Error( const CStr& message )
{
if ( IsErrorEnabled() )
{
// Get timestamp as a string
CStr timer;
GetStringTimeStamp( timer );
CStr eventMessage = "ERROR";
eventMessage += " - ";
eventMessage += timer;
eventMessage += " ";
eventMessage += message;
eventMessage += "\n";
CNetLogEvent newEvent( LOG_LEVEL_ERROR, eventMessage, m_Name );
CallSinks( newEvent );
}
}
//-----------------------------------------------------------------------------
// Name: Error()
// Desc: Log a formatted message with ERROR level
//-----------------------------------------------------------------------------
void CNetLogger::ErrorFormat( const char* pFormat, ... )
{
if ( IsErrorEnabled() )
{
char buffer[ 512 ] = { 0 };
CStr timer;
va_list args;
// Get timestamp as a string
GetStringTimeStamp( timer );
// Get arguments as a string
va_start ( args, pFormat );
vsnprintf ( buffer, 512, pFormat, args );
va_end ( args );
// Format message (e.g. ERROR - Hello World)
CStr eventMessage = "ERROR";
eventMessage += " - ";
eventMessage += timer;
eventMessage += " ";
eventMessage += buffer;
eventMessage += "\n";
CNetLogEvent newEvent( LOG_LEVEL_ERROR, eventMessage, m_Name );
CallSinks( newEvent );
}
}
//-----------------------------------------------------------------------------
// Name: Fatal()
// Desc: Log a message with FATAL level
//-----------------------------------------------------------------------------
void CNetLogger::Fatal( const CStr& message )
{
if ( IsFatalEnabled() )
{
// Get timestamp as a string
CStr timer;
GetStringTimeStamp( timer );
CStr eventMessage = "FATAL";
eventMessage += " - ";
eventMessage += timer;
eventMessage += " ";
eventMessage += message;
eventMessage += "\n";
CNetLogEvent newEvent( LOG_LEVEL_FATAL, eventMessage, m_Name );
CallSinks( newEvent );
}
}
//-----------------------------------------------------------------------------
// Name: Fatal()
// Desc: Log a formatted message with FATAL error
//-----------------------------------------------------------------------------
void CNetLogger::FatalFormat( const char* pFormat, ... )
{
if ( IsFatalEnabled() )
{
char buffer[ 512 ] = { 0 };
CStr timer;
va_list args;
// Get timestamp as a string
GetStringTimeStamp( timer );
// Get arguments as a string
va_start ( args, pFormat );
vsnprintf ( buffer, 512, pFormat, args );
va_end ( args );
// Format message (e.g. ERROR - Hello World)
CStr eventMessage = "FATAL";
eventMessage += " - ";
eventMessage += timer;
eventMessage += " ";
eventMessage += buffer;
eventMessage += "\n";
CNetLogEvent newEvent( LOG_LEVEL_FATAL, eventMessage, m_Name );
CallSinks( newEvent );
}
}
//-----------------------------------------------------------------------------
// Name: Info()
// Desc: Log a message with INFO level
//-----------------------------------------------------------------------------
void CNetLogger::Info( const CStr& message )
{
if ( IsInfoEnabled() )
{
// Get timestamp as a string
CStr timer;
GetStringTimeStamp( timer );
CStr eventMessage = "INFO";
eventMessage += " - ";
eventMessage += timer;
eventMessage += " ";
eventMessage += message;
eventMessage += "\n";
CNetLogEvent newEvent( LOG_LEVEL_INFO, eventMessage, m_Name );
CallSinks( newEvent );
}
}
//-----------------------------------------------------------------------------
// Name: Info()
// Desc: Log a formatted message with INFO level
//-----------------------------------------------------------------------------
void CNetLogger::InfoFormat( const char* pFormat, ... )
{
if ( IsInfoEnabled() )
{
char buffer[ 512 ] = { 0 };
CStr timer;
va_list args;
// Get timestamp as a string
GetStringTimeStamp( timer );
// Get arguments as a string
va_start ( args, pFormat );
vsnprintf ( buffer, 512, pFormat, args );
va_end ( args );
// Format message (e.g. ERROR - Hello World)
CStr eventMessage = "INFO";
eventMessage += " - ";
eventMessage += timer;
eventMessage += " ";
eventMessage += buffer;
eventMessage += "\n";
CNetLogEvent newEvent( LOG_LEVEL_INFO, eventMessage, m_Name );
CallSinks( newEvent );
}
}
//-----------------------------------------------------------------------------
// Name: Warn()
// Desc: Log a message with WARN level
//-----------------------------------------------------------------------------
void CNetLogger::Warn( const CStr& message )
{
if ( IsWarnEnabled() )
{
// Get timestamp as a string
CStr timer;
GetStringTimeStamp( timer );
CStr eventMessage = "WARN";
eventMessage += " - ";
eventMessage += timer;
eventMessage += " ";
eventMessage += message;
eventMessage += "\n";
CNetLogEvent newEvent( LOG_LEVEL_WARN, eventMessage, m_Name );
CallSinks( newEvent );
}
}
//-----------------------------------------------------------------------------
// Name: Warn()
// Desc: Log a formatted message with WARN level
//-----------------------------------------------------------------------------
void CNetLogger::WarnFormat( const char* pFormat, ... )
{
if ( IsWarnEnabled() )
{
char buffer[ 512 ] = { 0 };
CStr timer;
va_list args;
// Get timestamp as a string
GetStringTimeStamp( timer );
// Get arguments as a string
va_start ( args, pFormat );
vsnprintf ( buffer, 512, pFormat, args );
va_end ( args );
// Format message (e.g. ERROR - Hello World)
CStr eventMessage = "WARN";
eventMessage += " - ";
eventMessage += timer;
eventMessage += " ";
eventMessage += buffer;
eventMessage += "\n";
CNetLogEvent newEvent( LOG_LEVEL_WARN, eventMessage, m_Name );
CallSinks( newEvent );
}
}
//-----------------------------------------------------------------------------
// Name: AddSink()
// Desc: Attaches a new sink
//-----------------------------------------------------------------------------
void CNetLogger::AddSink( CNetLogSink* pSink )
{
size_t i;
CScopeLock lock( m_Mutex );
assert( pSink );
// Validate parameter
if ( !pSink ) return;
// Check if already exists
for ( i = 0; i < GetSinkCount(); i++ )
{
CNetLogSink* pCurrSink = GetSink( i );
if ( pCurrSink == pSink ) break;
}
// Already exists?
if ( i >= GetSinkCount() )
{
// Activate new sink
pSink->Activate();
// Add new sink to list
m_Sinks.push_back( pSink );
}
}
//-----------------------------------------------------------------------------
// Name: RemoveSink()
// Desc: Removes the sink from the list of attached sinks
//-----------------------------------------------------------------------------
CNetLogSink* CNetLogger::RemoveSink( CNetLogSink* pSink )
{
CScopeLock lock( m_Mutex );
// Validate parameter
if ( !pSink ) return NULL;
// Lookup the sink object
SinkList::iterator it = m_Sinks.begin();
for ( ; it != m_Sinks.end(); it++ )
{
CNetLogSink* pCurrSink = *it;
if ( pCurrSink == pSink )
{
m_Sinks.erase( it );
return pCurrSink;
}
}
return NULL;
}
//-----------------------------------------------------------------------------
// Name: RemoveSink()
// Desc: Removes the named sink
//-----------------------------------------------------------------------------
CNetLogSink* CNetLogger::RemoveSink( const CStr& name )
{
CScopeLock lock( m_Mutex );
// Lookup sink by name
SinkList::iterator it = m_Sinks.begin();
for ( ; it != m_Sinks.end(); it++ )
{
CNetLogSink* pCurrSink = *it;
if ( !pCurrSink ) continue;
if ( pCurrSink->GetName() == name )
{
m_Sinks.erase( it );
return pCurrSink;
}
}
// Sink not found
return NULL;
}
//-----------------------------------------------------------------------------
// Name: RemoveAllSinks()
// Desc: Remove all attached sinks
//-----------------------------------------------------------------------------
void CNetLogger::RemoveAllSinks( void )
{
CScopeLock lock( m_Mutex );
m_Sinks.clear();
}
//-----------------------------------------------------------------------------
// Name: GetSinkCount()
// Desc: Retrive the number of attached sinks
//-----------------------------------------------------------------------------
size_t CNetLogger::GetSinkCount( void )
{
return m_Sinks.size();
}
//-----------------------------------------------------------------------------
// Name: GetSink()
// Desc: Retrieves the sink by index
//-----------------------------------------------------------------------------
CNetLogSink* CNetLogger::GetSink( size_t index )
{
// Validate parameter
if ( index > m_Sinks.size() ) return NULL;
return m_Sinks[ index ];
}
//-----------------------------------------------------------------------------
// Name: GetSink()
// Desc: Retrieve the sink by name
//-----------------------------------------------------------------------------
CNetLogSink* CNetLogger::GetSink( const CStr& name )
{
for ( size_t i = 0; i < GetSinkCount(); i++ )
{
CNetLogSink* pCurrSink = GetSink( i );
if ( !pCurrSink ) continue;
if ( pCurrSink->GetName() == name )
return pCurrSink;
}
// Sink not found
return NULL;
}
//-----------------------------------------------------------------------------
// Name: CallSinks()
// Desc:
//-----------------------------------------------------------------------------
void CNetLogger::CallSinks( const CNetLogEvent& event )
{
for ( size_t i = 0; i < GetSinkCount(); i++ )
{
CNetLogSink* pCurrSink = GetSink( i );
if ( !pCurrSink ) continue;
pCurrSink->DoSink( event );
}
}
//-----------------------------------------------------------------------------
// Name: GetStringLocalTime()
// Desc: Returns the local date time into the passed in string
//-----------------------------------------------------------------------------
void CNetLogger::GetStringDateTime( CStr &str )
{
char buffer[ 128 ] = { 0 };
time_t tm;
struct tm *now;
#if OS_WIN
// Set timezone
_tzset();
// Get time and convert to tm structure
time( &tm );
struct tm nowBuf;
localtime_s( &nowBuf, &tm );
now = &nowBuf;
#else
time ( &tm );
now = localtime( &tm );
#endif
// Build custom time string
strftime( buffer, 128, "%Y-%m-%d %H:%M:%S", now );
str = buffer;
}
//-----------------------------------------------------------------------------
// Name: GetStringTime()
// Desc: Returns the local time into the passed string
//-----------------------------------------------------------------------------
void CNetLogger::GetStringTime( CStr& str )
{
char buffer[ 128 ] = { 0 };
time_t tm;
struct tm *now;
#if OS_WIN
// Set timezone
_tzset();
// Get time and convert to tm structure
time( &tm );
struct tm nowBuf;
localtime_s( &nowBuf, &tm );
now = &nowBuf;
#else
time ( &tm );
now = localtime( &tm );
#endif
// Build custom time string
strftime( buffer, 128, "%H%M%S", now );
str = buffer;
}
//-----------------------------------------------------------------------------
// Name: GetStringTimeStamp()
// Desc: Returns the formatted current time into the passed string
//-----------------------------------------------------------------------------
void CNetLogger::GetStringTimeStamp( CStr& str )
{
char buffer[ 128 ] = { 0 };
double timestamp = timer_Time();
sprintf( buffer, "[%3u.%03u]", ( unsigned )timestamp, ( ( unsigned )( timestamp * 1000 ) % 1000 ) );
str = buffer;
}
// List of loggers under log manager
LoggerList CNetLogManager::m_Loggers;
//-----------------------------------------------------------------------------
// Name: Shutdown()
// Desc: Shuts down the log manager
//-----------------------------------------------------------------------------
void CNetLogManager::Shutdown( void )
{
// Remove all loggers
LoggerList::iterator it = m_Loggers.begin();
for ( ; it != m_Loggers.end(); it++ )
{
CNetLogger *pCurrLogger = *it;
if ( !pCurrLogger ) continue;
pCurrLogger->RemoveAllSinks();
delete pCurrLogger;
}
m_Loggers.clear();
}
//-----------------------------------------------------------------------------
// Name: GetLogger()
// Desc: Retrieve or create a named logger
//-----------------------------------------------------------------------------
CNetLogger* CNetLogManager::GetLogger( const CStr& name )
{
LoggerList::const_iterator it = m_Loggers.begin();
for ( ; it != m_Loggers.end(); it++ )
{
CNetLogger* pCurrLogger = *it;
if ( !pCurrLogger ) continue;
if ( pCurrLogger->GetName() == name )
return pCurrLogger;
}
// Logger not found, create it
CNetLogger* pNewLogger = new CNetLogger( name );
if ( !pNewLogger ) return NULL;
// Add new logger to list
m_Loggers.push_back( pNewLogger );
return pNewLogger;
}
//-----------------------------------------------------------------------------
// Name: GetAllLoggers()
// Desc: Return the list of loggers
//-----------------------------------------------------------------------------
const LoggerList& CNetLogManager::GetAllLoggers( void )
{
return m_Loggers;
}