/src/libtomahawk/utils/Logger.cpp

http://github.com/tomahawk-player/tomahawk · C++ · 220 lines · 158 code · 42 blank · 20 comment · 15 complexity · 17327efd964f847260717c9c9cf9a4ed MD5 · raw file

  1. /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
  2. *
  3. * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
  4. *
  5. * Tomahawk is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * Tomahawk is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "Logger.h"
  19. #include <iostream>
  20. #include <fstream>
  21. #include <QCoreApplication>
  22. #include <QDir>
  23. #include <QFileInfo>
  24. #include <QMutex>
  25. #include <QTime>
  26. #include <QVariant>
  27. #include "utils/TomahawkUtils.h"
  28. #define LOGFILE_SIZE 1024 * 256
  29. #define RELEASE_LEVEL_THRESHOLD 0
  30. #define DEBUG_LEVEL_THRESHOLD LOGEXTRA
  31. #define LOG_SQL_QUERIES 1
  32. using namespace std;
  33. ofstream logStream;
  34. static int s_threshold = -1;
  35. QMutex s_mutex;
  36. bool shutdownInProgress = false;
  37. namespace Logger
  38. {
  39. static void
  40. log( const char *msg, unsigned int debugLevel, bool toDisk = true )
  41. {
  42. if ( s_threshold < 0 )
  43. {
  44. if ( qApp->arguments().contains( "--verbose" ) )
  45. s_threshold = LOGTHIRDPARTY;
  46. else
  47. #ifdef QT_NO_DEBUG
  48. s_threshold = RELEASE_LEVEL_THRESHOLD;
  49. #else
  50. s_threshold = DEBUG_LEVEL_THRESHOLD;
  51. #endif
  52. }
  53. if ( debugLevel > LOGTHIRDPARTY )
  54. toDisk = false;
  55. #ifdef LOG_SQL_QUERIES
  56. if ( debugLevel == LOGSQL )
  57. toDisk = true;
  58. #endif
  59. if ( toDisk || (int)debugLevel <= s_threshold )
  60. {
  61. QMutexLocker lock( &s_mutex );
  62. #ifdef LOG_SQL_QUERIES
  63. if ( debugLevel == LOGSQL )
  64. logStream << "TSQLQUERY: ";
  65. #endif
  66. if ( shutdownInProgress )
  67. {
  68. // Do not use locales anymore in shutdown
  69. logStream << QDate::currentDate().day() << "."
  70. << QDate::currentDate().month() << "."
  71. << QDate::currentDate().year() << " - "
  72. << QTime::currentTime().hour() << ":"
  73. << QTime::currentTime().minute() << ":"
  74. << QTime::currentTime().second()
  75. << " [" << QString::number( debugLevel ).toUtf8().data() << "]: "
  76. << msg << endl;
  77. }
  78. else
  79. {
  80. logStream << QDate::currentDate().toString().toUtf8().data()
  81. << " - "
  82. << QTime::currentTime().toString().toUtf8().data()
  83. << " [" << QString::number( debugLevel ).toUtf8().data() << "]: "
  84. << msg << endl;
  85. }
  86. logStream.flush();
  87. }
  88. if ( debugLevel <= LOGEXTRA || (int)debugLevel <= s_threshold )
  89. {
  90. QMutexLocker lock( &s_mutex );
  91. if ( shutdownInProgress )
  92. {
  93. wcout << QTime::currentTime().hour() << ":"
  94. << QTime::currentTime().minute() << ":"
  95. << QTime::currentTime().second()
  96. << " [" << QString::number( debugLevel ).toStdWString().c_str() << "]: "
  97. << msg << endl;
  98. }
  99. else
  100. {
  101. wcout << QTime::currentTime().toString().toUtf8().data()
  102. << " [" << QString::number( debugLevel ).toStdWString().c_str() << "]: "
  103. << msg << endl;
  104. }
  105. wcout.flush();
  106. }
  107. }
  108. void
  109. TomahawkLogHandler( QtMsgType type, const QMessageLogContext& context, const QString& msg )
  110. {
  111. static QMutex s_mutex;
  112. QByteArray ba = msg.toUtf8();
  113. const char* message = ba.constData();
  114. QMutexLocker locker( &s_mutex );
  115. switch( type )
  116. {
  117. case QtDebugMsg:
  118. log( message, LOGTHIRDPARTY );
  119. break;
  120. case QtInfoMsg:
  121. log( message, 0 );
  122. break;
  123. case QtCriticalMsg:
  124. log( message, 0 );
  125. break;
  126. case QtWarningMsg:
  127. log( message, 0 );
  128. break;
  129. case QtFatalMsg:
  130. log( message, 0 );
  131. break;
  132. }
  133. }
  134. void
  135. setupLogfile( QFile& f )
  136. {
  137. if ( QFileInfo( f ).size() > LOGFILE_SIZE )
  138. {
  139. QByteArray lc;
  140. {
  141. f.open( QIODevice::ReadOnly | QIODevice::Text );
  142. f.seek( f.size() - ( LOGFILE_SIZE - ( LOGFILE_SIZE / 4 ) ) );
  143. lc = f.readAll();
  144. f.close();
  145. }
  146. f.remove();
  147. {
  148. f.open( QIODevice::WriteOnly | QIODevice::Text );
  149. f.write( lc );
  150. f.close();
  151. }
  152. }
  153. #ifdef OFSTREAM_CAN_OPEN_WCHAR_FILE_NAMES
  154. // this is not supported in upstream libstdc++ as shipped with GCC
  155. // GCC needs the patch from https://gcc.gnu.org/ml/libstdc++/2011-06/msg00066.html applied
  156. logStream.open( f.fileName().toStdWString().c_str() );
  157. #else
  158. logStream.open( f.fileName().toStdString().c_str() );
  159. #endif
  160. qInstallMessageHandler( TomahawkLogHandler );
  161. }
  162. }
  163. using namespace Logger;
  164. TLog::TLog( unsigned int debugLevel )
  165. : QDebug( &m_msg )
  166. , m_debugLevel( debugLevel )
  167. {
  168. }
  169. TLog::~TLog()
  170. {
  171. log( m_msg.toUtf8().data(), m_debugLevel );
  172. }
  173. void
  174. tLogNotifyShutdown()
  175. {
  176. QMutexLocker locker( &s_mutex );
  177. shutdownInProgress = true;
  178. }