File indexing completed on 2025-01-05 04:47:05

0001 /***************************************************************************
0002  *   SPDX-FileCopyrightText: 2006 Tobias Koenig <tokoe@kde.org>            *
0003  *                                                                         *
0004  *   SPDX-License-Identifier: LGPL-2.0-or-later                            *
0005  ***************************************************************************/
0006 #include "tracer.h"
0007 
0008 #include <QSettings>
0009 #include <QString>
0010 
0011 #include "traceradaptor.h"
0012 
0013 #include "akonadiserver_debug.h"
0014 #include "dbustracer.h"
0015 #include "filetracer.h"
0016 
0017 #include "private/standarddirs_p.h"
0018 
0019 // #define DEFAULT_TRACER QLatin1StringView( "dbus" )
0020 #define DEFAULT_TRACER QStringLiteral("null")
0021 
0022 using namespace Akonadi;
0023 using namespace Akonadi::Server;
0024 
0025 Tracer::Tracer()
0026     : mSettings(std::make_unique<QSettings>(Akonadi::StandardDirs::serverConfigFile(), QSettings::IniFormat))
0027 {
0028     activateTracer(currentTracer());
0029 
0030     new TracerAdaptor(this);
0031 
0032     QDBusConnection::sessionBus().registerObject(QStringLiteral("/tracing"), this, QDBusConnection::ExportAdaptors);
0033 }
0034 
0035 Tracer::~Tracer() = default;
0036 
0037 void Tracer::beginConnection(const QString &identifier, const QString &msg)
0038 {
0039     QMutexLocker locker(&mMutex);
0040     if (mTracerBackend) {
0041         mTracerBackend->beginConnection(identifier, msg);
0042     }
0043 }
0044 
0045 void Tracer::endConnection(const QString &identifier, const QString &msg)
0046 {
0047     QMutexLocker locker(&mMutex);
0048     if (mTracerBackend) {
0049         mTracerBackend->endConnection(identifier, msg);
0050     }
0051 }
0052 
0053 void Tracer::connectionInput(const QString &identifier, const QByteArray &msg)
0054 {
0055     QMutexLocker locker(&mMutex);
0056     if (mTracerBackend) {
0057         mTracerBackend->connectionInput(identifier, msg);
0058     }
0059 }
0060 
0061 void Akonadi::Server::Tracer::connectionInput(const QString &identifier, qint64 tag, const Protocol::CommandPtr &cmd)
0062 {
0063     QMutexLocker locker(&mMutex);
0064     if (mTracerBackend) {
0065         if (mTracerBackend->connectionFormat() == TracerInterface::Json) {
0066             QJsonObject json;
0067             json[QStringLiteral("tag")] = tag;
0068             Akonadi::Protocol::toJson(cmd.data(), json);
0069 
0070             QJsonDocument doc(json);
0071 
0072             mTracerBackend->connectionInput(identifier, doc.toJson(QJsonDocument::Indented));
0073         } else {
0074             mTracerBackend->connectionInput(identifier, QByteArray::number(tag) + ' ' + Protocol::debugString(cmd).toUtf8());
0075         }
0076     }
0077 }
0078 
0079 void Tracer::connectionOutput(const QString &identifier, const QByteArray &msg)
0080 {
0081     QMutexLocker locker(&mMutex);
0082     if (mTracerBackend) {
0083         mTracerBackend->connectionOutput(identifier, msg);
0084     }
0085 }
0086 
0087 void Tracer::connectionOutput(const QString &identifier, qint64 tag, const Protocol::CommandPtr &cmd)
0088 {
0089     QMutexLocker locker(&mMutex);
0090     if (mTracerBackend) {
0091         if (mTracerBackend->connectionFormat() == TracerInterface::Json) {
0092             QJsonObject json;
0093             json[QStringLiteral("tag")] = tag;
0094             Protocol::toJson(cmd.data(), json);
0095             QJsonDocument doc(json);
0096 
0097             mTracerBackend->connectionOutput(identifier, doc.toJson(QJsonDocument::Indented));
0098         } else {
0099             mTracerBackend->connectionOutput(identifier, QByteArray::number(tag) + ' ' + Protocol::debugString(cmd).toUtf8());
0100         }
0101     }
0102 }
0103 
0104 void Tracer::signal(const QString &signalName, const QString &msg)
0105 {
0106     QMutexLocker locker(&mMutex);
0107     if (mTracerBackend) {
0108         mTracerBackend->signal(signalName, msg);
0109     }
0110 }
0111 
0112 void Tracer::signal(const char *signalName, const QString &msg)
0113 {
0114     signal(QLatin1StringView(signalName), msg);
0115 }
0116 
0117 void Tracer::warning(const QString &componentName, const QString &msg)
0118 {
0119     QMutexLocker locker(&mMutex);
0120     if (mTracerBackend) {
0121         mTracerBackend->warning(componentName, msg);
0122     }
0123 }
0124 
0125 void Tracer::error(const QString &componentName, const QString &msg)
0126 {
0127     QMutexLocker locker(&mMutex);
0128     if (mTracerBackend) {
0129         mTracerBackend->error(componentName, msg);
0130     }
0131 }
0132 
0133 void Tracer::error(const char *componentName, const QString &msg)
0134 {
0135     error(QLatin1StringView(componentName), msg);
0136 }
0137 
0138 QString Tracer::currentTracer() const
0139 {
0140     QMutexLocker locker(&mMutex);
0141     return mSettings->value(QStringLiteral("Debug/Tracer"), DEFAULT_TRACER).toString();
0142 }
0143 
0144 void Tracer::activateTracer(const QString &type)
0145 {
0146     QMutexLocker locker(&mMutex);
0147 
0148     if (type == QLatin1StringView("file")) {
0149         const QString file = mSettings->value(QStringLiteral("Debug/File"), QStringLiteral("/dev/null")).toString();
0150         mTracerBackend = std::make_unique<FileTracer>(file);
0151     } else if (type == QLatin1StringView("dbus")) {
0152         mTracerBackend = std::make_unique<DBusTracer>();
0153     } else if (type == QLatin1StringView("null")) {
0154         mTracerBackend.reset();
0155     } else {
0156         qCCritical(AKONADISERVER_LOG) << "Unknown tracer type" << type;
0157         mTracerBackend.reset();
0158         return;
0159     }
0160 
0161     mSettings->setValue(QStringLiteral("Debug/Tracer"), type);
0162     mSettings->sync();
0163 }
0164 
0165 #include "moc_tracer.cpp"