| 
									
										
										
										
											2009-07-28 21:32:10 +00:00
										 |  |  | // Copyright (C) 2003 Dolphin Project.
 | 
					
						
							| 
									
										
										
										
											2009-03-28 08:57:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | // This program is free software: you can redistribute it and/or modify
 | 
					
						
							|  |  |  | // it under the terms of the GNU General Public License as published by
 | 
					
						
							|  |  |  | // the Free Software Foundation, version 2.0.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // This program is distributed in the hope that it will be useful,
 | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					
						
							|  |  |  | // GNU General Public License 2.0 for more details.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // A copy of the GPL 2.0 should have been included with the program.
 | 
					
						
							|  |  |  | // If not, see http://www.gnu.org/licenses/
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Official SVN repository and contact information can be found at
 | 
					
						
							|  |  |  | // http://code.google.com/p/dolphin-emu/
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-28 23:14:16 +00:00
										 |  |  | #include <algorithm>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-18 17:17:58 +00:00
										 |  |  | #include "LogManager.h"
 | 
					
						
							| 
									
										
										
										
											2010-01-19 19:28:27 +00:00
										 |  |  | #include "ConsoleListener.h"
 | 
					
						
							| 
									
										
										
										
											2009-03-18 17:17:58 +00:00
										 |  |  | #include "Timer.h"
 | 
					
						
							| 
									
										
										
										
											2010-01-19 19:28:27 +00:00
										 |  |  | #include "Thread.h"
 | 
					
						
							| 
									
										
										
										
											2010-02-02 21:56:29 +00:00
										 |  |  | #include "FileUtil.h"
 | 
					
						
							| 
									
										
										
										
											2010-01-19 19:28:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-14 17:52:01 +00:00
										 |  |  | void GenericLog(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type,  | 
					
						
							| 
									
										
										
										
											2010-07-16 19:08:26 +00:00
										 |  |  | 		const char *file, int line, const char* fmt, ...) | 
					
						
							| 
									
										
										
										
											2009-07-12 21:58:32 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	va_list args; | 
					
						
							|  |  |  | 	va_start(args, fmt); | 
					
						
							| 
									
										
										
										
											2010-02-16 04:34:41 +00:00
										 |  |  | 	if (LogManager::GetInstance()) | 
					
						
							| 
									
										
										
										
											2010-07-16 19:08:26 +00:00
										 |  |  | 		LogManager::GetInstance()->Log(level, type, | 
					
						
							|  |  |  | 			file, line, fmt, args); | 
					
						
							| 
									
										
										
										
											2009-07-12 21:58:32 +00:00
										 |  |  | 	va_end(args); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-18 17:17:58 +00:00
										 |  |  | LogManager *LogManager::m_logManager = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-19 19:28:27 +00:00
										 |  |  | LogManager::LogManager() { | 
					
						
							|  |  |  | 	logMutex = new Common::CriticalSection(1); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-18 17:17:58 +00:00
										 |  |  | 	// create log files
 | 
					
						
							| 
									
										
										
										
											2010-12-14 17:52:01 +00:00
										 |  |  | 	m_Log[LogTypes::MASTER_LOG]			= new LogContainer("*",				"Master Log"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::BOOT]				= new LogContainer("BOOT",			"Boot"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::COMMON]				= new LogContainer("COMMON",		"Common"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::DISCIO]				= new LogContainer("DIO",	    	"Disc IO"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::FILEMON]			= new LogContainer("FileMon",		"File Monitor"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::PAD]		        = new LogContainer("PAD",			"Pad"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::PIXELENGINE]		= new LogContainer("PE",			"PixelEngine"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::COMMANDPROCESSOR]	= new LogContainer("CP",			"CommandProc"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::VIDEOINTERFACE]		= new LogContainer("VI",			"VideoInt"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::SERIALINTERFACE]	= new LogContainer("SI",			"SerialInt"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::PROCESSORINTERFACE]	= new LogContainer("PI",			"ProcessorInt"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::MEMMAP]				= new LogContainer("MI",			"MI & memmap"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::SP1]				= new LogContainer("SP1",			"Serial Port 1"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::STREAMINGINTERFACE] = new LogContainer("Stream",		"StreamingInt"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::DSPINTERFACE]		= new LogContainer("DSP",			"DSPInterface"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::DVDINTERFACE]		= new LogContainer("DVD",			"DVDInterface"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::GPFIFO]				= new LogContainer("GP",			"GPFifo"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::EXPANSIONINTERFACE]	= new LogContainer("EXI",			"ExpansionInt"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::AUDIO_INTERFACE]	= new LogContainer("AI",			"AudioInt"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::POWERPC]			= new LogContainer("PowerPC",		"IBM CPU"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::OSHLE]				= new LogContainer("HLE",			"HLE"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::DSPHLE]			    = new LogContainer("DSPHLE",		"DSP HLE"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::DSPLLE]			    = new LogContainer("DSPLLE",		"DSP LLE"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::DSP_MAIL]		    = new LogContainer("DSPMails",		"DSP Mails"); | 
					
						
							| 
									
										
										
										
											2011-02-14 02:18:03 +00:00
										 |  |  | 	m_Log[LogTypes::VIDEO]			    = new LogContainer("Video",			"Video Backend"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::AUDIO]			    = new LogContainer("Audio",			"Audio Emulator"); | 
					
						
							| 
									
										
										
										
											2010-12-14 17:52:01 +00:00
										 |  |  | 	m_Log[LogTypes::DYNA_REC]			= new LogContainer("JIT",			"Dynamic Recompiler"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::CONSOLE]			= new LogContainer("CONSOLE",		"Dolphin Console"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::OSREPORT]			= new LogContainer("OSREPORT",		"OSReport");			 | 
					
						
							| 
									
										
										
										
											2011-02-22 14:06:06 +00:00
										 |  |  | 	m_Log[LogTypes::WIIMOTE]			= new LogContainer("Wiimote",		"Wiimote");			 | 
					
						
							| 
									
										
										
										
											2010-12-14 17:52:01 +00:00
										 |  |  | 	m_Log[LogTypes::WII_IOB]			= new LogContainer("WII_IOB",		"WII IO Bridge"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::WII_IPC]			= new LogContainer("WII_IPC",		"WII IPC"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::WII_IPC_HLE]		= new LogContainer("WII_IPC_HLE",	"WII IPC HLE"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::WII_IPC_DVD]		= new LogContainer("WII_IPC_DVD",	"WII IPC DVD"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::WII_IPC_ES]			= new LogContainer("WII_IPC_ES",	"WII IPC ES"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::WII_IPC_FILEIO]		= new LogContainer("WII_IPC_FILEIO","WII IPC FILEIO"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::WII_IPC_SD]			= new LogContainer("WII_IPC_SD",	"WII IPC SD"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::WII_IPC_STM]		= new LogContainer("WII_IPC_STM",	"WII IPC STM"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::WII_IPC_NET]		= new LogContainer("WII_IPC_NET",	"WII IPC NET"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::WII_IPC_WIIMOTE]	= new LogContainer("WII_IPC_WIIMOTE","WII IPC WIIMOTE"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::ACTIONREPLAY]		= new LogContainer("ActionReplay",	"ActionReplay");	 | 
					
						
							|  |  |  | 	m_Log[LogTypes::MEMCARD_MANAGER]	= new LogContainer("MemCard Manager", "MemCard Manager"); | 
					
						
							|  |  |  | 	m_Log[LogTypes::NETPLAY]			= new LogContainer("NETPLAY",		"Netplay"); | 
					
						
							| 
									
										
										
										
											2009-03-18 17:17:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-02 21:56:29 +00:00
										 |  |  | 	m_fileLog = new FileLogListener(File::GetUserPath(F_MAINLOG_IDX)); | 
					
						
							| 
									
										
										
										
											2009-03-18 17:17:58 +00:00
										 |  |  | 	m_consoleLog = new ConsoleListener(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-14 17:52:01 +00:00
										 |  |  | 	for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i) { | 
					
						
							| 
									
										
										
										
											2009-03-18 17:17:58 +00:00
										 |  |  | 		m_Log[i]->setEnable(true); | 
					
						
							|  |  |  | 		m_Log[i]->addListener(m_fileLog); | 
					
						
							|  |  |  | 		m_Log[i]->addListener(m_consoleLog); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | LogManager::~LogManager() { | 
					
						
							| 
									
										
										
										
											2010-12-14 17:52:01 +00:00
										 |  |  | 	for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i) { | 
					
						
							|  |  |  | 		m_logManager->removeListener((LogTypes::LOG_TYPE)i, m_fileLog); | 
					
						
							|  |  |  | 		m_logManager->removeListener((LogTypes::LOG_TYPE)i, m_consoleLog); | 
					
						
							| 
									
										
										
										
											2009-03-18 17:17:58 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-02-16 04:34:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-14 17:52:01 +00:00
										 |  |  | 	for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i) | 
					
						
							| 
									
										
										
										
											2010-02-16 04:34:41 +00:00
										 |  |  | 		delete m_Log[i]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-18 17:17:58 +00:00
										 |  |  | 	delete m_fileLog; | 
					
						
							|  |  |  | 	delete m_consoleLog; | 
					
						
							| 
									
										
										
										
											2010-01-19 19:28:27 +00:00
										 |  |  | 	delete logMutex; | 
					
						
							| 
									
										
										
										
											2009-03-18 17:17:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-14 17:52:01 +00:00
										 |  |  | void LogManager::Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type,  | 
					
						
							|  |  |  | 					 const char *file, int line, const char *format,  | 
					
						
							|  |  |  | 					 va_list args) { | 
					
						
							| 
									
										
										
										
											2009-03-18 17:17:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	char temp[MAX_MSGLEN]; | 
					
						
							| 
									
										
										
										
											2010-04-10 15:41:44 +00:00
										 |  |  | 	char msg[MAX_MSGLEN * 2]; | 
					
						
							| 
									
										
										
										
											2009-03-18 17:17:58 +00:00
										 |  |  | 	LogContainer *log = m_Log[type]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-27 15:05:18 +00:00
										 |  |  | 	if (! log->isEnable() || level > log->getLevel() || ! log->hasListeners()) | 
					
						
							| 
									
										
										
										
											2009-03-18 17:17:58 +00:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2009-07-12 21:58:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-18 17:17:58 +00:00
										 |  |  | 	CharArrayFromFormatV(temp, MAX_MSGLEN, format, args); | 
					
						
							| 
									
										
										
										
											2009-03-20 21:23:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	static const char level_to_char[7] = "-NEWID"; | 
					
						
							| 
									
										
										
										
											2010-01-03 08:48:48 +00:00
										 |  |  | 	sprintf(msg, "%s %s:%u %c[%s]: %s\n", | 
					
						
							| 
									
										
										
										
											2009-03-18 17:17:58 +00:00
										 |  |  | 			Common::Timer::GetTimeFormatted().c_str(), | 
					
						
							| 
									
										
										
										
											2010-01-03 08:48:48 +00:00
										 |  |  | 			file, line, level_to_char[(int)level], | 
					
						
							|  |  |  | 			log->getShortName(), temp); | 
					
						
							| 
									
										
										
										
											2009-03-18 17:17:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-19 19:28:27 +00:00
										 |  |  | 	logMutex->Enter(); | 
					
						
							| 
									
										
										
										
											2009-03-18 17:17:58 +00:00
										 |  |  | 	log->trigger(level, msg); | 
					
						
							| 
									
										
										
										
											2010-01-19 19:28:27 +00:00
										 |  |  | 	logMutex->Leave(); | 
					
						
							| 
									
										
										
										
											2009-03-18 17:17:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-14 17:52:01 +00:00
										 |  |  | void LogManager::removeListener(LogTypes::LOG_TYPE type, LogListener *listener) { | 
					
						
							| 
									
										
										
										
											2010-01-19 19:28:27 +00:00
										 |  |  | 	logMutex->Enter(); | 
					
						
							| 
									
										
										
										
											2009-03-18 17:17:58 +00:00
										 |  |  | 	m_Log[type]->removeListener(listener); | 
					
						
							| 
									
										
										
										
											2010-01-19 19:28:27 +00:00
										 |  |  | 	logMutex->Leave(); | 
					
						
							| 
									
										
										
										
											2009-03-18 17:17:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-16 04:34:41 +00:00
										 |  |  | void LogManager::Init() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	m_logManager = new LogManager(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void LogManager::Shutdown() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	delete m_logManager; | 
					
						
							|  |  |  | 	m_logManager = NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-20 20:52:37 +00:00
										 |  |  | LogContainer::LogContainer(const char* shortName, const char* fullName, bool enable) | 
					
						
							|  |  |  | 	: m_enable(enable) { | 
					
						
							|  |  |  | 	strncpy(m_fullName, fullName, 128); | 
					
						
							|  |  |  | 	strncpy(m_shortName, shortName, 32); | 
					
						
							| 
									
										
										
										
											2010-12-14 17:52:01 +00:00
										 |  |  | 	m_level = LogTypes::LWARNING; | 
					
						
							| 
									
										
										
										
											2009-03-20 20:52:37 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-18 17:17:58 +00:00
										 |  |  | // LogContainer
 | 
					
						
							| 
									
										
										
										
											2009-03-20 19:12:04 +00:00
										 |  |  | void LogContainer::addListener(LogListener *listener) { | 
					
						
							| 
									
										
										
										
											2009-03-20 21:23:36 +00:00
										 |  |  | 	if (!isListener(listener)) | 
					
						
							| 
									
										
										
										
											2009-03-18 17:17:58 +00:00
										 |  |  | 		listeners.push_back(listener); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-20 19:12:04 +00:00
										 |  |  | void LogContainer::removeListener(LogListener *listener) { | 
					
						
							| 
									
										
										
										
											2010-05-28 23:14:16 +00:00
										 |  |  | 	std::vector<LogListener *>::iterator i = std::find(listeners.begin(), listeners.end(), listener); | 
					
						
							|  |  |  | 	if (listeners.end() != i) | 
					
						
							|  |  |  | 		listeners.erase(i); | 
					
						
							| 
									
										
										
										
											2009-03-18 17:17:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-20 19:12:04 +00:00
										 |  |  | bool LogContainer::isListener(LogListener *listener) const { | 
					
						
							| 
									
										
										
										
											2010-05-29 10:09:24 +00:00
										 |  |  | 	return listeners.end() != std::find(listeners.begin(), listeners.end(), listener); | 
					
						
							| 
									
										
										
										
											2009-03-18 17:17:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-14 17:52:01 +00:00
										 |  |  | void LogContainer::trigger(LogTypes::LOG_LEVELS level, const char *msg) { | 
					
						
							| 
									
										
										
										
											2009-03-20 19:12:04 +00:00
										 |  |  | 	std::vector<LogListener *>::const_iterator i; | 
					
						
							| 
									
										
										
										
											2010-05-28 23:14:16 +00:00
										 |  |  | 	for (i = listeners.begin(); i != listeners.end(); ++i) { | 
					
						
							| 
									
										
										
										
											2009-03-18 17:17:58 +00:00
										 |  |  | 		(*i)->Log(level, msg); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-20 19:12:04 +00:00
										 |  |  | FileLogListener::FileLogListener(const char *filename) { | 
					
						
							| 
									
										
										
										
											2009-03-18 17:17:58 +00:00
										 |  |  | 	m_filename = strndup(filename, 255); | 
					
						
							|  |  |  | 	m_logfile = fopen(filename, "a+"); | 
					
						
							|  |  |  | 	setEnable(true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | FileLogListener::~FileLogListener() { | 
					
						
							|  |  |  | 	free(m_filename); | 
					
						
							| 
									
										
										
										
											2010-02-16 04:34:41 +00:00
										 |  |  | 	if (m_logfile) | 
					
						
							|  |  |  | 		fclose(m_logfile); | 
					
						
							| 
									
										
										
										
											2009-03-18 17:17:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-14 17:52:01 +00:00
										 |  |  | void FileLogListener::Log(LogTypes::LOG_LEVELS, const char *msg) { | 
					
						
							| 
									
										
										
										
											2009-03-18 17:17:58 +00:00
										 |  |  | 	if (!m_enable || !isValid()) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-14 17:52:01 +00:00
										 |  |  |    	fwrite(msg, strlen(msg) * sizeof(char), 1, m_logfile); | 
					
						
							| 
									
										
										
										
											2009-03-18 17:17:58 +00:00
										 |  |  | 	fflush(m_logfile); | 
					
						
							|  |  |  | } |