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