2012-12-05 19:45:28 +04:00
|
|
|
/*
|
|
|
|
* Copyright (C) by Klaas Freitag <freitag@owncloud.com>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
* for more details.
|
|
|
|
*/
|
|
|
|
|
2014-07-11 02:31:24 +04:00
|
|
|
#include "logger.h"
|
2012-12-05 19:45:28 +04:00
|
|
|
|
2013-10-02 17:28:33 +04:00
|
|
|
#include <QDir>
|
|
|
|
#include <QStringList>
|
2014-10-11 18:58:47 +04:00
|
|
|
#include <QThread>
|
2015-10-20 14:22:48 +03:00
|
|
|
#include <qmetaobject.h>
|
2013-10-02 17:28:33 +04:00
|
|
|
|
2016-12-08 19:30:41 +03:00
|
|
|
#include "csync.h"
|
2017-03-31 17:13:01 +03:00
|
|
|
#include "csync_log.h"
|
2016-12-08 19:30:41 +03:00
|
|
|
|
2014-11-10 00:34:07 +03:00
|
|
|
namespace OCC {
|
2012-12-05 19:45:28 +04:00
|
|
|
|
2017-03-31 17:13:01 +03:00
|
|
|
Q_LOGGING_CATEGORY(lcCsync, "sync.csync", QtInfoMsg)
|
|
|
|
|
2015-02-14 16:21:37 +03:00
|
|
|
static void mirallLogCatcher(QtMsgType type, const QMessageLogContext &ctx, const QString &message)
|
|
|
|
{
|
2015-10-20 14:22:48 +03:00
|
|
|
auto logger = Logger::instance();
|
|
|
|
if (!logger->isNoop()) {
|
|
|
|
logger->doLog(qFormatLogMessage(type, ctx, message));
|
|
|
|
}
|
2015-02-14 16:21:37 +03:00
|
|
|
}
|
2013-10-02 17:28:33 +04:00
|
|
|
|
2017-03-31 17:13:01 +03:00
|
|
|
static void csyncLogCatcher(int verbosity,
|
|
|
|
const char *function,
|
|
|
|
const char *buffer)
|
2016-12-08 19:30:41 +03:00
|
|
|
{
|
2017-03-31 17:13:01 +03:00
|
|
|
if (verbosity <= CSYNC_LOG_PRIORITY_FATAL) {
|
|
|
|
QMessageLogger(0, 0, function, lcCsync().categoryName()).fatal("%s", buffer);
|
|
|
|
} else if (verbosity <= CSYNC_LOG_PRIORITY_CRIT) {
|
|
|
|
if (lcCsync().isCriticalEnabled())
|
|
|
|
QMessageLogger(0, 0, function, lcCsync().categoryName()).critical("%s", buffer);
|
|
|
|
} else if (verbosity <= CSYNC_LOG_PRIORITY_WARN) {
|
|
|
|
if (lcCsync().isWarningEnabled())
|
|
|
|
QMessageLogger(0, 0, function, lcCsync().categoryName()).warning("%s", buffer);
|
|
|
|
} else if (verbosity <= CSYNC_LOG_PRIORITY_INFO) {
|
|
|
|
if (lcCsync().isInfoEnabled())
|
|
|
|
QMessageLogger(0, 0, function, lcCsync().categoryName()).info("%s", buffer);
|
|
|
|
} else if (verbosity <= CSYNC_LOG_PRIORITY_NOTSET) {
|
|
|
|
if (lcCsync().isDebugEnabled())
|
|
|
|
QMessageLogger(0, 0, function, lcCsync().categoryName()).debug("%s", buffer);
|
|
|
|
}
|
2016-12-08 19:30:41 +03:00
|
|
|
}
|
|
|
|
|
2014-05-26 15:01:29 +04:00
|
|
|
Logger *Logger::instance()
|
2012-12-05 19:45:28 +04:00
|
|
|
{
|
2014-05-26 15:01:29 +04:00
|
|
|
static Logger log;
|
|
|
|
return &log;
|
2012-12-05 19:45:28 +04:00
|
|
|
}
|
|
|
|
|
2014-05-26 15:01:29 +04:00
|
|
|
Logger::Logger(QObject *parent)
|
|
|
|
: QObject(parent)
|
2017-05-09 18:04:04 +03:00
|
|
|
, _showTime(true)
|
|
|
|
, _logWindowActivated(false)
|
|
|
|
, _doFileFlush(false)
|
|
|
|
, _logExpire(0)
|
|
|
|
, _logDebug(false)
|
2012-12-05 19:45:28 +04:00
|
|
|
{
|
2017-03-28 16:56:07 +03:00
|
|
|
qSetMessagePattern("%{time MM-dd hh:mm:ss:zzz} [ %{type} %{category} ]%{if-debug}\t[ %{function} ]%{endif}:\t%{message}");
|
|
|
|
#ifndef NO_MSG_HANDLER
|
2014-05-26 15:01:29 +04:00
|
|
|
qInstallMessageHandler(mirallLogCatcher);
|
2015-02-19 18:49:39 +03:00
|
|
|
#else
|
|
|
|
Q_UNUSED(mirallLogCatcher)
|
2017-03-31 17:13:01 +03:00
|
|
|
// Always get logging from csync in that case.
|
|
|
|
csync_set_log_level(11);
|
2015-02-19 18:49:39 +03:00
|
|
|
#endif
|
2017-03-31 17:13:01 +03:00
|
|
|
|
|
|
|
// Setup CSYNC logging to forward to our own logger
|
|
|
|
csync_set_log_callback(csyncLogCatcher);
|
2012-12-05 19:45:28 +04:00
|
|
|
}
|
|
|
|
|
2014-05-26 15:01:29 +04:00
|
|
|
Logger::~Logger()
|
|
|
|
{
|
2015-02-19 18:49:39 +03:00
|
|
|
#ifndef NO_MSG_HANDLER
|
2014-05-26 15:01:29 +04:00
|
|
|
qInstallMessageHandler(0);
|
2015-02-19 18:49:39 +03:00
|
|
|
#endif
|
2012-12-05 19:45:28 +04:00
|
|
|
}
|
|
|
|
|
2014-05-26 15:01:29 +04:00
|
|
|
|
2013-08-07 16:58:56 +04:00
|
|
|
void Logger::postGuiLog(const QString &title, const QString &message)
|
|
|
|
{
|
|
|
|
emit guiLog(title, message);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Logger::postOptionalGuiLog(const QString &title, const QString &message)
|
|
|
|
{
|
|
|
|
emit optionalGuiLog(title, message);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Logger::postGuiMessage(const QString &title, const QString &message)
|
|
|
|
{
|
2013-10-02 17:55:15 +04:00
|
|
|
emit guiMessage(title, message);
|
2013-08-07 16:58:56 +04:00
|
|
|
}
|
|
|
|
|
2012-12-05 19:45:28 +04:00
|
|
|
void Logger::log(Log log)
|
|
|
|
{
|
|
|
|
QString msg;
|
|
|
|
if (_showTime) {
|
|
|
|
msg = log.timeStamp.toString(QLatin1String("MM-dd hh:mm:ss:zzz")) + QLatin1Char(' ');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (log.source == Log::CSync) {
|
|
|
|
// msg += "csync - ";
|
|
|
|
} else {
|
|
|
|
// msg += "ownCloud - ";
|
|
|
|
}
|
2014-10-11 18:58:47 +04:00
|
|
|
msg += QString().sprintf("%p ", (void *)QThread::currentThread());
|
2012-12-05 19:45:28 +04:00
|
|
|
msg += log.message;
|
|
|
|
// _logs.append(log);
|
|
|
|
// std::cout << qPrintable(log.message) << std::endl;
|
2013-10-02 17:28:33 +04:00
|
|
|
|
2015-02-14 16:21:37 +03:00
|
|
|
doLog(msg);
|
|
|
|
}
|
|
|
|
|
2015-10-20 14:22:48 +03:00
|
|
|
/**
|
|
|
|
* Returns true if doLog does nothing and need not to be called
|
|
|
|
*/
|
|
|
|
bool Logger::isNoop() const
|
|
|
|
{
|
|
|
|
QMutexLocker lock(const_cast<QMutex *>(&_mutex));
|
2016-12-08 19:30:41 +03:00
|
|
|
return !_logstream && !_logWindowActivated;
|
2015-10-20 14:22:48 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-02-14 16:21:37 +03:00
|
|
|
void Logger::doLog(const QString &msg)
|
|
|
|
{
|
2013-10-03 16:21:45 +04:00
|
|
|
{
|
|
|
|
QMutexLocker lock(&_mutex);
|
|
|
|
if (_logstream) {
|
|
|
|
(*_logstream) << msg << endl;
|
|
|
|
if (_doFileFlush)
|
|
|
|
_logstream->flush();
|
|
|
|
}
|
2013-10-02 17:28:33 +04:00
|
|
|
}
|
2016-12-08 19:30:41 +03:00
|
|
|
emit logWindowLog(msg);
|
2012-12-05 19:45:28 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void Logger::mirallLog(const QString &message)
|
|
|
|
{
|
|
|
|
Log log_;
|
2014-11-10 00:34:07 +03:00
|
|
|
log_.source = Log::Occ;
|
2017-09-25 12:49:11 +03:00
|
|
|
log_.timeStamp = QDateTime::currentDateTimeUtc();
|
2012-12-05 19:45:28 +04:00
|
|
|
log_.message = message;
|
|
|
|
|
|
|
|
Logger::instance()->log(log_);
|
|
|
|
}
|
|
|
|
|
2016-12-08 19:30:41 +03:00
|
|
|
void Logger::setLogWindowActivated(bool activated)
|
|
|
|
{
|
|
|
|
QMutexLocker locker(&_mutex);
|
|
|
|
|
|
|
|
csync_set_log_level(11);
|
|
|
|
|
|
|
|
_logWindowActivated = activated;
|
|
|
|
}
|
|
|
|
|
2013-10-02 17:28:33 +04:00
|
|
|
void Logger::setLogFile(const QString &name)
|
|
|
|
{
|
2013-10-03 16:21:45 +04:00
|
|
|
QMutexLocker locker(&_mutex);
|
|
|
|
|
2016-12-08 19:30:41 +03:00
|
|
|
csync_set_log_level(11);
|
2017-05-17 11:55:42 +03:00
|
|
|
|
2013-10-02 17:28:33 +04:00
|
|
|
if (_logstream) {
|
2013-10-03 16:21:45 +04:00
|
|
|
_logstream.reset(0);
|
2013-10-02 17:28:33 +04:00
|
|
|
_logFile.close();
|
|
|
|
}
|
|
|
|
|
2013-10-02 17:55:15 +04:00
|
|
|
if (name.isEmpty()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-10-02 17:28:33 +04:00
|
|
|
bool openSucceeded = false;
|
|
|
|
if (name == QLatin1String("-")) {
|
|
|
|
openSucceeded = _logFile.open(1, QIODevice::WriteOnly);
|
|
|
|
} else {
|
|
|
|
_logFile.setFileName(name);
|
|
|
|
openSucceeded = _logFile.open(QIODevice::WriteOnly);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!openSucceeded) {
|
2013-10-03 16:21:45 +04:00
|
|
|
locker.unlock(); // Just in case postGuiMessage has a qDebug()
|
2013-10-02 17:28:33 +04:00
|
|
|
postGuiMessage(tr("Error"),
|
|
|
|
QString(tr("<nobr>File '%1'<br/>cannot be opened for writing.<br/><br/>"
|
|
|
|
"The log output can <b>not</b> be saved!</nobr>"))
|
|
|
|
.arg(name));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
_logstream.reset(new QTextStream(&_logFile));
|
|
|
|
}
|
|
|
|
|
|
|
|
void Logger::setLogExpire(int expire)
|
|
|
|
{
|
|
|
|
_logExpire = expire;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Logger::setLogDir(const QString &dir)
|
|
|
|
{
|
|
|
|
_logDirectory = dir;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Logger::setLogFlush(bool flush)
|
|
|
|
{
|
|
|
|
_doFileFlush = flush;
|
|
|
|
}
|
|
|
|
|
2017-05-09 18:04:04 +03:00
|
|
|
void Logger::setLogDebug(bool debug)
|
|
|
|
{
|
|
|
|
QLoggingCategory::setFilterRules(debug ? QStringLiteral("qt.*=true\n*.debug=true") : QString());
|
|
|
|
_logDebug = debug;
|
|
|
|
}
|
|
|
|
|
2013-10-02 17:28:33 +04:00
|
|
|
void Logger::enterNextLogFile()
|
|
|
|
{
|
|
|
|
if (!_logDirectory.isEmpty()) {
|
|
|
|
QDir dir(_logDirectory);
|
|
|
|
if (!dir.exists()) {
|
|
|
|
dir.mkpath(".");
|
|
|
|
}
|
|
|
|
|
2015-10-05 06:20:09 +03:00
|
|
|
// Find out what is the file with the highest number if any
|
2013-10-02 17:28:33 +04:00
|
|
|
QStringList files = dir.entryList(QStringList("owncloud.log.*"),
|
|
|
|
QDir::Files);
|
|
|
|
QRegExp rx("owncloud.log.(\\d+)");
|
|
|
|
uint maxNumber = 0;
|
2017-09-25 12:49:11 +03:00
|
|
|
QDateTime now = QDateTime::currentDateTimeUtc();
|
2013-10-02 17:28:33 +04:00
|
|
|
foreach (const QString &s, files) {
|
|
|
|
if (rx.exactMatch(s)) {
|
|
|
|
maxNumber = qMax(maxNumber, rx.cap(1).toUInt());
|
|
|
|
if (_logExpire > 0) {
|
|
|
|
QFileInfo fileInfo = dir.absoluteFilePath(s);
|
|
|
|
if (fileInfo.lastModified().addSecs(60 * 60 * _logExpire) < now) {
|
|
|
|
dir.remove(s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QString filename = _logDirectory + "/owncloud.log." + QString::number(maxNumber + 1);
|
|
|
|
setLogFile(filename);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-10 00:34:07 +03:00
|
|
|
} // namespace OCC
|