Skip to content

Commit

Permalink
[FEATURE][needs-doc] Support QGIS Server logs to stderr
Browse files Browse the repository at this point in the history
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".
  • Loading branch information
Éric Lemoine committed Sep 11, 2018
1 parent 42aea6c commit e33954c
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 34 deletions.
11 changes: 11 additions & 0 deletions python/core/auto_generated/qgsmessagelog.sip.in
Expand Up @@ -117,6 +117,17 @@ be the right choice for apps without GUI.
public:
QgsMessageLogConsole();

protected:

QString formatLogMessage( const QString &message, const QString &tag, Qgis::MessageLevel level = Qgis::Info ) const;
%Docstring
Format a log message. Used by child classes.

:param message: the message to format
:param tag: the tag of the message
:param level: the log level of the message
%End

public slots:
void logMessage( const QString &message, const QString &tag, Qgis::MessageLevel level );
};
Expand Down
21 changes: 15 additions & 6 deletions src/core/qgsmessagelog.cpp
Expand Up @@ -18,7 +18,9 @@
#include "qgslogger.h"
#include <QDateTime>
#include <QMetaType>
#include <QTextStream>
#include <iostream>
#include <stdio.h>

class QgsMessageLogConsole;

Expand Down Expand Up @@ -47,12 +49,19 @@ QgsMessageLogConsole::QgsMessageLogConsole()

void QgsMessageLogConsole::logMessage( const QString &message, const QString &tag, Qgis::MessageLevel level )
{
std::cerr
<< tag.toLocal8Bit().data() << "[" <<
( level == Qgis::Info ? "INFO"
: level == Qgis::Warning ? "WARNING"
: "CRITICAL" )
<< "]: " << message.toLocal8Bit().data() << std::endl;
QString formattedMessage = formatLogMessage( message, tag, level );
QTextStream cerr( stderr );
cerr << formattedMessage;
}

QString QgsMessageLogConsole::formatLogMessage( const QString &message, const QString &tag, Qgis::MessageLevel level ) const
{
const QString time = QTime::currentTime().toString();
const QString levelStr = level == Qgis::Info ? QStringLiteral( "INFO" ) :
level == Qgis::Warning ? QStringLiteral( "WARNING" ) :
QStringLiteral( "CRITICAL" );
const QString pid = QString::number( QCoreApplication::applicationPid() );
return QStringLiteral( "%1 %2 %3[%4]: %5\n" ).arg( time, levelStr, tag, pid, message );
}

//
Expand Down
11 changes: 11 additions & 0 deletions src/core/qgsmessagelog.h
Expand Up @@ -140,6 +140,17 @@ class CORE_EXPORT QgsMessageLogConsole : public QObject
public:
QgsMessageLogConsole();

protected:

/**
* Format a log message. Used by child classes.
*
* \param message the message to format
* \param tag the tag of the message
* \param level the log level of the message
*/
QString formatLogMessage( const QString &message, const QString &tag, Qgis::MessageLevel level = Qgis::Info ) const;

public slots:
void logMessage( const QString &message, const QString &tag, Qgis::MessageLevel level );
};
Expand Down
54 changes: 27 additions & 27 deletions src/server/qgsserverlogger.cpp
Expand Up @@ -36,44 +36,44 @@ QgsServerLogger *QgsServerLogger::instance()
}

QgsServerLogger::QgsServerLogger()
: mLogFile( nullptr )
: QgsMessageLogConsole()
{
connect( QgsApplication::messageLog(), static_cast<void ( QgsMessageLog::* )( const QString &, const QString &, Qgis::MessageLevel )>( &QgsMessageLog::messageReceived ), this,
&QgsServerLogger::logMessage );
}

void QgsServerLogger::setLogLevel( Qgis::MessageLevel level )
void QgsServerLogger::logMessage( const QString &message, const QString &tag, Qgis::MessageLevel level )
{
if ( mLogLevel > level )
{
return;
}
if ( mLogFile.isOpen() )
{
QString formattedMessage = formatLogMessage( message, tag, level );
mTextStream << formattedMessage;
mTextStream.flush();
}
else if ( QString::compare( mLogFile.fileName(), QStringLiteral( "stderr" ), Qt::CaseInsensitive ) == 0 )
{
QgsMessageLogConsole::logMessage( message, tag, level );
}
}

void QgsServerLogger::setLogLevel( const Qgis::MessageLevel level )
{
mLogLevel = level;
}

void QgsServerLogger::setLogFile( const QString &f )
{
if ( ! f.isEmpty() )
{
if ( mLogFile.exists() )
{
mTextStream.flush();
mLogFile.close();
}
mTextStream.flush();
mLogFile.close();

mLogFile.setFileName( f );
if ( mLogFile.open( QIODevice::Append ) )
{
mTextStream.setDevice( &mLogFile );
}
}
}
mLogFile.setFileName( f );

void QgsServerLogger::logMessage( const QString &message, const QString &tag, Qgis::MessageLevel level )
{
Q_UNUSED( tag );
if ( !mLogFile.isOpen() || mLogLevel > level )
if ( ( ! f.isEmpty() ) &&
QString::compare( f, QStringLiteral( "stderr" ), Qt::CaseInsensitive ) != 0 &&
mLogFile.open( QIODevice::Append ) )
{
return;
mTextStream.setDevice( &mLogFile );
}

mTextStream << ( "[" + QString::number( qlonglong( QCoreApplication::applicationPid() ) ) + "]["
+ QTime::currentTime().toString() + "] " + message + "\n" );
mTextStream.flush();
}
2 changes: 1 addition & 1 deletion src/server/qgsserverlogger.h
Expand Up @@ -33,7 +33,7 @@
* \brief Writes message log into server logfile
* \since QGIS 2.8
*/
class QgsServerLogger: public QObject
class QgsServerLogger: public QgsMessageLogConsole
{
Q_OBJECT
public:
Expand Down

0 comments on commit e33954c

Please sign in to comment.