VALog.h 5.28 KB
Newer Older
1 2 3 4 5 6
/*
 *  --------------------------------------------------------------------------------------------
 *
 *    VVV        VVV A           Virtual Acoustics (VA) | http://www.virtualacoustics.org
 *     VVV      VVV AAA          Licensed under the Apache License, Version 2.0
 *      VVV    VVV   AAA
7
 *       VVV  VVV     AAA        Copyright 2015-2018
8 9 10 11 12 13 14 15
 *        VVVVVV       AAA       Institute of Technical Acoustics (ITA)
 *         VVVV         AAA      RWTH Aachen University
 *
 *  --------------------------------------------------------------------------------------------
 */

#ifndef IW_VACORE_LOG
#define IW_VACORE_LOG
Jonas Stienen's avatar
Jonas Stienen committed
16 17 18

#include <VACoreDefinitions.h>

19
#include <VA.h>
Jonas Stienen's avatar
Jonas Stienen committed
20 21 22 23 24 25 26 27 28 29 30

#include <ITAClock.h>
#include <ITAAtomicPrimitives.h>

#include <tbb/concurrent_queue.h>

#include <VistaInterProcComm/Concurrency/VistaMutex.h>
#include <VistaInterProcComm/Concurrency/VistaThreadEvent.h>
#include <VistaInterProcComm/Concurrency/VistaThreadLoop.h>

#include <iostream>
31
#include <iomanip>
Jonas Stienen's avatar
Jonas Stienen committed
32 33
#include <list>
#include <stdarg.h>
34
#include <stdio.h>
Jonas Stienen's avatar
Jonas Stienen committed
35 36 37 38

extern VACORE_API std::ostream* VA_STDOUT;
extern VACORE_API std::ostream* VA_STDERR;

Jonas Stienen's avatar
Jonas Stienen committed
39 40
void VACORE_API VALog_setOutputStream( std::ostream* os );
void VACORE_API VALog_setErrorStream( std::ostream* os );
Jonas Stienen's avatar
Jonas Stienen committed
41 42 43 44 45
int VACORE_API VALog_GetLogLevel();
void VACORE_API VALog_SetLogLevel( int );

VistaMutex& VALog_getOutputStreamMutex();

46 47 48 49 50 51
#define VA_PRINT( expr )			{ if (VA_STDOUT && (VALog_GetLogLevel() >= IVAInterface::VA_LOG_LEVEL_QUIET ) )		{ VistaMutexLock oLock(VALog_getOutputStreamMutex() ); (*VA_STDOUT) << "[ VAPrint   ] " << expr << std::endl; } }
#define VA_ERROR( module, expr )	{ if (VA_STDOUT && (VALog_GetLogLevel() >= IVAInterface::VA_LOG_LEVEL_QUIET ) )		{ VistaMutexLock oLock(VALog_getOutputStreamMutex() ); (*VA_STDERR) << "[ VAError   ][ " << std::right << std::setw( 20 ) << module << " ] " << expr << std::endl; } }
#define VA_WARN( module, expr )		{ if (VA_STDOUT && (VALog_GetLogLevel() >= IVAInterface::VA_LOG_LEVEL_ERROR ) )		{ VistaMutexLock oLock(VALog_getOutputStreamMutex() ); (*VA_STDOUT) << "[ VAWarning ][ " << std::right << std::setw( 20 ) << module << " ] " << expr << std::endl; } }
#define VA_INFO( module, expr )		{ if (VA_STDOUT && (VALog_GetLogLevel() >= IVAInterface::VA_LOG_LEVEL_INFO ) )		{ VistaMutexLock oLock(VALog_getOutputStreamMutex() ); (*VA_STDOUT) << "[ VAInfo    ][ " << std::right << std::setw( 20 ) << module << " ] " << expr << std::endl; } }
#define VA_VERBOSE( module,expr )	{ if (VA_STDOUT && (VALog_GetLogLevel() >= IVAInterface::VA_LOG_LEVEL_VERBOSE ) )	{ VistaMutexLock oLock(VALog_getOutputStreamMutex() ); (*VA_STDOUT) << "[ VAVerbose ][ " << std::right << std::setw( 20 ) << module << " ] " << expr << std::endl; } }
#define VA_TRACE( module, expr )	{ if (VA_STDOUT && (VALog_GetLogLevel() >= IVAInterface::VA_LOG_LEVEL_TRACE ) )		{ VistaMutexLock oLock(VALog_getOutputStreamMutex() ); (*VA_STDOUT) << "[ VATrace   ][ " << std::right << std::setw( 20 ) << module << " ] " << expr << std::endl; } }
Jonas Stienen's avatar
Jonas Stienen committed
52 53 54 55 56 57 58 59

class CVALogItem
{
public:
	double dTimestamp;
	std::string sLogger;
	std::string sMsg;

Jonas Stienen's avatar
Jonas Stienen committed
60 61 62 63 64 65 66 67 68 69 70
	inline CVALogItem()
		: dTimestamp( 0 )
	{
	};

