Aufgrund einer Wartung wird GitLab am 26.10. zwischen 8:00 und 9:00 Uhr kurzzeitig nicht zur Verfügung stehen. / Due to maintenance, GitLab will be temporarily unavailable on 26.10. between 8:00 and 9:00 am.

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