Commit db55f227 authored by Julien Wintz's avatar Julien Wintz
Browse files

Adding logging layer together with tests.

parent 65524fbd
......@@ -3,9 +3,9 @@
## Author: Julien Wintz
## Created: Mon Feb 4 10:17:21 2013 (+0100)
## Version:
## Last-Updated: Mon Feb 11 12:32:18 2013 (+0100)
## Last-Updated: Mon Feb 11 23:25:49 2013 (+0100)
## By: Julien Wintz
## Update #: 112
## Update #: 113
######################################################################
##
### Change Log:
......@@ -74,6 +74,7 @@ find_package(Qt5Widgets REQUIRED)
include_directories(${PROJECT_SOURCE_DIR}/src)
include_directories(${PROJECT_SOURCE_DIR}/src/dtk)
include_directories(${PROJECT_SOURCE_DIR}/src/dtkLog)
include_directories(${PROJECT_SOURCE_DIR}/src/dtkDistributed)
include_directories(${PROJECT_SOURCE_DIR}/src/dtkTest)
......
......@@ -3,9 +3,9 @@
## Author: Julien Wintz
## Created: Mon Feb 4 10:29:13 2013 (+0100)
## Version:
## Last-Updated: Fri Feb 8 16:54:13 2013 (+0100)
## Last-Updated: Mon Feb 11 20:31:57 2013 (+0100)
## By: Julien Wintz
## Update #: 6
## Update #: 7
######################################################################
##
### Change Log:
......@@ -13,6 +13,7 @@
######################################################################
add_subdirectory(dtk)
add_subdirectory(dtkLog)
add_subdirectory(dtkCore)
add_subdirectory(dtkDistributed)
add_subdirectory(dtkTest)
### CMakeLists.txt ---
##
## Author: Julien Wintz
## Created: Mon Feb 11 19:23:24 2013 (+0100)
## Version:
## Last-Updated: Wed Feb 13 15:22:23 2013 (+0100)
## By: Julien Wintz
## Update #: 21
######################################################################
##
### Change Log:
##
######################################################################
project(dtkLog)
## #################################################################
## Input
## #################################################################
set(${PROJECT_NAME}_HEADERS
dtkLogger.h
dtkLogger_p.h)
set(${PROJECT_NAME}_SOURCES
dtkLogger.cpp)
## #################################################################
## Build rules
## #################################################################
add_library(${PROJECT_NAME} SHARED
${${PROJECT_NAME}_SOURCES}
${${PROJECT_NAME}_HEADERS})
## ###################################################################
## Link rules
## ###################################################################
qt5_use_modules(${PROJECT_NAME} Core)
## ###################################################################
## Install rules - files
## ###################################################################
install(FILES ${${PROJECT_NAME}_HEADERS}
DESTINATION include/${PROJECT_NAME}
COMPONENT log)
## ###################################################################
## Install rules - targets
## ###################################################################
install(TARGETS ${PROJECT_NAME}
DESTINATION lib
COMPONENT log
EXPORT dtkDepends)
## ###################################################################
## Export rules
## ###################################################################
export(TARGETS dtkLog APPEND FILE "${CMAKE_BINARY_DIR}/dtkDepends.cmake")
#include "dtkLogger.h"
#include "dtkLogger_p.h"
This diff is collapsed.
/* dtkLogger.h ---
*
* Author: Julien Wintz
* Created: Wed Feb 13 12:18:35 2013 (+0100)
* Version:
* Last-Updated: Wed Feb 13 15:32:41 2013 (+0100)
* By: Julien Wintz
* Update #: 22
*/
/* Change Log:
*
*/
#pragma once
#include <QtCore>
#include <QtDebug>
// ///////////////////////////////////////////////////////////////////
// Logging rules
// ///////////////////////////////////////////////////////////////////
void dtkSetLoggingRules(const QByteArray &rules);
void dtkSetLoggingRulesFile(const QString &path);
// ///////////////////////////////////////////////////////////////////
// qDebug overload
// ///////////////////////////////////////////////////////////////////
#if defined(qDebug)
# undef qDebug
#endif
#define qDebug \
for (bool enabled = dtkLoggingCategory::defaultCategory().isEnabled(QtDebugMsg); enabled; enabled = false) \
QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, dtkLoggingCategory::defaultCategory().categoryName()).debug
// ///////////////////////////////////////////////////////////////////
// qWarning overload
// ///////////////////////////////////////////////////////////////////
#if defined(qWarning)
# undef qWarning
#endif
#define qWarning \
for (bool enabled = dtkLoggingCategory::defaultCategory().isEnabled(QtWarningMsg); enabled; enabled = false) \
QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, dtkLoggingCategory::defaultCategory().categoryName()).warning
// ///////////////////////////////////////////////////////////////////
// qCritical overload
// ///////////////////////////////////////////////////////////////////
#if defined(qCritical)
# undef qCritical
#endif
#define qCritical \
for (bool enabled = dtkLoggingCategory::defaultCategory().isEnabled(QtCriticalMsg); enabled; enabled = false) \
QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, dtkLoggingCategory::defaultCategory().categoryName()).critical
// ///////////////////////////////////////////////////////////////////
// Helper macro
// ///////////////////////////////////////////////////////////////////
#define DTK_LOG_CATEGORY(categorytype, categoryname) \
namespace { \
static dtkLoggingCategory categorytype(categoryname); \
}
// ///////////////////////////////////////////////////////////////////
// dtkDebug
// ///////////////////////////////////////////////////////////////////
#define dtkDebug(category) \
for (bool enabled = category.isEnabled(QtDebugMsg); enabled; enabled = false) \
QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, category.categoryName()).debug()
// ///////////////////////////////////////////////////////////////////
// dtkWarning
// ///////////////////////////////////////////////////////////////////
#define dtkWarning(category) \
for (bool enabled = category.isEnabled(QtWarningMsg); enabled; enabled = false) \
QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, category.categoryName()).warning()
// ///////////////////////////////////////////////////////////////////
// dtkCritical
// ///////////////////////////////////////////////////////////////////
#define dtkCritical(category) \
for (bool enabled = category.isEnabled(QtCriticalMsg); enabled; enabled = false) \
QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, category.categoryName()).critical()
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the logger module of the Qt Toolkit.
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
****************************************************************************/
// qlogger_p.h
#pragma once
#include "dtkLogger.h"
class QFileSystemWatcher;
// ///////////////////////////////////////////////////////////////////
// dtkLoggingCategory
// ///////////////////////////////////////////////////////////////////
class dtkLoggingCategoryPrivate
{
public:
dtkLoggingCategoryPrivate(void);
virtual ~dtkLoggingCategoryPrivate(void);
public:
bool statusMessageType(const QtMsgType &type);
public:
bool _enabledDebug;
bool _enabledWarning;
bool _enabledCritical;
bool _registered;
int _references;
};
// ///////////////////////////////////////////////////////////////////
// dtkLoggingCategory
// ///////////////////////////////////////////////////////////////////
class dtkLoggingCategory
{
Q_DISABLE_COPY(dtkLoggingCategory)
public:
dtkLoggingCategory(const char *category);
~dtkLoggingCategory(void);
bool isEnabled(QtMsgType msgtype);
const char *categoryName(void);
static dtkLoggingCategory& defaultCategory(void);
private:
dtkLoggingCategoryPrivate *d_ptr;
const char *_categoryName;
friend class dtkLoggingPrivate;
};
// ///////////////////////////////////////////////////////////////////
// dtkLogConfigFilterItem
// ///////////////////////////////////////////////////////////////////
class dtkLogConfigFilterItem
{
public:
dtkLogConfigFilterItem(const QString &category, bool active);
int pass(dtkLoggingCategory *log, const QtMsgType &type);
void parse(void);
int _type;
QString _category;
bool _active;
};
// ///////////////////////////////////////////////////////////////////
// dtkLogging
// ///////////////////////////////////////////////////////////////////
class dtkLoggingPrivate : public QObject
{
Q_OBJECT
public:
dtkLoggingPrivate();
virtual ~dtkLoggingPrivate();
public:
static QString resolveConfigFile(const QString &path);
public:
void setLoggingRulesFile(const QString &path);
void setLoggingRules(const QByteArray &configcontent);
bool isEnabled(dtkLoggingCategory &category, QtMsgType type);
void unregisterCategory(dtkLoggingCategory &category);
bool checkEnvironment() { return _environment; }
bool registerCategories() { return _registerCategories; }
dtkLoggingCategoryPrivate *categoryPrivate(dtkLoggingCategory &category);
void releasePrivate(dtkLoggingCategory &category);
public:
Q_INVOKABLE void createFileWatcher();
public:
void readSettings(QIODevice &device);
void updateCategory(dtkLoggingCategory *log);
signals:
void configurationChanged();
public slots:
void fileChanged(const QString &path);
public:
QFileSystemWatcher *_configFileWatcher;
QList<dtkLoggingCategory *> _registeredCategories;
QString _configFile;
QMutex _mutexRegisteredCategory;
QList<dtkLogConfigFilterItem> _logConfigItemList;
bool _environment;
bool _registerCategories;
QMutex _privateCategoryObjectsMutex;
QMap<QString, dtkLoggingCategoryPrivate *> _privateCategoryObjects;
};
// ///////////////////////////////////////////////////////////////////
// Helper functions
// ///////////////////////////////////////////////////////////////////
dtkLoggingPrivate *dtkLogger(void);
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the logger module of the Qt Toolkit.
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
g** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
****************************************************************************/
......@@ -3,13 +3,14 @@
## Author: Julien Wintz
## Created: Mon Feb 4 12:19:46 2013 (+0100)
## Version:
## Last-Updated: Mon Feb 4 16:34:10 2013 (+0100)
## Last-Updated: Mon Feb 11 23:21:35 2013 (+0100)
## By: Julien Wintz
## Update #: 20
## Update #: 21
######################################################################
##
### Change Log:
##
######################################################################
add_subdirectory(dtkLog)
add_subdirectory(dtkDistributed)
......@@ -3,12 +3,9 @@
## Author: Julien Wintz
## Created: Mon Feb 4 12:20:18 2013 (+0100)
## Version:
## Last-Updated: Mon Feb 4 16:55:07 2013 (+0100)
## Last-Updated: Mon Feb 11 23:30:44 2013 (+0100)
## By: Julien Wintz
## Update #: 47
## Last-Updated: 2013 Mon Feb 4 15:39:14 (+0100)
## By: Thibaud Kloczko
## Update #: 17
## Update #: 48
######################################################################
##
### Change Log:
......
### CMakeLists.txt ---
##
## Author: Julien Wintz
## Created: Mon Feb 11 20:47:00 2013 (+0100)
## Version:
## Last-Updated: Wed Feb 13 16:07:21 2013 (+0100)
## By: Julien Wintz
## Update #: 19
######################################################################
##
### Change Log:
##
######################################################################
project(dtkLogTest)
## ###################################################################
## Input
## ###################################################################
set(${PROJECT_NAME}_HEADERS
dtkLoggerTest.h
dtkLoggerEnvTest.h)
set(${PROJECT_NAME}_SOURCES
dtkLoggerTest.cpp
dtkLoggerEnvTest.cpp)
## ###################################################################
## Input - introspected
## ###################################################################
create_test_sourcelist(
${PROJECT_NAME}_SOURCES_TST
${PROJECT_NAME}.cpp
${${PROJECT_NAME}_SOURCES})
## ###################################################################
## Build rules
## ###################################################################
add_executable(${PROJECT_NAME}
${${PROJECT_NAME}_SOURCES_TST}
${${PROJECT_NAME}_SOURCES})
## ###################################################################
## Link rules
## ###################################################################
qt5_use_modules(${PROJECT_NAME} Core)
qt5_use_modules(${PROJECT_NAME} Test)
target_link_libraries(${PROJECT_NAME} dtkLog)
## ###################################################################
## Test rules
## ###################################################################
add_test(dtkLoggerTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/dtkLogTest dtkLoggerTest)
add_test(dtkLoggerEnvTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/dtkLogTest dtkLoggerEnvTest)
\ No newline at end of file
/* dtkLoggerEnvTest.h ---
*
* Author: Julien Wintz
* Created: Wed Feb 13 15:45:42 2013 (+0100)
* Version:
* Last-Updated: Wed Feb 13 16:23:21 2013 (+0100)
* By: Julien Wintz
* Update #: 75
*/
/* Change Log:
*
*/
#include "dtkLoggerEnvTest.h"
#include <dtkLog/dtkLogger.h>
#include <dtkLog/dtkLogger_p.h>
// ///////////////////////////////////////////////////////////////////
// Helper categories
// ///////////////////////////////////////////////////////////////////
DTK_LOG_CATEGORY(My_Category_A, "My.Category.A")
DTK_LOG_CATEGORY(My_Category_B, "My.Category.B")
DTK_LOG_CATEGORY(My_Category_C, "My.Category.C")
// ///////////////////////////////////////////////////////////////////
// Log rules file
// ///////////////////////////////////////////////////////////////////
#define LOGRULEFILE "./myLogRules.txt"
// ///////////////////////////////////////////////////////////////////
// Helper variables
// ///////////////////////////////////////////////////////////////////
QtMessageHandler env_oldMessageHandler;
bool env_logReceived = false;
QMutex env_threadmutex;
// ///////////////////////////////////////////////////////////////////
// Helper functions
// ///////////////////////////////////////////////////////////////////
QByteArray qMyMessageFormatStringEnv(QtMsgType /*type*/, const QMessageLogContext &/*context*/, const QString &str)
{
QByteArray message;
{
message.append(qPrintable(str));
message.append('\n');
}
return message;
}
static void myCustomMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
QMutexLocker locker(&env_threadmutex);
QString logmsg = qMyMessageFormatStringEnv(type, context, msg);
if (logmsg.indexOf("My_Category") >= 0) {
env_logReceived = true;
}
else
env_oldMessageHandler(type, context, msg);
}
// ///////////////////////////////////////////////////////////////////
// Helper LogRules class
// ///////////////////////////////////////////////////////////////////
class LogRules
{
public:
LogRules(void)
{
}
void addKey(const QString &key, bool val){
_values.insert(key, (val ? "true" : "false"));
if(!_configitemEntryOrder.contains(key))
_configitemEntryOrder.append(key);
}
QByteArray array(void)
{
QString ret;
QTextStream out(&ret);
for (int a = 0; a < _configitemEntryOrder.count(); a++) {
out << _configitemEntryOrder[a] << " = " << _values.value(_configitemEntryOrder[a]) << endl;
}
out.flush();
return ret.toLatin1();
}
void clear(void)
{
_values.clear();
_configitemEntryOrder.clear();
}
private:
QMap<QString, QString> _values;
QStringList _configitemEntryOrder;
};
// ///////////////////////////////////////////////////////////////////
// Helper LogThread class
// ///////////////////////////////////////////////////////////////////
class LogThreadEnv : public QThread
{
Q_OBJECT
public:
LogThreadEnv(void) {}
protected:
void run(void);
};
void LogThreadEnv::run()
{
dtkDebug(My_Category_A) << "My_Category_A";
dtkDebug(My_Category_B) << "My_Category_B";
dtkDebug(My_Category_C) << "My_Category_C";
dtkWarning(My_Category_A) << "My_Category_A";
dtkWarning(My_Category_B) << "My_Category_B";
dtkWarning(My_Category_C) << "My_Category_C";
dtkCritical(My_Category_A) << "My_Category_A";
dtkCritical(My_Category_B) << "My_Category_B";
dtkCritical(My_Category_C) << "My_Category_C";
}
// ///////////////////////////////////////////////////////////////////
// Helper variables
// ///////////////////////////////////////////////////////////////////