mirror of
https://github.com/ProtonMail/proton-bridge.git
synced 2025-12-21 17:46:48 +00:00
GODT-1893: bridge-gui sends bridge's log to stdout, stderr.
WIP: bridge-gui now parses and self-apply log level from command-line. WIP: downgraded the log level of gRPC calls to debug.
This commit is contained in:
@ -110,6 +110,7 @@ endif(UNIX)
|
||||
add_executable(bridge-gui
|
||||
Resources.qrc
|
||||
AppController.cpp AppController.h
|
||||
CommandLine.cpp CommandLine.h
|
||||
EventStreamWorker.cpp EventStreamWorker.h
|
||||
main.cpp
|
||||
Pch.h
|
||||
|
||||
129
internal/frontend/bridge-gui/bridge-gui/CommandLine.cpp
Normal file
129
internal/frontend/bridge-gui/bridge-gui/CommandLine.cpp
Normal file
@ -0,0 +1,129 @@
|
||||
// Copyright (c) 2022 Proton AG
|
||||
//
|
||||
// This file is part of Proton Mail Bridge.
|
||||
//
|
||||
// Proton Mail Bridge 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 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Proton Mail Bridge 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.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
#include "Pch.h"
|
||||
#include "CommandLine.h"
|
||||
|
||||
|
||||
using namespace bridgepp;
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
|
||||
QString const launcherFlag = "--launcher"; ///< launcher flag parameter used for bridge.
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \brief parse a command-line string argument as expected by go's CLI package.
|
||||
/// \param[in] argc The number of arguments passed to the application.
|
||||
/// \param[in] argv The list of arguments passed to the application.
|
||||
/// \param[in] paramNames the list of names for the parameter
|
||||
//****************************************************************************************************************************************************
|
||||
QString parseGoCLIStringArgument(int argc, char *argv[], QStringList paramNames)
|
||||
{
|
||||
// go cli package is pretty permissive when it comes to parsing arguments. For each name 'param', all the following seems to be accepted:
|
||||
// -param value
|
||||
// --param value
|
||||
// -param=value
|
||||
// --param=value
|
||||
|
||||
for (QString const ¶mName: paramNames)
|
||||
for (qsizetype i = 1; i < argc; ++i)
|
||||
{
|
||||
QString const arg(QString::fromLocal8Bit(argv[i]));
|
||||
if ((i < argc - 1) && ((arg == "-" + paramName) || (arg == "--" + paramName)))
|
||||
return QString(argv[i + 1]);
|
||||
|
||||
QRegularExpressionMatch match = QRegularExpression(QString("^-{1,2}%1=(.+)$").arg(paramName)).match(arg);
|
||||
if (match.hasMatch())
|
||||
return match.captured(1);
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \brief Parse the log level from the command-line arguments.
|
||||
///
|
||||
/// \param[in] argc The number of arguments passed to the application.
|
||||
/// \param[in] argv The list of arguments passed to the application.
|
||||
/// \return The log level. if not specified on the command-line, the default log level is returned.
|
||||
//****************************************************************************************************************************************************
|
||||
Log::Level parseLogLevel(int argc, char *argv[])
|
||||
{
|
||||
QString levelStr = parseGoCLIStringArgument(argc, argv, { "l", "log-level" });
|
||||
if (levelStr.isEmpty())
|
||||
return Log::defaultLevel;
|
||||
|
||||
Log::Level level = Log::defaultLevel;
|
||||
Log::stringToLevel(levelStr, level);
|
||||
return level;
|
||||
}
|
||||
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \param[in] argc number of arguments passed to the application.
|
||||
/// \param[in] argv list of arguments passed to the application.
|
||||
/// \param[out] args list of arguments passed to the application as a QStringList.
|
||||
/// \param[out] launcher launcher used in argument, forced to self application if not specify.
|
||||
/// \param[out] outAttach The value for the 'attach' command-line parameter.
|
||||
/// \param[out] outLogLevel The parsed log level. If not found, the default log level is returned.
|
||||
//****************************************************************************************************************************************************
|
||||
void parseCommandLineArguments(int argc, char *argv[], QStringList& args, QString& launcher, bool &outAttach, Log::Level& outLogLevel) {
|
||||
bool flagFound = false;
|
||||
launcher = QString::fromLocal8Bit(argv[0]);
|
||||
// for unknown reasons, on Windows QCoreApplication::arguments() frequently returns an empty list, which is incorrect, so we rebuild the argument
|
||||
// list from the original argc and argv values.
|
||||
for (int i = 1; i < argc; i++) {
|
||||
QString const &arg = QString::fromLocal8Bit(argv[i]);
|
||||
// we can't use QCommandLineParser here since it will fail on unknown options.
|
||||
// Arguments may contain some bridge flags.
|
||||
if (arg == launcherFlag)
|
||||
{
|
||||
args.append(arg);
|
||||
launcher = QString::fromLocal8Bit(argv[++i]);
|
||||
args.append(launcher);
|
||||
flagFound = true;
|
||||
}
|
||||
#ifdef QT_DEBUG
|
||||
else if (arg == "--attach" || arg == "-a")
|
||||
{
|
||||
// we don't keep the attach mode within the args since we don't need it for Bridge.
|
||||
outAttach = true;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
args.append(arg);
|
||||
}
|
||||
}
|
||||
if (!flagFound)
|
||||
{
|
||||
// add bridge-gui as launcher
|
||||
args.append(launcherFlag);
|
||||
args.append(launcher);
|
||||
}
|
||||
|
||||
outLogLevel = parseLogLevel(argc, argv);
|
||||
}
|
||||
29
internal/frontend/bridge-gui/bridge-gui/CommandLine.h
Normal file
29
internal/frontend/bridge-gui/bridge-gui/CommandLine.h
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright (c) 2022 Proton AG
|
||||
//
|
||||
// This file is part of Proton Mail Bridge.
|
||||
//
|
||||
// Proton Mail Bridge 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 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Proton Mail Bridge 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.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
#ifndef BRIDGE_GUI_COMMAND_LINE_H
|
||||
#define BRIDGE_GUI_COMMAND_LINE_H
|
||||
|
||||
|
||||
#include <bridgepp/Log/Log.h>
|
||||
|
||||
|
||||
void parseCommandLineArguments(int argc, char *argv[], QStringList& args, QString& launcher, bool &outAttach, bridgepp::Log::Level& outLogLevel); ///< Parse the command-line arguments
|
||||
|
||||
|
||||
#endif //BRIDGE_GUI_COMMAND_LINE_H
|
||||
@ -161,12 +161,9 @@ bridgepp::SPUser UserList::getUserWithID(QString const &userID) const
|
||||
User *UserList::get(int row) const
|
||||
{
|
||||
if ((row < 0) || (row >= users_.count()))
|
||||
{
|
||||
app().log().error(QString("Requesting invalid user at row %1 (user userCount = %2)").arg(row).arg(users_.count()));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
app().log().debug(QString("Retrieving user at row %1 (user userCount = %2)").arg(row).arg(users_.count()));
|
||||
app().log().trace(QString("Retrieving user at row %1 (user userCount = %2)").arg(row).arg(users_.count()));
|
||||
return users_[row].get();
|
||||
}
|
||||
|
||||
@ -185,7 +182,7 @@ void UserList::onUserChanged(QString const &userID)
|
||||
{
|
||||
if (index >= 0) // user exists here but not in the go backend. we delete it.
|
||||
{
|
||||
app().log().debug(QString("Removing user from user list: %1").arg(userID));
|
||||
app().log().trace(QString("Removing user from user list: %1").arg(userID));
|
||||
this->removeUserAt(index);
|
||||
}
|
||||
return;
|
||||
@ -193,12 +190,12 @@ void UserList::onUserChanged(QString const &userID)
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
app().log().debug(QString("Adding user in user list: %1").arg(userID));
|
||||
app().log().trace(QString("Adding user in user list: %1").arg(userID));
|
||||
this->appendUser(user);
|
||||
return;
|
||||
}
|
||||
|
||||
app().log().debug(QString("Updating user in user list: %1").arg(userID));
|
||||
app().log().trace(QString("Updating user in user list: %1").arg(userID));
|
||||
this->updateUserAtRow(index, *user);
|
||||
}
|
||||
|
||||
|
||||
@ -16,6 +16,8 @@
|
||||
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
#include "Pch.h"
|
||||
#include "CommandLine.h"
|
||||
#include "QMLBackend.h"
|
||||
#include "Version.h"
|
||||
#include <bridgepp/Log/Log.h>
|
||||
@ -23,10 +25,6 @@
|
||||
#include <bridgepp/Exception/Exception.h>
|
||||
#include <bridgepp/ProcessMonitor.h>
|
||||
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkRequest>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
using namespace bridgepp;
|
||||
|
||||
@ -41,7 +39,6 @@ namespace
|
||||
QString const exeSuffix;
|
||||
#endif
|
||||
|
||||
QString const launcherFlag = "--launcher"; ///< launcher flag parameter used for bridge.
|
||||
QString const bridgeLock = "bridge-gui.lock"; ///< file name used for the lock file.
|
||||
QString const exeName = "bridge" + exeSuffix; ///< The bridge executable file name.*
|
||||
}
|
||||
@ -81,8 +78,6 @@ void initQtApplication()
|
||||
Log &initLog()
|
||||
{
|
||||
Log &log = app().log();
|
||||
log.setEchoInConsole(true);
|
||||
log.setLevel(Log::Level::Debug);
|
||||
log.registerAsQtMessageHandler();
|
||||
return log;
|
||||
}
|
||||
@ -141,7 +136,7 @@ bool checkSingleInstance(QLockFile &lock)
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \return QUrl to reqch the bridge API.
|
||||
/// \return QUrl to reach the bridge API.
|
||||
//****************************************************************************************************************************************************
|
||||
QUrl getApiUrl()
|
||||
{
|
||||
@ -189,50 +184,6 @@ void focusOtherInstance()
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \param [in] argc number of arguments passed to the application.
|
||||
/// \param [in] argv list of arguments passed to the application.
|
||||
/// \param [out] args list of arguments passed to the application as a QStringList.
|
||||
/// \param [out] launcher launcher used in argument, forced to self application if not specify.
|
||||
/// \param[out] outAttach The value for the 'attach' command-line parameter.
|
||||
//****************************************************************************************************************************************************
|
||||
void parseArguments(int argc, char *argv[], QStringList& args, QString& launcher, bool &outAttach) {
|
||||
bool flagFound = false;
|
||||
launcher = QString::fromLocal8Bit(argv[0]);
|
||||
// for unknown reasons, on Windows QCoreApplication::arguments() frequently returns an empty list, which is incorrect, so we rebuild the argument
|
||||
// list from the original argc and argv values.
|
||||
for (int i = 1; i < argc; i++) {
|
||||
QString const &arg = QString::fromLocal8Bit(argv[i]);
|
||||
// we can't use QCommandLineParser here since it will fail on unknown options.
|
||||
// Arguments may contain some bridge flags.
|
||||
if (arg == launcherFlag)
|
||||
{
|
||||
args.append(arg);
|
||||
launcher = QString::fromLocal8Bit(argv[++i]);
|
||||
args.append(launcher);
|
||||
flagFound = true;
|
||||
}
|
||||
#ifdef QT_DEBUG
|
||||
else if (arg == "--attach" || arg == "-a")
|
||||
{
|
||||
// we don't keep the attach mode within the args since we don't need it for Bridge.
|
||||
outAttach = true;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
args.append(arg);
|
||||
}
|
||||
}
|
||||
if (!flagFound)
|
||||
{
|
||||
// add bridge-gui as launcher
|
||||
args.append(launcherFlag);
|
||||
args.append(launcher);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \param [in] args list of arguments to pass to bridge.
|
||||
//****************************************************************************************************************************************************
|
||||
@ -300,7 +251,14 @@ int main(int argc, char *argv[])
|
||||
QStringList args;
|
||||
QString launcher;
|
||||
bool attach = false;
|
||||
parseArguments(argc, argv, args, launcher, attach);
|
||||
Log::Level logLevel = Log::defaultLevel;
|
||||
parseCommandLineArguments(argc, argv, args, launcher, attach, logLevel);
|
||||
|
||||
// In attached mode, we do not intercept stderr and stdout of bridge, as we did not launch it ourselves, so we output the log to the console.
|
||||
// When not in attached mode, log entries are forwarded to bridge, which output it on stdout/stderr. bridge-gui's process monitor intercept
|
||||
// these outputs and output them on the command-line.
|
||||
log.setEchoInConsole(attach);
|
||||
log.setLevel(logLevel);
|
||||
|
||||
if (!attach)
|
||||
launchBridge(args);
|
||||
@ -344,7 +302,7 @@ int main(int argc, char *argv[])
|
||||
int result = 0;
|
||||
if (!startError)
|
||||
{
|
||||
// we succeed to run the bridge so we can be set as mainExecutable.
|
||||
// we succeeded in launching bridge, so we can be set as mainExecutable.
|
||||
app().grpc().setMainExecutable(QString::fromLocal8Bit(argv[0]));
|
||||
result = QGuiApplication::exec();
|
||||
}
|
||||
|
||||
@ -897,10 +897,10 @@ grpc::Status GRPCClient::stopEventStreamReader()
|
||||
//****************************************************************************************************************************************************
|
||||
/// \param[in] message The event message.
|
||||
//****************************************************************************************************************************************************
|
||||
void GRPCClient::logDebug(QString const &message)
|
||||
void GRPCClient::logTrace(QString const &message)
|
||||
{
|
||||
if (log_)
|
||||
log_->debug(message);
|
||||
log_->trace(message);
|
||||
}
|
||||
|
||||
|
||||
@ -1102,31 +1102,31 @@ void GRPCClient::processAppEvent(AppEvent const &event)
|
||||
switch (event.event_case())
|
||||
{
|
||||
case AppEvent::kInternetStatus:
|
||||
this->logDebug("App event received: InternetStatus.");
|
||||
this->logTrace("App event received: InternetStatus.");
|
||||
emit internetStatus(event.internetstatus().connected());
|
||||
break;
|
||||
case AppEvent::kToggleAutostartFinished:
|
||||
this->logDebug("App event received: AutostartFinished.");
|
||||
this->logTrace("App event received: AutostartFinished.");
|
||||
emit toggleAutostartFinished();
|
||||
break;
|
||||
case AppEvent::kResetFinished:
|
||||
this->logDebug("App event received: ResetFinished.");
|
||||
this->logTrace("App event received: ResetFinished.");
|
||||
emit resetFinished();
|
||||
break;
|
||||
case AppEvent::kReportBugFinished:
|
||||
this->logDebug("App event received: ReportBugFinished.");
|
||||
this->logTrace("App event received: ReportBugFinished.");
|
||||
emit reportBugFinished();
|
||||
break;
|
||||
case AppEvent::kReportBugSuccess:
|
||||
this->logDebug("App event received: ReportBugSuccess.");
|
||||
this->logTrace("App event received: ReportBugSuccess.");
|
||||
emit reportBugSuccess();
|
||||
break;
|
||||
case AppEvent::kReportBugError:
|
||||
this->logDebug("App event received: ReportBugError.");
|
||||
this->logTrace("App event received: ReportBugError.");
|
||||
emit reportBugError();
|
||||
break;
|
||||
case AppEvent::kShowMainWindow:
|
||||
this->logDebug("App event received: ShowMainWindow.");
|
||||
this->logTrace("App event received: ShowMainWindow.");
|
||||
emit showMainWindow();
|
||||
break;
|
||||
default:
|
||||
@ -1144,7 +1144,7 @@ void GRPCClient::processLoginEvent(LoginEvent const &event)
|
||||
{
|
||||
case LoginEvent::kError:
|
||||
{
|
||||
this->logDebug("Login event received: Error.");
|
||||
this->logTrace("Login event received: Error.");
|
||||
LoginErrorEvent const &error = event.error();
|
||||
switch (error.type())
|
||||
{
|
||||
@ -1176,19 +1176,19 @@ void GRPCClient::processLoginEvent(LoginEvent const &event)
|
||||
break;
|
||||
}
|
||||
case LoginEvent::kTfaRequested:
|
||||
this->logDebug("Login event received: TfaRequested.");
|
||||
this->logTrace("Login event received: TfaRequested.");
|
||||
emit login2FARequested(QString::fromStdString(event.tfarequested().username()));
|
||||
break;
|
||||
case LoginEvent::kTwoPasswordRequested:
|
||||
this->logDebug("Login event received: TwoPasswordRequested.");
|
||||
this->logTrace("Login event received: TwoPasswordRequested.");
|
||||
emit login2PasswordRequested();
|
||||
break;
|
||||
case LoginEvent::kFinished:
|
||||
this->logDebug("Login event received: Finished.");
|
||||
this->logTrace("Login event received: Finished.");
|
||||
emit loginFinished(QString::fromStdString(event.finished().userid()));
|
||||
break;
|
||||
case LoginEvent::kAlreadyLoggedIn:
|
||||
this->logDebug("Login event received: AlreadyLoggedIn.");
|
||||
this->logTrace("Login event received: AlreadyLoggedIn.");
|
||||
emit loginAlreadyLoggedIn(QString::fromStdString(event.finished().userid()));
|
||||
break;
|
||||
default:
|
||||
@ -1207,7 +1207,7 @@ void GRPCClient::processUpdateEvent(UpdateEvent const &event)
|
||||
{
|
||||
case UpdateEvent::kError:
|
||||
{
|
||||
this->logDebug("Update event received: Error.");
|
||||
this->logTrace("Update event received: Error.");
|
||||
|
||||
UpdateErrorEvent const &errorEvent = event.error();
|
||||
switch (errorEvent.type())
|
||||
@ -1228,31 +1228,31 @@ void GRPCClient::processUpdateEvent(UpdateEvent const &event)
|
||||
break;
|
||||
}
|
||||
case UpdateEvent::kManualReady:
|
||||
this->logDebug("Update event received: ManualReady.");
|
||||
this->logTrace("Update event received: ManualReady.");
|
||||
emit updateManualReady(QString::fromStdString(event.manualready().version()));
|
||||
break;
|
||||
case UpdateEvent::kManualRestartNeeded:
|
||||
this->logDebug("Update event received: kManualRestartNeeded.");
|
||||
this->logTrace("Update event received: kManualRestartNeeded.");
|
||||
emit updateManualRestartNeeded();
|
||||
break;
|
||||
case UpdateEvent::kForce:
|
||||
this->logDebug("Update event received: kForce.");
|
||||
this->logTrace("Update event received: kForce.");
|
||||
emit updateForce(QString::fromStdString(event.force().version()));
|
||||
break;
|
||||
case UpdateEvent::kSilentRestartNeeded:
|
||||
this->logDebug("Update event received: kSilentRestartNeeded.");
|
||||
this->logTrace("Update event received: kSilentRestartNeeded.");
|
||||
emit updateSilentRestartNeeded();
|
||||
break;
|
||||
case UpdateEvent::kIsLatestVersion:
|
||||
this->logDebug("Update event received: kIsLatestVersion.");
|
||||
this->logTrace("Update event received: kIsLatestVersion.");
|
||||
emit updateIsLatestVersion();
|
||||
break;
|
||||
case UpdateEvent::kCheckFinished:
|
||||
this->logDebug("Update event received: kCheckFinished.");
|
||||
this->logTrace("Update event received: kCheckFinished.");
|
||||
emit checkUpdatesFinished();
|
||||
break;
|
||||
case UpdateEvent::kVersionChanged:
|
||||
this->logDebug("Update event received: kVersionChanged.");
|
||||
this->logTrace("Update event received: kVersionChanged.");
|
||||
emit updateVersionChanged();
|
||||
break;
|
||||
default:
|
||||
@ -1293,22 +1293,22 @@ void GRPCClient::processCacheEvent(CacheEvent const &event)
|
||||
}
|
||||
|
||||
case CacheEvent::kLocationChangedSuccess:
|
||||
this->logDebug("Cache event received: LocationChangedSuccess.");
|
||||
this->logTrace("Cache event received: LocationChangedSuccess.");
|
||||
emit cacheLocationChangeSuccess();
|
||||
break;
|
||||
|
||||
case CacheEvent::kChangeLocalCacheFinished:
|
||||
emit changeLocalCacheFinished(event.changelocalcachefinished().willrestart());
|
||||
this->logDebug("Cache event received: ChangeLocalCacheFinished.");
|
||||
this->logTrace("Cache event received: ChangeLocalCacheFinished.");
|
||||
break;
|
||||
|
||||
case CacheEvent::kIsCacheOnDiskEnabledChanged:
|
||||
this->logDebug("Cache event received: IsCacheOnDiskEnabledChanged.");
|
||||
this->logTrace("Cache event received: IsCacheOnDiskEnabledChanged.");
|
||||
emit isCacheOnDiskEnabledChanged(event.iscacheondiskenabledchanged().enabled());
|
||||
break;
|
||||
|
||||
case CacheEvent::kDiskCachePathChanged:
|
||||
this->logDebug("Cache event received: DiskCachePathChanged.");
|
||||
this->logTrace("Cache event received: DiskCachePathChanged.");
|
||||
emit diskCachePathChanged(QUrl::fromLocalFile(QString::fromStdString(event.diskcachepathchanged().path())));
|
||||
break;
|
||||
|
||||
@ -1326,7 +1326,7 @@ void GRPCClient::processMailSettingsEvent(MailSettingsEvent const &event)
|
||||
switch (event.event_case())
|
||||
{
|
||||
case MailSettingsEvent::kError:
|
||||
this->logDebug("MailSettings event received: Error.");
|
||||
this->logTrace("MailSettings event received: Error.");
|
||||
switch (event.error().type())
|
||||
{
|
||||
case IMAP_PORT_ISSUE:
|
||||
@ -1341,11 +1341,11 @@ void GRPCClient::processMailSettingsEvent(MailSettingsEvent const &event)
|
||||
}
|
||||
|
||||
case MailSettingsEvent::kUseSslForSmtpFinished:
|
||||
this->logDebug("MailSettings event received: UseSslForSmtpFinished.");
|
||||
this->logTrace("MailSettings event received: UseSslForSmtpFinished.");
|
||||
emit toggleUseSSLFinished();
|
||||
break;
|
||||
case MailSettingsEvent::kChangePortsFinished:
|
||||
this->logDebug("MailSettings event received: ChangePortsFinished.");
|
||||
this->logTrace("MailSettings event received: ChangePortsFinished.");
|
||||
emit changePortFinished();
|
||||
break;
|
||||
default:
|
||||
@ -1362,15 +1362,15 @@ void GRPCClient::processKeychainEvent(KeychainEvent const &event)
|
||||
switch (event.event_case())
|
||||
{
|
||||
case KeychainEvent::kChangeKeychainFinished:
|
||||
this->logDebug("Keychain event received: ChangeKeychainFinished.");
|
||||
this->logTrace("Keychain event received: ChangeKeychainFinished.");
|
||||
emit changeKeychainFinished();
|
||||
break;
|
||||
case KeychainEvent::kHasNoKeychain:
|
||||
this->logDebug("Keychain event received: HasNoKeychain.");
|
||||
this->logTrace("Keychain event received: HasNoKeychain.");
|
||||
emit hasNoKeychain();
|
||||
break;
|
||||
case KeychainEvent::kRebuildKeychain:
|
||||
this->logDebug("Keychain event received: RebuildKeychain.");
|
||||
this->logTrace("Keychain event received: RebuildKeychain.");
|
||||
emit rebuildKeychain();
|
||||
break;
|
||||
default:
|
||||
@ -1387,20 +1387,20 @@ void GRPCClient::processMailEvent(MailEvent const &event)
|
||||
switch (event.event_case())
|
||||
{
|
||||
case MailEvent::kNoActiveKeyForRecipientEvent:
|
||||
this->logDebug("Mail event received: kNoActiveKeyForRecipientEvent.");
|
||||
this->logTrace("Mail event received: kNoActiveKeyForRecipientEvent.");
|
||||
emit noActiveKeyForRecipient(QString::fromStdString(event.noactivekeyforrecipientevent().email()));
|
||||
break;
|
||||
case MailEvent::kAddressChanged:
|
||||
this->logDebug("Mail event received: AddressChanged.");
|
||||
this->logTrace("Mail event received: AddressChanged.");
|
||||
emit addressChanged(QString::fromStdString(event.addresschanged().address()));
|
||||
break;
|
||||
case MailEvent::kAddressChangedLogout:
|
||||
this->logDebug("Mail event received: AddressChangedLogout.");
|
||||
this->logTrace("Mail event received: AddressChangedLogout.");
|
||||
emit addressChangedLogout(QString::fromStdString(event.addresschangedlogout().address()));
|
||||
break;
|
||||
case MailEvent::kApiCertIssue:
|
||||
emit apiCertIssue();
|
||||
this->logDebug("Mail event received: ApiCertIssue.");
|
||||
this->logTrace("Mail event received: ApiCertIssue.");
|
||||
break;
|
||||
default:
|
||||
this->logError("Unknown Mail event received.");
|
||||
@ -1418,21 +1418,21 @@ void GRPCClient::processUserEvent(UserEvent const &event)
|
||||
case UserEvent::kToggleSplitModeFinished:
|
||||
{
|
||||
QString const userID = QString::fromStdString(event.togglesplitmodefinished().userid());
|
||||
this->logDebug(QString("User event received: ToggleSplitModeFinished (userID = %1).").arg(userID));
|
||||
this->logTrace(QString("User event received: ToggleSplitModeFinished (userID = %1).").arg(userID));
|
||||
emit toggleSplitModeFinished(userID);
|
||||
break;
|
||||
}
|
||||
case UserEvent::kUserDisconnected:
|
||||
{
|
||||
QString const username = QString::fromStdString(event.userdisconnected().username());
|
||||
this->logDebug(QString("User event received: UserDisconnected (username = %1).").arg(username));
|
||||
this->logTrace(QString("User event received: UserDisconnected (username = %1).").arg(username));
|
||||
emit userDisconnected(username);
|
||||
break;
|
||||
}
|
||||
case UserEvent::kUserChanged:
|
||||
{
|
||||
QString const userID = QString::fromStdString(event.userchanged().userid());
|
||||
this->logDebug(QString("User event received: UserChanged (userID = %1).").arg(userID));
|
||||
this->logTrace(QString("User event received: UserChanged (userID = %1).").arg(userID));
|
||||
emit userChanged(userID);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -203,7 +203,7 @@ private slots:
|
||||
void configFolderChanged();
|
||||
|
||||
private:
|
||||
void logDebug(QString const &message); ///< Log an event.
|
||||
void logTrace(QString const &message); ///< Log an event.
|
||||
void logError(QString const &message); ///< Log an event.
|
||||
grpc::Status logGRPCCallStatus(grpc::Status const &status, QString const &callName, QList<grpc::StatusCode> allowedErrors = {}); ///< Log the status of a gRPC code.
|
||||
grpc::Status simpleMethod(SimpleMethod method); ///< perform a gRPC call to a bool setter.
|
||||
|
||||
@ -29,6 +29,18 @@ namespace
|
||||
Log *qtHandlerLog { nullptr }; ///< The log instance handling qt logs.
|
||||
QMutex qtHandlerMutex; ///< A mutex used to access qtHandlerLog.
|
||||
|
||||
// Mapping of log levels to string. Maybe used to lookup using both side a a key, so a list of pair is more convenient that a map.
|
||||
QList<QPair<Log::Level, QString>> const logLevelStrings {
|
||||
{ Log::Level::Panic, "panic", },
|
||||
{ Log::Level::Fatal, "fatal", },
|
||||
{ Log::Level::Error, "error", },
|
||||
{ Log::Level::Warn, "warn", },
|
||||
{ Log::Level::Info, "info", },
|
||||
{ Log::Level::Debug, "debug", },
|
||||
{ Log::Level::Trace, "trace", },
|
||||
};
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \param[in] log The log handling qt log entries. Can be null.
|
||||
//****************************************************************************************************************************************************
|
||||
@ -79,36 +91,6 @@ void qtMessageHandler(QtMsgType type, QMessageLogContext const &, QString const
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \param[in] level The level.
|
||||
/// \return A string describing the level.
|
||||
//****************************************************************************************************************************************************
|
||||
QString logLevelToString(Log::Level level)
|
||||
{
|
||||
switch (level)
|
||||
{
|
||||
case Log::Level::Panic:
|
||||
return "PANIC";
|
||||
case Log::Level::Fatal:
|
||||
return "FATAL";
|
||||
case Log::Level::Error:
|
||||
return "ERROR";
|
||||
case Log::Level::Warn:
|
||||
return "WARN";
|
||||
case Log::Level::Info:
|
||||
return "INFO";
|
||||
case Log::Level::Debug:
|
||||
return "DEBUG";
|
||||
case Log::Level::Trace:
|
||||
return "TRACE";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
@ -121,7 +103,43 @@ QString logLevelToString(Log::Level level)
|
||||
//****************************************************************************************************************************************************
|
||||
QString Log::logEntryToString(Log::Level level, QString const &message)
|
||||
{
|
||||
return QString("[%1] %2").arg(logLevelToString(level), message);
|
||||
return QString("[%1] %2").arg(levelToString(level).toUpper(), message);
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \param[in] level The level.
|
||||
/// \return A string describing the level.
|
||||
//****************************************************************************************************************************************************
|
||||
QString Log::levelToString(Log::Level level)
|
||||
{
|
||||
QList<QPair<Log::Level, QString>>::const_iterator it = std::find_if(logLevelStrings.begin(), logLevelStrings.end(),
|
||||
[&level](QPair<Log::Level, QString> const &pair) -> bool {
|
||||
return pair.first == level;
|
||||
});
|
||||
return (it == logLevelStrings.end()) ? QString() : it->second;
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// The matching is case-insensitive.
|
||||
///
|
||||
/// \param[in] str The string
|
||||
/// \param[out] outLevel The log level parsed. if not found, the value of the variable is not modified.
|
||||
/// \return true iff parsing was successful.
|
||||
//****************************************************************************************************************************************************
|
||||
bool Log::stringToLevel(QString const &str, Log::Level &outLevel)
|
||||
{
|
||||
QList<QPair<Log::Level, QString>>::const_iterator it = std::find_if(logLevelStrings.begin(), logLevelStrings.end(),
|
||||
[&str](QPair<Log::Level, QString> const &pair) -> bool {
|
||||
return 0 == QString::compare(str, pair.second, Qt::CaseInsensitive);
|
||||
});
|
||||
|
||||
bool const found = (it != logLevelStrings.end());
|
||||
if (found)
|
||||
outLevel = it->first;
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
@ -162,7 +180,7 @@ void Log::setLevel(Log::Level level)
|
||||
Log::Level Log::level() const
|
||||
{
|
||||
QMutexLocker locker(&mutex_);
|
||||
return Log::Level::Debug;
|
||||
return level_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -45,7 +45,11 @@ public: // data types.
|
||||
|
||||
public: // static member functions.
|
||||
static QString logEntryToString(Log::Level level, QString const &message); ///< Return a string describing a log entry.
|
||||
static QString levelToString(Log::Level level); ///< return the string for a level.
|
||||
static bool stringToLevel(QString const &str, Log::Level& outLevel); ///< parse a level from a string.
|
||||
|
||||
public: // static data member.
|
||||
static const Level defaultLevel { Level::Info }; ///< The default log level (the same as logrus).
|
||||
|
||||
public: // member functions.
|
||||
Log(); ///< Default constructor.
|
||||
@ -77,8 +81,8 @@ signals:
|
||||
|
||||
private: // data members
|
||||
mutable QMutex mutex_; ///< The mutex.
|
||||
Level level_{Level::Debug}; ///< The log level
|
||||
bool echoInConsole_{false}; ///< Set if the log messages should be sent to STDOUT/STDERR.
|
||||
Level level_ { defaultLevel }; ///< The log level
|
||||
bool echoInConsole_ { false }; ///< Set if the log messages should be sent to STDOUT/STDERR.
|
||||
|
||||
QTextStream stdout_; ///< The stdout stream.
|
||||
QTextStream stderr_; ///< The stderr stream.
|
||||
|
||||
@ -58,11 +58,23 @@ void ProcessMonitor::run()
|
||||
status_.running = true;
|
||||
status_.pid = p.processId();
|
||||
|
||||
QTextStream out(stdout), err(stderr);
|
||||
QByteArray array;
|
||||
while (!p.waitForFinished(100))
|
||||
{
|
||||
// we discard output from bridge, it's logged to file on bridge side.
|
||||
p.readAllStandardError();
|
||||
p.readAllStandardOutput();
|
||||
array = p.readAllStandardError();
|
||||
if (!array.isEmpty())
|
||||
{
|
||||
err << array;
|
||||
err.flush();
|
||||
}
|
||||
|
||||
array = p.readAllStandardOutput();
|
||||
if (!array.isEmpty())
|
||||
{
|
||||
out << array;
|
||||
out.flush();
|
||||
}
|
||||
}
|
||||
|
||||
status_.running = false;
|
||||
|
||||
Reference in New Issue
Block a user