1// 2// This file is part of the aMule Project. 3// 4// Copyright (c) 2005-2011 aMule Team ( admin@amule.org / http://www.amule.org ) 5// 6// Any parts of this program derived from the xMule, lMule or eMule project, 7// or contributed by third-party developers are copyrighted by their 8// respective authors. 9// 10// This program is free software; you can redistribute it and/or modify 11// it under the terms of the GNU General Public License as published by 12// the Free Software Foundation; either version 2 of the License, or 13// (at your option) any later version. 14// 15// This program is distributed in the hope that it will be useful, 16// but WITHOUT ANY WARRANTY; without even the implied warranty of 17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18// GNU General Public License for more details. 19// 20// You should have received a copy of the GNU General Public License 21// along with this program; if not, write to the Free Software 22// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 23// 24 25#ifndef LOGGER_H 26#define LOGGER_H 27 28#include <wx/log.h> 29#include <wx/event.h> 30#include <iosfwd> 31 32 33enum DebugType 34{ 35 //! Standard warning, not debug 36 logStandard = -1, 37 //! General warnings/errors. 38 logGeneral = 0, 39 //! Warnings/Errors for the main hashing thread. 40 logHasher, 41 //! Warnings/Errors for client-objects. 42 logClient, 43 //! Warnings/Errors for the local client protocol. 44 logLocalClient, 45 //! Warnings/Errors for the remote client protocol. 46 logRemoteClient, 47 //! Warnings/Errors when parsing packets. 48 logPacketErrors, 49 //! Warnings/Errors for the CFile class. 50 logCFile, 51 //! Warnings/Errors related to reading/writing files. 52 logFileIO, 53 //! Warnings/Errors when using the zLib library. 54 logZLib, 55 //! Warnings/Errors for the AICH-syncronization thread. 56 logAICHThread, 57 //! Warnings/Errors for transfering AICH hash-sets. 58 logAICHTransfer, 59 //! Warnings/Errors when recovering with AICH. 60 logAICHRecovery, 61 //! Warnings/Errors for the CListenSocket class. 62 logListenSocket, 63 //! Warnings/Errors for Client-Credits. 64 logCredits, 65 //! Warnings/Errors for the client UDP socket. 66 logClientUDP, 67 //! Warnings/Errors for the download-queue. 68 logDownloadQueue, 69 //! Warnings/Errors for the IP-Filter. 70 logIPFilter, 71 //! Warnings/Errors for known-files. 72 logKnownFiles, 73 //! Warnings/Errors for part-files. 74 logPartFile, 75 //! Warnings/Errors for SHA-hashset creation. 76 logSHAHashSet, 77 //! Warnings/Errors for servers, server connections. 78 logServer, 79 //! Warnings/Errors for proxy. 80 logProxy, 81 //! Warnings/Errors related to searching. 82 logSearch, 83 //! Warnings/Errors related to the server UDP socket. 84 logServerUDP, 85 //! Warning/Errors related to Kademlia UDP comunication on client 86 logClientKadUDP, 87 //! Warning/Errors related to Kademlia Search 88 logKadSearch, 89 //! Warning/Errors related to Kademlia Routing 90 logKadRouting, 91 //! Warning/Errors related to Kademlia Indexing 92 logKadIndex, 93 //! Warning/Errors related to Kademlia Main Thread 94 logKadMain, 95 //! Warning/Errors related to Kademlia Preferences 96 logKadPrefs, 97 //! Warnings/Errors related to partfile importer 98 logPfConvert, 99 //! Warnings/Errors related to the basic UDP socket-class. 100 logMuleUDP, 101 //! Warnings/Errors related to the thread-scheduler. 102 logThreads, 103 //! Warnings/Errors related to the Universal Plug and Play subsystem. 104 logUPnP, 105 //! Warnings/Errors related to the UDP Firewall Tester 106 logKadUdpFwTester, 107 //! Warnings/Errors related to Kad packet tracking. 108 logKadPacketTracking, 109 //! Warnings/Errors related to Kad entry tracking. 110 logKadEntryTracking, 111 //! Full log of external connection packets 112 logEC, 113 //! Warnings/Errors related to HTTP traffic 114 logHTTP 115 // IMPORTANT NOTE: when you add values to this enum, update the g_debugcats 116 // array in Logger.cpp! 117}; 118 119 120 121/** 122 * Container-class for the debugging categories. 123 */ 124class CDebugCategory 125{ 126public: 127 /** 128 * Constructor. 129 * 130 * @param type The actual debug-category type. 131 * @param name The user-readable name. 132 */ 133 CDebugCategory( DebugType type, const wxString& name ) 134 : m_name(name), m_type(type), m_enabled(false) 135 {} 136 137 138 /** 139 * Returns true if the category is enabled. 140 */ 141 bool IsEnabled() const { return m_enabled; } 142 143 /** 144 * Enables/Disables the category. 145 */ 146 void SetEnabled( bool enabled ) { m_enabled = enabled; } 147 148 149 /** 150 * Returns the user-readable name. 151 */ 152 const wxString& GetName() const { return m_name; } 153 154 /** 155 * Returns the actual type. 156 */ 157 DebugType GetType() const { return m_type; } 158 159private: 160 //! The user-readable name. 161 wxString m_name; 162 //! The actual type. 163 DebugType m_type; 164 //! Whenever or not the category is enabled. 165 bool m_enabled; 166}; 167 168 169/** 170 * Functions for logging operations. 171 */ 172class CLogger: public wxEvtHandler 173{ 174public: 175 /** 176 * Returns true if debug-messages should be generated for a specific category. 177 */ 178#ifdef __DEBUG__ 179 bool IsEnabled( DebugType ) const; 180#else 181 bool IsEnabled( DebugType ) const { return false; } 182#endif 183 184 /** 185 * Enables or disables debug-messages for a specific category. 186 */ 187 void SetEnabled( DebugType type, bool enabled ); 188 189 /** 190 * Returns true if logging to stdout is enabled 191 */ 192 bool IsEnabledStdoutLog() const { return m_StdoutLog; } 193 194 /** 195 * Enables or disables logging to stdout. 196 */ 197 void SetEnabledStdoutLog(bool enabled) { m_StdoutLog = enabled; } 198 199 200 /** 201 * Logs the specified line of text, prefixed with the name of the DebugType. 202 * (except for logStandard) 203 * 204 * @param file 205 * @param line 206 * @param critical If true, then the message will be made visible directly to the user. 207 * @param type The debug-category, the name of which will be prepended to the line. 208 * @param str The actual line of text. 209 * 210 * This function is thread-safe. If it is called by the main thread, the 211 * event will be sent directly to the application, otherwise it will be 212 * queued in the event-loop. 213 */ 214 void AddLogLine( 215 const wxString &file, 216 int line, 217 bool critical, 218 DebugType type, 219 const wxString &str, 220 bool toStdout = false, 221 bool toGUI = true); 222 223 // for UPnP 224 void AddLogLine( 225 const wxString &file, 226 int line, 227 bool critical, 228 DebugType type, 229 const std::ostringstream &msg); 230 231 void AddLogLine( 232 const wxString &file, 233 int line, 234 bool critical, 235 const std::ostringstream &msg); 236 237 238 /** 239 * Returns a category specified by index. 240 */ 241 const CDebugCategory& GetDebugCategory( int index ); 242 243 /** 244 * Returns the number of debug-categories. 245 */ 246 unsigned int GetDebugCategoryCount(); 247 248 /** 249 * Open Logfile, true on success 250 */ 251 bool OpenLogfile(const wxString & name); 252 253 /** 254 * Close Logfile 255 */ 256 void CloseLogfile(); 257 258 /** 259 * Get name of Logfile 260 */ 261 const wxString & GetLogfileName() const { 262 return m_LogfileName; 263 } 264 265 /** 266 * Event handler 267 */ 268 void OnLoggingEvent(class CLoggingEvent& evt); 269 270 /** 271 * Construct 272 */ 273 CLogger() { 274 applog = NULL; 275 m_StdoutLog = false; 276 m_count = 0; 277 } 278 279private: 280 class wxFFileOutputStream* applog; // the logfile 281 wxString m_LogfileName; 282 wxString m_ApplogBuf; 283 bool m_StdoutLog; 284 int m_count; // output line counter 285 286 /** 287 * Write all waiting log info to the logfile 288 */ 289 void FlushApplog(); 290 291 /** 292 * Really output a single line 293 */ 294 void DoLine(const wxString & line, bool toStdout, bool toGUI); 295 296 DECLARE_EVENT_TABLE() 297}; 298 299extern CLogger theLogger; 300 301/** 302 * This class forwards log-lines from wxWidgets to CLogger. 303 */ 304class CLoggerTarget : public wxLog 305{ 306public: 307 CLoggerTarget(); 308 309 /** 310 * @see wxLog::DoLogString 311 */ 312#if wxCHECK_VERSION(2, 9, 0) 313 void DoLogText(const wxString &msg); 314#else 315 void DoLogString(const wxChar *msg, time_t); 316#endif 317}; 318 319 320DECLARE_LOCAL_EVENT_TYPE(MULE_EVT_LOGLINE, -1) 321 322 323/** This event is sent when a log-line is queued. */ 324class CLoggingEvent : public wxEvent 325{ 326public: 327 CLoggingEvent(bool critical, bool toStdout, bool toGUI, const wxString& msg) 328 : wxEvent(-1, MULE_EVT_LOGLINE) 329 , m_critical(critical) 330 , m_stdout(toStdout) 331 , m_GUI(toGUI) 332 // Deep copy, to avoid thread-unsafe reference counting. */ 333 , m_msg(msg.c_str(), msg.Length()) 334 { 335 } 336 337 const wxString& Message() const { 338 return m_msg; 339 } 340 341 bool IsCritical() const { 342 return m_critical; 343 } 344 345 bool ToStdout() const { 346 return m_stdout; 347 } 348 349 bool ToGUI() const { 350 return m_GUI; 351 } 352 353 wxEvent* Clone() const { 354 return new CLoggingEvent(m_critical, m_stdout, m_GUI, m_msg); 355 } 356 357private: 358 bool m_critical; 359 bool m_stdout; 360 bool m_GUI; 361 wxString m_msg; 362}; 363 364 365typedef void (wxEvtHandler::*MuleLogEventFunction)(CLoggingEvent&); 366 367//! Event-handler for completed hashings of new shared files and partfiles. 368#define EVT_MULE_LOGGING(func) \ 369 DECLARE_EVENT_TABLE_ENTRY(MULE_EVT_LOGLINE, -1, -1, \ 370 (wxObjectEventFunction) (wxEventFunction) \ 371 wxStaticCastEvent(MuleLogEventFunction, &func), (wxObject*) NULL), 372 373 374// access the logfile for EC 375class CLoggerAccess 376{ 377private: 378 class wxFFileInputStream * m_logfile; 379 class wxCharBuffer * m_buffer; 380 size_t m_bufferlen; 381 size_t m_pos; 382 383 bool m_ready; 384public: 385 // 386 // construct/destruct 387 // 388 CLoggerAccess(); 389 ~CLoggerAccess(); 390 // 391 // Reset (used when logfile is cleared) 392 // 393 void Reset(); 394 // 395 // get a String (if there is one) 396 // 397 bool GetString(wxString & s); 398 // 399 // is a String available ? 400 // 401 bool HasString(); 402}; 403 404 405/** 406 * These macros should be used when logging. The 407 * AddLogLineM macro will simply call one of the 408 * two CLogger::AddLogLine functions depending on 409 * parameters, but AddDebugLogLine* will only log 410 * a message if the message is either critical or 411 * the specified debug-type is enabled in the 412 * preferences. 413 * AddLogLineMS will also always print to stdout. 414 */ 415#ifdef MULEUNIT 416 #define AddDebugLogLineN(...) do {} while (false) 417 #define AddLogLineN(...) do {} while (false) 418 #define AddLogLineNS(...) do {} while (false) 419 #define AddDebugLogLineC(...) do {} while (false) 420 #define AddLogLineC(...) do {} while (false) 421 #define AddLogLineCS(...) do {} while (false) 422#else 423// Macro for UPnP. This is not a debug macro, but wants its category printed nevertheless (sigh). 424 #define AddLogLineU(critical, type, string) theLogger.AddLogLine(__TFILE__, __LINE__, critical, type, string) 425// Macros for 'N'on critical logging 426 #ifdef __DEBUG__ 427 #define AddDebugLogLineN(type, string) theLogger.AddLogLine(__TFILE__, __LINE__, false, type, string) 428 #else 429 #define AddDebugLogLineN(type, string) do {} while (false) 430 #endif 431 #define AddLogLineN(string) theLogger.AddLogLine(__TFILE__, __LINE__, false, logStandard, string) 432 #define AddLogLineNS(string) theLogger.AddLogLine(__TFILE__, __LINE__, false, logStandard, string, true) 433// Macros for 'C'ritical logging 434 #define AddDebugLogLineC(type, string) theLogger.AddLogLine(__TFILE__, __LINE__, true, type, string) 435 #define AddLogLineC(string) theLogger.AddLogLine(__TFILE__, __LINE__, true, logStandard, string) 436 #define AddLogLineCS(string) theLogger.AddLogLine(__TFILE__, __LINE__, true, logStandard, string, true) 437// Macros for logging to logfile only 438 #define AddDebugLogLineF(type, string) theLogger.AddLogLine(__TFILE__, __LINE__, false, type, string, false, false) 439 #define AddLogLineF(string) theLogger.AddLogLine(__TFILE__, __LINE__, false, logStandard, string, false, false) 440#endif 441 442#endif 443// File_checked_for_headers 444