	inline CVALogItem( double dTheTimestamp, const std::string sTheLogger, const std::string sTheMsg )
		: dTimestamp( dTheTimestamp )
		, sLogger( sTheLogger )
		, sMsg( sTheMsg )
	{
	};
Jonas Stienen's avatar
Jonas Stienen committed
71 72

	//! Grer-Operator zur Verwendung der sort() Funktion
Jonas Stienen's avatar
Jonas Stienen committed
73
	bool operator> ( CVALogItem const& rhs );
Jonas Stienen's avatar
Jonas Stienen committed
74 75

	//! Kleiner-Operation
Jonas Stienen's avatar
Jonas Stienen committed
76
	bool operator< ( CVALogItem const& rhs );
Jonas Stienen's avatar
Jonas Stienen committed
77 78 79 80 81 82

};

class CVARealtimeLogStream;

//! Realtime Logger entkoppelt die Ausgabe von Logger-Streams auf einem niederpriorisierten Thread
Jonas Stienen's avatar
Jonas Stienen committed
83 84
class CVARealtimeLogger : public VistaThreadLoop
{
Jonas Stienen's avatar
Jonas Stienen committed
85 86 87 88 89 90 91
public:
	CVARealtimeLogger();
	~CVARealtimeLogger();

	static CVARealtimeLogger* GetInstance();

	//! Streams registrieren
Jonas Stienen's avatar
Jonas Stienen committed
92
	void Register( CVARealtimeLogStream* pStream );
Jonas Stienen's avatar
Jonas Stienen committed
93 94

	//! Streams deregistrieren
Jonas Stienen's avatar
Jonas Stienen committed
95
	void Unregister( CVARealtimeLogStream* pStream );
Jonas Stienen's avatar
Jonas Stienen committed
96 97 98 99 100 101 102

	//! Thread anschubsen (nach Aktion)
	void Trigger();

	//! Ausgabe
	bool LoopBody();

103 104
	inline void PreLoop() {};
	inline void PostLoop() {};
Jonas Stienen's avatar
Jonas Stienen committed
105 106 107 108 109

private:
	VistaThreadEvent m_evTrigger;
	ITAAtomicInt m_iTriggerCnt;
	ITAAtomicBool m_bStop;
110
	std::list< CVARealtimeLogStream* > m_lpStreams;
Jonas Stienen's avatar
Jonas Stienen committed
111 112 113 114 115 116 117 118 119
	VistaMutex m_mxRegistration;
};

//! Implementierung des Echtzeit-Logger-Streams
/**
  * Nutzt den RealtimeLogger, um Stream-Informationen mittels
  * niederpriorisiertem Thread auf die Konsole oder Visual Studio Ausgabe
  * auszugeben.
  */
120 121
class CVARealtimeLogStream
{
Jonas Stienen's avatar
Jonas Stienen committed
122
public:
123 124 125
	inline CVARealtimeLogStream( ITAClock* pClock = ITAClock::getDefaultClock() )
		: m_pClock( pClock )
	{
Jonas Stienen's avatar
Jonas Stienen committed
126
		// Bei Ausgabe-Thread registrieren (Singleton)
Jonas Stienen's avatar
Jonas Stienen committed
127
		CVARealtimeLogger::GetInstance()->Register( this );
Jonas Stienen's avatar
Jonas Stienen committed
128 129
	}

130 131
	virtual ~CVARealtimeLogStream()
	{
Jonas Stienen's avatar
Jonas Stienen committed
132
		// Bei Thread deregistieren
Jonas Stienen's avatar
Jonas Stienen committed
133
		CVARealtimeLogger::GetInstance()->Unregister( this );
Jonas Stienen's avatar
Jonas Stienen committed
134 135
	}

136 137
	std::string GetName() const
	{
Jonas Stienen's avatar
Jonas Stienen committed
138 139 140
		return m_sName;
	}

141 142
	void SetName( const std::string& sName )
	{
Jonas Stienen's avatar
Jonas Stienen committed
143 144 145 146
		m_sName = sName;
	}

	// Ausgabe
147 148
	void Printf( const char * format, ... )
	{
Jonas Stienen's avatar
Jonas Stienen committed
149
		char buf[ 16384 ];
Jonas Stienen's avatar
Jonas Stienen committed
150
		va_list args;
Jonas Stienen's avatar
Jonas Stienen committed
151
		va_start( args, format );
152
		vsprintf( buf, format, args );
Jonas Stienen's avatar
Jonas Stienen committed
153
		va_end( args );
Jonas Stienen's avatar
Jonas Stienen committed
154

Jonas Stienen's avatar
Jonas Stienen committed
155
		m_qLog.push( CVALogItem( m_pClock->getTime(), m_sName, buf ) );
Jonas Stienen's avatar
Jonas Stienen committed
156 157 158 159 160 161 162 163 164 165
		// TODO: Thread zur Ausgabe anwerfen ggf.
	}

private:
	ITAClock* m_pClock;
	std::string m_sName;
	tbb::strict_ppl::concurrent_queue<CVALogItem> m_qLog;

	friend class CVARealtimeLogger;
};
166
#endif // IW_VACORE_LOG