diff --git a/src/csync/csync.h b/src/csync/csync.h index 3baf87587f46c..2b46ce68f5926 100644 --- a/src/csync/csync.h +++ b/src/csync/csync.h @@ -32,20 +32,23 @@ #ifndef _CSYNC_H #define _CSYNC_H -#include "std/c_private.h" -#include "ocsynclib.h" - -#include +#include +#include #include +#include #include -#include #include #include -#include + +#include "ocsynclib.h" +#include "config_csync.h" +#include "std/c_private.h" #include "common/remotepermissions.h" namespace OCC { +Q_DECLARE_LOGGING_CATEGORY(lcPermanentLog) + class SyncJournalFileRecord; namespace EncryptionStatusEnums { diff --git a/src/gui/application.cpp b/src/gui/application.cpp index 48fb06682f109..2a3c972e0fd5c 100644 --- a/src/gui/application.cpp +++ b/src/gui/application.cpp @@ -672,6 +672,10 @@ void Application::setupLogging() #endif logger->enterNextLogFile(); + { + QDir logFolder{logger->logDir()}; + logger->setPermanentDeleteLogFile(logFolder.filePath("permanent_delete.log")); + } qCInfo(lcApplication) << "##################" << _theme->appName() << "locale:" << QLocale::system().name() diff --git a/src/libsync/discovery.cpp b/src/libsync/discovery.cpp index f93c26b0488d4..038d4d4537869 100644 --- a/src/libsync/discovery.cpp +++ b/src/libsync/discovery.cpp @@ -512,6 +512,23 @@ void ProcessDirectoryJob::processFile(PathTuple path, item->_previousSize = dbEntry._fileSize; item->_previousModtime = dbEntry._modtime; + QDebug deleteLogger{&item->_discoveryResult}; + deleteLogger.nospace() << "Processing " << path._original + << " | (db/local/remote)" + << " | valid: " << dbEntry.isValid() << "/" << hasLocal << "/" << hasServer + << " | mtime: " << dbEntry._modtime << "/" << localEntry.modtime << "/" << serverEntry.modtime + << " | size: " << dbEntry._fileSize << "/" << localEntry.size << "/" << serverEntry.size + << " | etag: " << dbEntry._etag << "//" << serverEntry.etag + << " | checksum: " << dbEntry._checksumHeader << "//" << serverEntry.checksumHeader + << " | perm: " << dbEntry._remotePerm << "//" << serverEntry.remotePerm + << " | fileid: " << dbEntry._fileId << "//" << serverEntry.fileId + << " | type: " << dbEntry._type << "/" << localEntry.type << "/" << (serverEntry.isDirectory ? ItemTypeDirectory : ItemTypeFile) + << " | e2ee: " << dbEntry.isE2eEncrypted() << "/" << serverEntry.isE2eEncrypted() + << " | e2eeMangledName: " << dbEntry.e2eMangledName() << "/" << serverEntry.e2eMangledName + << " | file lock: " << localFileIsLocked << "//" << serverFileIsLocked + << " | file lock type: " << localFileLockType << "//" << serverFileLockType + << " | metadata missing: /" << localEntry.isMetadataMissing << '/'; + if (dbEntry._modtime == localEntry.modtime && dbEntry._type == ItemTypeVirtualFile && localEntry.type == ItemTypeFile) { item->_type = ItemTypeFile; qCInfo(lcDisco) << "Changing item type from virtual to normal file" << item->_file; diff --git a/src/libsync/logger.cpp b/src/libsync/logger.cpp index 2bfaa8aaf6147..1a985ddfae9c3 100644 --- a/src/libsync/logger.cpp +++ b/src/libsync/logger.cpp @@ -68,6 +68,8 @@ static bool compressLog(const QString &originalName, const QString &targetName) namespace OCC { +Q_LOGGING_CATEGORY(lcPermanentLog, "nextcloud.log.permanent") + Logger *Logger::instance() { static Logger log; @@ -163,6 +165,10 @@ void Logger::doLog(QtMsgType type, const QMessageLogContext &ctx, const QString if (_doFileFlush) _logstream->flush(); } + if (_permanentDeleteLogStream && strcmp(ctx.category, "nextcloud.log.permanent") == 0) { + (*_permanentDeleteLogStream) << msg << "\n"; + _permanentDeleteLogStream->flush(); + } if (type == QtFatalMsg) { closeNoLock(); #if defined(Q_OS_WIN) @@ -197,6 +203,12 @@ void Logger::setLogFile(const QString &name) setLogFileNoLock(name); } +void Logger::setPermanentDeleteLogFile(const QString &name) +{ + QMutexLocker locker(&_mutex); + setPermanentDeleteLogFileNoLock(name); +} + void Logger::setLogExpire(int expire) { _logExpire = expire; @@ -362,6 +374,37 @@ void Logger::setLogFileNoLock(const QString &name) _logstream->setCodec(QTextCodec::codecForName("UTF-8")); } +void Logger::setPermanentDeleteLogFileNoLock(const QString &name) +{ + if (_permanentDeleteLogStream) { + _permanentDeleteLogStream.reset(nullptr); + _permanentDeleteLogFile.close(); + } + + if (name.isEmpty()) { + return; + } + + bool openSucceeded = false; + if (name == QLatin1String("-")) { + openSucceeded = _permanentDeleteLogFile.open(stdout, QIODevice::WriteOnly); + } else { + _permanentDeleteLogFile.setFileName(name); + openSucceeded = _permanentDeleteLogFile.open(QIODevice::WriteOnly); + } + + if (!openSucceeded) { + postGuiMessage(tr("Error"), + QString(tr("File \"%1\"
cannot be opened for writing.

