Skip to content

Commit e33954c

Browse files
author
Éric Lemoine
committed
[FEATURE][needs-doc] Support QGIS Server logs to stderr
This commit makes it possible to configure QGIS Server to make it write its logs to stderr. This is done by setting the QGIS_SERVER_LOG_FILE env var to the special value "stderr".
1 parent 42aea6c commit e33954c

File tree

5 files changed

+65
-34
lines changed

5 files changed

+65
-34
lines changed

python/core/auto_generated/qgsmessagelog.sip.in

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,17 @@ be the right choice for apps without GUI.
117117
public:
118118
QgsMessageLogConsole();
119119

120+
protected:
121+
122+
QString formatLogMessage( const QString &message, const QString &tag, Qgis::MessageLevel level = Qgis::Info ) const;
123+
%Docstring
124+
Format a log message. Used by child classes.
125+
126+
:param message: the message to format
127+
:param tag: the tag of the message
128+
:param level: the log level of the message
129+
%End
130+
120131
public slots:
121132
void logMessage( const QString &message, const QString &tag, Qgis::MessageLevel level );
122133
};

src/core/qgsmessagelog.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
#include "qgslogger.h"
1919
#include <QDateTime>
2020
#include <QMetaType>
21+
#include <QTextStream>
2122
#include <iostream>
23+
#include <stdio.h>
2224

2325
class QgsMessageLogConsole;
2426

@@ -47,12 +49,19 @@ QgsMessageLogConsole::QgsMessageLogConsole()
4749

4850
void QgsMessageLogConsole::logMessage( const QString &message, const QString &tag, Qgis::MessageLevel level )
4951
{
50-
std::cerr
51-
<< tag.toLocal8Bit().data() << "[" <<
52-
( level == Qgis::Info ? "INFO"
53-
: level == Qgis::Warning ? "WARNING"
54-
: "CRITICAL" )
55-
<< "]: " << message.toLocal8Bit().data() << std::endl;
52+
QString formattedMessage = formatLogMessage( message, tag, level );
53+
QTextStream cerr( stderr );
54+
cerr << formattedMessage;
55+
}
56+
57+
QString QgsMessageLogConsole::formatLogMessage( const QString &message, const QString &tag, Qgis::MessageLevel level ) const
58+
{
59+
const QString time = QTime::currentTime().toString();
60+
const QString levelStr = level == Qgis::Info ? QStringLiteral( "INFO" ) :
61+
level == Qgis::Warning ? QStringLiteral( "WARNING" ) :
62+
QStringLiteral( "CRITICAL" );
63+
const QString pid = QString::number( QCoreApplication::applicationPid() );
64+
return QStringLiteral( "%1 %2 %3[%4]: %5\n" ).arg( time, levelStr, tag, pid, message );
5665
}
5766

5867
//

src/core/qgsmessagelog.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,17 @@ class CORE_EXPORT QgsMessageLogConsole : public QObject
140140
public:
141141
QgsMessageLogConsole();
142142

143+
protected:
144+
145+
/**
146+
* Format a log message. Used by child classes.
147+
*
148+
* \param message the message to format
149+
* \param tag the tag of the message
150+
* \param level the log level of the message
151+
*/
152+
QString formatLogMessage( const QString &message, const QString &tag, Qgis::MessageLevel level = Qgis::Info ) const;
153+
143154
public slots:
144155
void logMessage( const QString &message, const QString &tag, Qgis::MessageLevel level );
145156
};

src/server/qgsserverlogger.cpp

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -36,44 +36,44 @@ QgsServerLogger *QgsServerLogger::instance()
3636
}
3737

3838
QgsServerLogger::QgsServerLogger()
39-
: mLogFile( nullptr )
39+
: QgsMessageLogConsole()
4040
{
41-
connect( QgsApplication::messageLog(), static_cast<void ( QgsMessageLog::* )( const QString &, const QString &, Qgis::MessageLevel )>( &QgsMessageLog::messageReceived ), this,
42-
&QgsServerLogger::logMessage );
4341
}
4442

45-
void QgsServerLogger::setLogLevel( Qgis::MessageLevel level )
43+
void QgsServerLogger::logMessage( const QString &message, const QString &tag, Qgis::MessageLevel level )
44+
{
45+
if ( mLogLevel > level )
46+
{
47+
return;
48+
}
49+
if ( mLogFile.isOpen() )
50+
{
51+
QString formattedMessage = formatLogMessage( message, tag, level );
52+
mTextStream << formattedMessage;
53+
mTextStream.flush();
54+
}
55+
else if ( QString::compare( mLogFile.fileName(), QStringLiteral( "stderr" ), Qt::CaseInsensitive ) == 0 )
56+
{
57+
QgsMessageLogConsole::logMessage( message, tag, level );
58+
}
59+
}
60+
61+
void QgsServerLogger::setLogLevel( const Qgis::MessageLevel level )
4662
{
4763
mLogLevel = level;
4864
}
4965

5066
void QgsServerLogger::setLogFile( const QString &f )
5167
{
52-
if ( ! f.isEmpty() )
53-
{
54-
if ( mLogFile.exists() )
55-
{
56-
mTextStream.flush();
57-
mLogFile.close();
58-
}
68+
mTextStream.flush();
69+
mLogFile.close();
5970

60-
mLogFile.setFileName( f );
61-
if ( mLogFile.open( QIODevice::Append ) )
62-
{
63-
mTextStream.setDevice( &mLogFile );
64-
}
65-
}
66-
}
71+
mLogFile.setFileName( f );
6772

68-
void QgsServerLogger::logMessage( const QString &message, const QString &tag, Qgis::MessageLevel level )
69-
{
70-
Q_UNUSED( tag );
71-
if ( !mLogFile.isOpen() || mLogLevel > level )
73+
if ( ( ! f.isEmpty() ) &&
74+
QString::compare( f, QStringLiteral( "stderr" ), Qt::CaseInsensitive ) != 0 &&
75+
mLogFile.open( QIODevice::Append ) )
7276
{
73-
return;
77+
mTextStream.setDevice( &mLogFile );
7478
}
75-
76-
mTextStream << ( "[" + QString::number( qlonglong( QCoreApplication::applicationPid() ) ) + "]["
77-
+ QTime::currentTime().toString() + "] " + message + "\n" );
78-
mTextStream.flush();
7979
}

src/server/qgsserverlogger.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
* \brief Writes message log into server logfile
3434
* \since QGIS 2.8
3535
*/
36-
class QgsServerLogger: public QObject
36+
class QgsServerLogger: public QgsMessageLogConsole
3737
{
3838
Q_OBJECT
3939
public:

0 commit comments

Comments
 (0)