QGIS API Documentation 3.99.0-Master (8e76e220402)
Loading...
Searching...
No Matches
qgslogger.cpp
Go to the documentation of this file.
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 <QElapsedTimer>
22#include <QFile>
23#include <QString>
24#include <QThread>
25#include <QtDebug>
26
27using namespace Qt::StringLiterals;
28
29#ifndef CMAKE_SOURCE_DIR
30#error CMAKE_SOURCE_DIR undefined
31#endif // CMAKE_SOURCE_DIR
32
33int QgsLogger::sDebugLevel = -999; // undefined value
34int QgsLogger::sPrefixLength = -1;
35Q_GLOBAL_STATIC( QString, sFileFilter )
36Q_GLOBAL_STATIC( QString, sLogFile )
37Q_GLOBAL_STATIC( QElapsedTimer, sTime )
38
39void QgsLogger::init()
40{
41 if ( sDebugLevel != -999 )
42 return;
43
44 sTime()->start();
45
46 *sLogFile() = getenv( "QGIS_LOG_FILE" ) ? getenv( "QGIS_LOG_FILE" ) : "";
47 *sFileFilter() = getenv( "QGIS_DEBUG_FILE" ) ? getenv( "QGIS_DEBUG_FILE" ) : "";
48 sDebugLevel = getenv( "QGIS_DEBUG" ) ? atoi( getenv( "QGIS_DEBUG" ) ) :
49#ifdef QGISDEBUG
50 1
51#else
52 0
53#endif
54 ;
55
56 sPrefixLength = sizeof( CMAKE_SOURCE_DIR );
57 // cppcheck-suppress internalAstError
58 if ( CMAKE_SOURCE_DIR[sPrefixLength - 1] == '/' )
59 sPrefixLength++;
60}
61
62void QgsLogger::debug( const QString &msg, int debuglevel, const char *file, const char *function, int line )
63{
64 init();
65
66 if ( !file && !sFileFilter()->isEmpty() && !sFileFilter()->endsWith( file ) )
67 return;
68
69 if ( sDebugLevel == 0 || debuglevel > sDebugLevel )
70 return;
71
72
73 QString m = msg;
74
75 if ( file )
76 {
77 if ( qApp && qApp->thread() != QThread::currentThread() )
78 {
79 m.prepend( u"[thread:0x%1] "_s.arg( reinterpret_cast< qint64 >( QThread::currentThread() ), 0, 16 ) );
80 }
81
82 m.prepend( u"[%1ms] "_s.arg( sTime()->elapsed() ) );
83 sTime()->restart();
84
85 if ( function )
86 {
87 m.prepend( u" (%1) "_s.arg( function ) );
88 }
89
90 if ( line != -1 )
91 {
92#ifndef _MSC_VER
93 m.prepend( u":%1 :"_s.arg( line ) );
94#else
95 m.prepend( QString( "(%1) :" ).arg( line ) );
96#endif
97 }
98
99#ifndef _MSC_VER
100 m.prepend( file + ( file[0] == '/' ? sPrefixLength : 0 ) );
101#else
102 m.prepend( file );
103#endif
104 }
105
106 if ( sLogFile()->isEmpty() )
107 {
108 if ( debuglevel == 0 )
109 {
110 // debug level 0 is for errors only, so highlight these by dumping them to stderr
111 std::cerr << m.toUtf8().constData() << std::endl;
112 }
113 else
114 {
115 qDebug( "%s", m.toUtf8().constData() );
116 }
117 }
118 else
119 {
120 logMessageToFile( m );
121 }
122}
123
124void QgsLogger::debug( const QString &var, int val, int debuglevel, const char *file, const char *function, int line )
125{
126 debug( u"%1: %2"_s.arg( var ).arg( val ), debuglevel, file, function, line );
127}
128
129void QgsLogger::debug( const QString &var, double val, int debuglevel, const char *file, const char *function, int line )
130{
131 debug( u"%1: %2"_s.arg( var ).arg( val ), debuglevel, file, function, line );
132}
133
134void QgsLogger::warning( const QString &msg )
135{
136 logMessageToFile( msg );
137 qWarning( "Logged warning: %s", msg.toLocal8Bit().constData() );
138}
139
140void QgsLogger::critical( const QString &msg )
141{
142 logMessageToFile( msg );
143 qCritical( "Logged critical: %s", msg.toLocal8Bit().constData() );
144}
145
146void QgsLogger::fatal( const QString &msg )
147{
148 logMessageToFile( msg );
149 qFatal( "Logged fatal: %s", msg.toLocal8Bit().constData() );
150}
151
152void QgsLogger::logMessageToFile( const QString &message )
153{
154 if ( sLogFile()->isEmpty() )
155 return;
156
157 //Maybe more efficient to keep the file open for the life of qgis...
158 QFile file( *sLogFile() );
159 if ( !file.open( QIODevice::Append ) )
160 return;
161 file.write( message.toLocal8Bit().constData() );
162 file.write( "\n" );
163 file.close();
164}
165
167{
168 init();
169 return *sLogFile();
170}
static void fatal(const QString &msg)
Goes to qFatal.
static void debug(const QString &msg, int debuglevel=1, const char *file=nullptr, const char *function=nullptr, int line=-1)
Goes to qDebug.
Definition qgslogger.cpp:62
static QString logFile()
Reads the environment variable QGIS_LOG_FILE.
static void critical(const QString &msg)
Goes to qCritical.
static void logMessageToFile(const QString &message)
Logs the message passed in to the logfile defined in QGIS_LOG_FILE if any.
static void warning(const QString &msg)
Goes to qWarning.
Q_GLOBAL_STATIC(QReadWriteLock, sDefinitionCacheLock)