" + "The log output cannot be saved!
")) + .arg(name)); + return; + } + + _permanentDeleteLogStream.reset(new QTextStream(&_permanentDeleteLogFile)); + _permanentDeleteLogStream->setCodec(QTextCodec::codecForName("UTF-8")); +} + void Logger::enterNextLogFile() { QMutexLocker locker(&_mutex); diff --git a/src/libsync/logger.h b/src/libsync/logger.h index bfcb2989d5db0..c3c5bcd9ec47c 100644 --- a/src/libsync/logger.h +++ b/src/libsync/logger.h @@ -47,6 +47,8 @@ class OWNCLOUDSYNC_EXPORT Logger : public QObject QString logFile() const; void setLogFile(const QString &name); + void setPermanentDeleteLogFile(const QString &name); + void setLogExpire(int expire); QString logDir() const; @@ -98,6 +100,7 @@ public slots: void dumpCrashLog(); void enterNextLogFileNoLock(); void setLogFileNoLock(const QString &name); + void setPermanentDeleteLogFileNoLock(const QString &name); QFile _logFile; bool _doFileFlush = false; @@ -110,6 +113,8 @@ public slots: QSet _logRules; QVector _crashLog; int _crashLogIndex = 0; + QFile _permanentDeleteLogFile; + QScopedPointer _permanentDeleteLogStream; }; } // namespace OCC diff --git a/src/libsync/propagateremotedelete.cpp b/src/libsync/propagateremotedelete.cpp index 7bc5be9528889..708b0f2ed2a0a 100644 --- a/src/libsync/propagateremotedelete.cpp +++ b/src/libsync/propagateremotedelete.cpp @@ -29,6 +29,7 @@ Q_LOGGING_CATEGORY(lcPropagateRemoteDelete, "nextcloud.sync.propagator.remotedel void PropagateRemoteDelete::start() { qCInfo(lcPropagateRemoteDelete) << "Start propagate remote delete job for" << _item->_file; + qCInfo(lcPermanentLog) << "delete" << _item->_file << _item->_discoveryResult; if (propagator()->_abortRequested) return; diff --git a/src/libsync/propagatorjobs.cpp b/src/libsync/propagatorjobs.cpp index 37506b6607c54..6cfb85895b944 100644 --- a/src/libsync/propagatorjobs.cpp +++ b/src/libsync/propagatorjobs.cpp @@ -101,6 +101,7 @@ bool PropagateLocalRemove::removeRecursively(const QString &path) void PropagateLocalRemove::start() { qCInfo(lcPropagateLocalRemove) << "Start propagate local remove job"; + qCInfo(lcPermanentLog) << "delete" << _item->_file << _item->_discoveryResult; _moveToTrash = propagator()->syncOptions()._moveFilesToTrash; diff --git a/src/libsync/syncfileitem.h b/src/libsync/syncfileitem.h index 3f6a52898611d..610dd71bc0ec6 100644 --- a/src/libsync/syncfileitem.h +++ b/src/libsync/syncfileitem.h @@ -338,6 +338,8 @@ class OWNCLOUDSYNC_EXPORT SyncFileItem bool _isAnyInvalidCharChild = false; bool _isAnyCaseClashChild = false; + + QString _discoveryResult; }; inline bool operator<(const SyncFileItemPtr &item1, const SyncFileItemPtr &item2)