1 /***************************************************************************
2 qgslogger.cpp - description
3 -------------------
4 begin : April 2006
5 copyright : (C) 2006 by Marco Hugentobler
6 email : marco.hugentobler at karto dot baug dot ethz dot ch
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18 #include "qgslogger.h"
19
20 #include <QApplication>
21 #include <QtDebug>
22 #include <QFile>
23 #include <QElapsedTimer>
24 #include <QThread>
25
26 #ifndef CMAKE_SOURCE_DIR
27 #error CMAKE_SOURCE_DIR undefined
28 #endif // CMAKE_SOURCE_DIR
29
30 int QgsLogger::sDebugLevel = -999; // undefined value
31 int QgsLogger::sPrefixLength = -1;
Q_GLOBAL_STATIC(QString,sFileFilter)32 Q_GLOBAL_STATIC( QString, sFileFilter )
33 Q_GLOBAL_STATIC( QString, sLogFile )
34 Q_GLOBAL_STATIC( QElapsedTimer, sTime )
35
36 void QgsLogger::init()
37 {
38 if ( sDebugLevel != -999 )
39 return;
40
41 sTime()->start();
42
43 *sLogFile() = getenv( "QGIS_LOG_FILE" ) ? getenv( "QGIS_LOG_FILE" ) : "";
44 *sFileFilter() = getenv( "QGIS_DEBUG_FILE" ) ? getenv( "QGIS_DEBUG_FILE" ) : "";
45 sDebugLevel = getenv( "QGIS_DEBUG" ) ? atoi( getenv( "QGIS_DEBUG" ) ) :
46 #ifdef QGISDEBUG
47 1
48 #else
49 0
50 #endif
51 ;
52
53 sPrefixLength = sizeof( CMAKE_SOURCE_DIR );
54 if ( CMAKE_SOURCE_DIR[sPrefixLength - 1] == '/' )
55 sPrefixLength++;
56 }
57
debug(const QString & msg,int debuglevel,const char * file,const char * function,int line)58 void QgsLogger::debug( const QString &msg, int debuglevel, const char *file, const char *function, int line )
59 {
60 init();
61
62 if ( !file && !sFileFilter()->isEmpty() && !sFileFilter()->endsWith( file ) )
63 return;
64
65 if ( sDebugLevel == 0 || debuglevel > sDebugLevel )
66 return;
67
68
69 QString m = msg;
70
71 if ( file )
72 {
73 if ( qApp && qApp->thread() != QThread::currentThread() )
74 {
75 m.prepend( QStringLiteral( "[thread:0x%1] " ).arg( reinterpret_cast< qint64 >( QThread::currentThread() ), 0, 16 ) );
76 }
77
78 m.prepend( QStringLiteral( "[%1ms] " ).arg( sTime()->elapsed() ) );
79 sTime()->restart();
80
81 if ( function )
82 {
83 m.prepend( QStringLiteral( " (%1) " ).arg( function ) );
84 }
85
86 if ( line != -1 )
87 {
88 #ifndef _MSC_VER
89 m.prepend( QStringLiteral( ":%1 :" ).arg( line ) );
90 #else
91 m.prepend( QString( "(%1) :" ).arg( line ) );
92 #endif
93 }
94
95 #ifndef _MSC_VER
96 m.prepend( file + ( file[0] == '/' ? sPrefixLength : 0 ) );
97 #else
98 m.prepend( file );
99 #endif
100 }
101
102 if ( sLogFile()->isEmpty() )
103 {
104 qDebug( "%s", m.toUtf8().constData() );
105 }
106 else
107 {
108 logMessageToFile( m );
109 }
110 }
111
debug(const QString & var,int val,int debuglevel,const char * file,const char * function,int line)112 void QgsLogger::debug( const QString &var, int val, int debuglevel, const char *file, const char *function, int line )
113 {
114 debug( QStringLiteral( "%1: %2" ).arg( var ).arg( val ), debuglevel, file, function, line );
115 }
116
debug(const QString & var,double val,int debuglevel,const char * file,const char * function,int line)117 void QgsLogger::debug( const QString &var, double val, int debuglevel, const char *file, const char *function, int line )
118 {
119 debug( QStringLiteral( "%1: %2" ).arg( var ).arg( val ), debuglevel, file, function, line );
120 }
121
warning(const QString & msg)122 void QgsLogger::warning( const QString &msg )
123 {
124 logMessageToFile( msg );
125 qWarning( "Logged warning: %s", msg.toLocal8Bit().constData() );
126 }
127
critical(const QString & msg)128 void QgsLogger::critical( const QString &msg )
129 {
130 logMessageToFile( msg );
131 qCritical( "Logged critical: %s", msg.toLocal8Bit().constData() );
132 }
133
fatal(const QString & msg)134 void QgsLogger::fatal( const QString &msg )
135 {
136 logMessageToFile( msg );
137 qFatal( "Logged fatal: %s", msg.toLocal8Bit().constData() );
138 }
139
logMessageToFile(const QString & message)140 void QgsLogger::logMessageToFile( const QString &message )
141 {
142 if ( sLogFile()->isEmpty() )
143 return;
144
145 //Maybe more efficient to keep the file open for the life of qgis...
146 QFile file( *sLogFile() );
147 if ( !file.open( QIODevice::Append ) )
148 return;
149 file.write( message.toLocal8Bit().constData() );
150 file.write( "\n" );
151 file.close();
152 }
153
logFile()154 QString QgsLogger::logFile()
155 {
156 init();
157 return *sLogFile();
158 }
159