diff options
author | Christian Kandeler <christian.kandeler@digia.com> | 2014-01-09 17:50:40 +0100 |
---|---|---|
committer | Joerg Bornemann <joerg.bornemann@digia.com> | 2014-01-10 18:11:22 +0100 |
commit | 81af9acaa295a574c1cb5e6714725197dac7f530 (patch) | |
tree | cc8c94467f49a7d267e5249f624874feecc7eed4 /src/lib/corelib/logging | |
parent | 2fe25eb3f20ffb4e58cb559f2bcb9950c963290a (diff) |
Move Qt profile setup into a dedicated library.
Otherwise all changes to the implementation will have to be duplicated
in IDEs.
Change-Id: I61e6d4fa1ee9b724eb5d9de9f233dc915a6c8bc3
Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
Diffstat (limited to 'src/lib/corelib/logging')
-rw-r--r-- | src/lib/corelib/logging/ilogsink.cpp | 118 | ||||
-rw-r--r-- | src/lib/corelib/logging/ilogsink.h | 81 | ||||
-rw-r--r-- | src/lib/corelib/logging/logger.cpp | 271 | ||||
-rw-r--r-- | src/lib/corelib/logging/logger.h | 137 | ||||
-rw-r--r-- | src/lib/corelib/logging/logging.pri | 14 | ||||
-rw-r--r-- | src/lib/corelib/logging/translator.h | 47 |
6 files changed, 668 insertions, 0 deletions
diff --git a/src/lib/corelib/logging/ilogsink.cpp b/src/lib/corelib/logging/ilogsink.cpp new file mode 100644 index 000000000..118fdf106 --- /dev/null +++ b/src/lib/corelib/logging/ilogsink.cpp @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Build Suite. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ +#include "ilogsink.h" + +#include <tools/error.h> + +#include <QByteArray> +#include <QMutex> + +namespace qbs { + +QString logLevelTag(LoggerLevel level) +{ + if (level == LoggerInfo) + return QByteArray(); + QString str = logLevelName(level).toUpper(); + if (!str.isEmpty()) + str.append(QLatin1String(": ")); + return str; +} + +QString logLevelName(LoggerLevel level) +{ + switch (level) { + case qbs::LoggerError: + return QLatin1String("error"); + case qbs::LoggerWarning: + return QLatin1String("warning"); + case qbs::LoggerInfo: + return QLatin1String("info"); + case qbs::LoggerDebug: + return QLatin1String("debug"); + case qbs::LoggerTrace: + return QLatin1String("trace"); + default: + break; + } + return QString(); +} + +class ILogSink::ILogSinkPrivate +{ +public: + LoggerLevel logLevel; + QMutex mutex; +}; + +ILogSink::ILogSink() : d(new ILogSinkPrivate) +{ + d->logLevel = defaultLogLevel(); +} + +ILogSink::~ILogSink() +{ + delete d; +} + +void ILogSink::setLogLevel(LoggerLevel level) +{ + d->logLevel = level; +} + +LoggerLevel ILogSink::logLevel() const +{ + return d->logLevel; +} + +void ILogSink::printWarning(const ErrorInfo &warning) +{ + if (willPrint(LoggerWarning)) { + d->mutex.lock(); + doPrintWarning(warning); + d->mutex.unlock(); + } +} + +void ILogSink::printMessage(LoggerLevel level, const QString &message, const QString &tag, + bool force) +{ + if (force || willPrint(level)) { + d->mutex.lock(); + doPrintMessage(level, message, tag); + d->mutex.unlock(); + } +} + +void ILogSink::doPrintWarning(const ErrorInfo &warning) +{ + doPrintMessage(LoggerWarning, warning.toString(), QString()); +} + +} // namespace qbs diff --git a/src/lib/corelib/logging/ilogsink.h b/src/lib/corelib/logging/ilogsink.h new file mode 100644 index 000000000..9c263b52d --- /dev/null +++ b/src/lib/corelib/logging/ilogsink.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Build Suite. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ +#ifndef QBS_ILOGSINK_H +#define QBS_ILOGSINK_H + +#include "../tools/qbs_export.h" + +#include <QString> + +namespace qbs { +class ErrorInfo; + +enum LoggerLevel +{ + LoggerMinLevel, + LoggerError = LoggerMinLevel, + LoggerWarning, + LoggerInfo, + LoggerDebug, + LoggerTrace, + LoggerMaxLevel = LoggerTrace +}; + +inline LoggerLevel defaultLogLevel() { return LoggerInfo; } +QBS_EXPORT QString logLevelTag(LoggerLevel level); +QBS_EXPORT QString logLevelName(LoggerLevel level); + +class QBS_EXPORT ILogSink +{ + Q_DISABLE_COPY(ILogSink) +public: + ILogSink(); + virtual ~ILogSink(); + + void setLogLevel(LoggerLevel level); + LoggerLevel logLevel() const; + + bool willPrint(LoggerLevel level) const { return level <= logLevel(); } + + void printWarning(const ErrorInfo &warning); + void printMessage(LoggerLevel level, const QString &message, + const QString &tag = QString(), bool force = false); + +private: + virtual void doPrintWarning(const ErrorInfo &warning); + virtual void doPrintMessage(LoggerLevel level, const QString &message, + const QString &tag) = 0; + + class ILogSinkPrivate; + ILogSinkPrivate * const d; +}; + +} // namespace qbs + +#endif // Include guard diff --git a/src/lib/corelib/logging/logger.cpp b/src/lib/corelib/logging/logger.cpp new file mode 100644 index 000000000..9f7a19c01 --- /dev/null +++ b/src/lib/corelib/logging/logger.cpp @@ -0,0 +1,271 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Build Suite. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#if defined(_MSC_VER) && _MSC_VER > 0 +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "logger.h" + +#include <QByteArray> +#include <QElapsedTimer> +#include <QMutex> +#include <QSet> +#include <QVariant> + +#include <cstdarg> +#include <stdio.h> + +namespace qbs { +namespace Internal { + +LogWriter::LogWriter(ILogSink *logSink, LoggerLevel level, bool force) + : m_logSink(logSink), m_level(level), m_force(force) +{} + +LogWriter::LogWriter(const LogWriter &other) + : m_logSink(other.m_logSink) + , m_level(other.m_level) + , m_message(other.m_message) + , m_tag(other.m_tag) + , m_force(other.m_force) +{ + other.m_message.clear(); +} + +LogWriter::~LogWriter() +{ + if (!m_message.isEmpty()) + m_logSink->printMessage(m_level, m_message, m_tag, m_force); +} + +const LogWriter &LogWriter::operator=(const LogWriter &other) +{ + m_logSink = other.m_logSink; + m_level = other.m_level; + m_message = other.m_message; + m_tag = other.m_tag; + m_force = other.m_force; + other.m_message.clear(); + return *this; +} + +void LogWriter::write(char c) +{ + write(QLatin1Char(c)); +} + +void LogWriter::write(const char *str) +{ + write(QLatin1String(str)); +} + +void LogWriter::write(const QChar &c) +{ + if (m_force || m_logSink->logLevel() >= m_level) + m_message.append(c); +} + +void LogWriter::write(const QString &message) +{ + if (m_force || m_logSink->logLevel() >= m_level) + m_message += message; +} + +void LogWriter::setMessageTag(const QString &tag) +{ + m_tag = tag; +} + +LogWriter operator<<(LogWriter w, const char *str) +{ + w.write(str); + return w; +} + +LogWriter operator<<(LogWriter w, const QByteArray &byteArray) +{ + w.write(byteArray.data()); + return w; +} + +LogWriter operator<<(LogWriter w, const QString &str) +{ + w.write(str); + return w; +} + +LogWriter operator<<(LogWriter w, const QStringList &strList) +{ + w.write('['); + for (int i = 0; i < strList.size(); ++i) { + w.write(strList.at(i)); + if (i != strList.size() - 1) + w.write(QLatin1String(", ")); + } + w.write(']'); + return w; +} + +LogWriter operator<<(LogWriter w, const QSet<QString> &strSet) +{ + bool firstLoop = true; + w.write('('); + foreach (const QString &str, strSet) { + if (firstLoop) + firstLoop = false; + else + w.write(QLatin1String(", ")); + w.write(str); + } + w.write(')'); + return w; +} + +LogWriter operator<<(LogWriter w, const QVariant &variant) +{ + QString str = variant.typeName() + QLatin1Char('('); + if (variant.type() == QVariant::List) { + bool firstLoop = true; + foreach (const QVariant &item, variant.toList()) { + str += item.toString(); + if (firstLoop) + firstLoop = false; + else + str += QLatin1String(", "); + } + } else { + str += variant.toString(); + } + str += QLatin1Char(')'); + w.write(str); + return w; +} + +LogWriter operator<<(LogWriter w, int n) +{ + return w << QString::number(n); +} + +LogWriter operator<<(LogWriter w, qint64 n) +{ + return w << QString::number(n); +} + +LogWriter operator<<(LogWriter w, bool b) +{ + return w << QString(QLatin1String(b ? "true" : "false")); +} + +LogWriter operator<<(LogWriter w, const MessageTag &tag) +{ + w.setMessageTag(tag.tag()); + return w; +} + +Logger::Logger(ILogSink *logger) : m_logSink(logger) +{ +} + +bool Logger::debugEnabled() const +{ + return m_logSink->willPrint(LoggerDebug); +} + +bool Logger::traceEnabled() const +{ + return m_logSink->willPrint(LoggerTrace); +} + +LogWriter Logger::qbsLog(LoggerLevel level, bool force) const +{ + return LogWriter(m_logSink, level, force); +} + + +class TimedActivityLogger::TimedActivityLoggerPrivate +{ +public: + Logger logger; + QString prefix; + QString activity; + LoggerLevel logLevel; + QElapsedTimer timer; + bool alwaysLog; +}; + +TimedActivityLogger::TimedActivityLogger(const Logger &logger, const QString &activity, + const QString &prefix, LoggerLevel logLevel, bool alwaysLog) + : d(0) +{ + if (!alwaysLog && !logger.logSink()->willPrint(logLevel)) + return; + d = new TimedActivityLoggerPrivate; + d->logger = logger; + d->prefix = prefix; + d->activity = activity; + d->logLevel = logLevel; + d->alwaysLog = alwaysLog; + d->logger.qbsLog(logLevel, alwaysLog) << QString::fromLocal8Bit("%1Starting activity '%2'.") + .arg(prefix, activity); + d->timer.start(); +} + +void TimedActivityLogger::finishActivity() +{ + if (!d) + return; + qint64 ms = d->timer.elapsed(); + qint64 s = ms/1000; + ms -= s*1000; + qint64 m = s/60; + s -= m*60; + const qint64 h = m/60; + m -= h*60; + QString timeString = QString::fromLocal8Bit("%1ms").arg(ms); + if (h || m || s) + timeString.prepend(QString::fromLocal8Bit("%1s, ").arg(s)); + if (h || m) + timeString.prepend(QString::fromLocal8Bit("%1m, ").arg(m)); + if (h) + timeString.prepend(QString::fromLocal8Bit("%1h, ").arg(h)); + d->logger.qbsLog(d->logLevel, d->alwaysLog) + << QString::fromLocal8Bit("%1Activity '%2' took %3.") + .arg(d->prefix, d->activity, timeString); + delete d; + d = 0; +} + +TimedActivityLogger::~TimedActivityLogger() +{ + finishActivity(); +} + +} // namespace Internal +} // namespace qbs diff --git a/src/lib/corelib/logging/logger.h b/src/lib/corelib/logging/logger.h new file mode 100644 index 000000000..1ab11144d --- /dev/null +++ b/src/lib/corelib/logging/logger.h @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Build Suite. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef QBS_LOGGER_H +#define QBS_LOGGER_H + +#include "ilogsink.h" + +#include <QByteArray> +#include <QString> +#include <QStringList> + +QT_BEGIN_NAMESPACE +class QVariant; +QT_END_NAMESPACE + +namespace qbs { +namespace Internal { + +// Note that while these classes are not part of the API, we export some stuff for use by +// our command line tools for the sake of a uniform logging approach. + +class QBS_EXPORT LogWriter +{ +public: + LogWriter(ILogSink *logSink, LoggerLevel level, bool force = false); + + // log writer has move semantics and the last instance of + // a << chain prints the accumulated data + LogWriter(const LogWriter &other); + ~LogWriter(); + const LogWriter &operator=(const LogWriter &other); + + void write(char c); + void write(const char *str); + void write(const QChar &c); + void write(const QString &message); + + void setMessageTag(const QString &tag); + +private: + ILogSink *m_logSink; + LoggerLevel m_level; + mutable QString m_message; + QString m_tag; + bool m_force; +}; + +class QBS_EXPORT MessageTag +{ +public: + explicit MessageTag(const QString &tag) : m_tag(tag) {} + + const QString &tag() const { return m_tag; } + +private: + QString m_tag; +}; + +QBS_EXPORT LogWriter operator<<(LogWriter w, const char *str); +QBS_EXPORT LogWriter operator<<(LogWriter w, const QByteArray &byteArray); +QBS_EXPORT LogWriter operator<<(LogWriter w, const QString &str); +QBS_EXPORT LogWriter operator<<(LogWriter w, const QStringList &strList); +QBS_EXPORT LogWriter operator<<(LogWriter w, const QSet<QString> &strSet); +QBS_EXPORT LogWriter operator<<(LogWriter w, const QVariant &variant); +QBS_EXPORT LogWriter operator<<(LogWriter w, int n); +QBS_EXPORT LogWriter operator<<(LogWriter w, qint64 n); +QBS_EXPORT LogWriter operator<<(LogWriter w, bool b); +QBS_EXPORT LogWriter operator<<(LogWriter w, const MessageTag &tag); + +class QBS_EXPORT Logger +{ +public: + Logger(ILogSink *logSink = 0); + + ILogSink *logSink() const { return m_logSink; } + + bool debugEnabled() const; + bool traceEnabled() const; + + void printWarning(const ErrorInfo &warning) { logSink()->printWarning(warning); } + + LogWriter qbsLog(LoggerLevel level, bool force = false) const; + LogWriter qbsWarning() const { return qbsLog(LoggerWarning); } + LogWriter qbsInfo() const { return qbsLog(LoggerInfo); } + LogWriter qbsDebug() const { return qbsLog(LoggerDebug); } + LogWriter qbsTrace() const { return qbsLog(LoggerTrace); } + +private: + ILogSink *m_logSink; +}; + + +class TimedActivityLogger +{ +public: + TimedActivityLogger(const Logger &logger, const QString &activity, + const QString &prefix = QString(), LoggerLevel logLevel = LoggerDebug, + bool alwaysLog = false); + void finishActivity(); + ~TimedActivityLogger(); + +private: + class TimedActivityLoggerPrivate; + TimedActivityLoggerPrivate *d; +}; + +} // namespace Internal +} // namespace qbs + +#endif // QBS_LOGGER_H diff --git a/src/lib/corelib/logging/logging.pri b/src/lib/corelib/logging/logging.pri new file mode 100644 index 000000000..8c0367779 --- /dev/null +++ b/src/lib/corelib/logging/logging.pri @@ -0,0 +1,14 @@ +HEADERS += \ + $$PWD/logger.h \ + $$PWD/translator.h \ + $$PWD/ilogsink.h + +SOURCES += \ + $$PWD/logger.cpp \ + $$PWD/ilogsink.cpp + +!qbs_no_dev_install { + logging_headers.files = $$PWD/ilogsink.h + logging_headers.path = $${QBS_INSTALL_PREFIX}/include/qbs/logging + INSTALLS += logging_headers +} diff --git a/src/lib/corelib/logging/translator.h b/src/lib/corelib/logging/translator.h new file mode 100644 index 000000000..5c1f5304b --- /dev/null +++ b/src/lib/corelib/logging/translator.h @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Build Suite. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ +#ifndef QBS_TRANSLATOR_H +#define QBS_TRANSLATOR_H + +#include <tools/qbs_export.h> + +#include <QCoreApplication> + +namespace qbs { +namespace Internal { + +class QBS_EXPORT Tr // Name intended to be short. Exported for use by command line tools. +{ + Q_DECLARE_TR_FUNCTIONS(Qbs) +}; + +} // namespace Internal +} // namespace qbs + +#endif // QBS_TRANSLATOR_H |