added open service logs to logs page (#951)
* added open service logs to logs page * redesign of log saving buttons * hide service logs buttons for mobile platforms * refactoring: moved logger to common folder * feature: added the ability to enable logs to the start screen
This commit is contained in:
parent
918be16372
commit
9cab51fb00
22 changed files with 519 additions and 691 deletions
|
@ -113,6 +113,7 @@ include(${CMAKE_CURRENT_LIST_DIR}/cmake/3rdparty.cmake)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
${CMAKE_CURRENT_LIST_DIR}/../ipc
|
${CMAKE_CURRENT_LIST_DIR}/../ipc
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/../common/logger
|
||||||
${CMAKE_CURRENT_LIST_DIR}
|
${CMAKE_CURRENT_LIST_DIR}
|
||||||
${CMAKE_CURRENT_BINARY_DIR}
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
)
|
)
|
||||||
|
@ -134,7 +135,6 @@ set(HEADERS ${HEADERS}
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/protocols_defs.h
|
${CMAKE_CURRENT_LIST_DIR}/protocols/protocols_defs.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/qml_register_protocols.h
|
${CMAKE_CURRENT_LIST_DIR}/protocols/qml_register_protocols.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ui/pages.h
|
${CMAKE_CURRENT_LIST_DIR}/ui/pages.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ui/property_helper.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ui/qautostart.h
|
${CMAKE_CURRENT_LIST_DIR}/ui/qautostart.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/vpnprotocol.h
|
${CMAKE_CURRENT_LIST_DIR}/protocols/vpnprotocol.h
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/version.h
|
${CMAKE_CURRENT_BINARY_DIR}/version.h
|
||||||
|
@ -143,6 +143,7 @@ set(HEADERS ${HEADERS}
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/serialization/serialization.h
|
${CMAKE_CURRENT_LIST_DIR}/core/serialization/serialization.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/serialization/transfer.h
|
${CMAKE_CURRENT_LIST_DIR}/core/serialization/transfer.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/enums/apiEnums.h
|
${CMAKE_CURRENT_LIST_DIR}/core/enums/apiEnums.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/../common/logger/logger.h
|
||||||
)
|
)
|
||||||
|
|
||||||
# Mozilla headres
|
# Mozilla headres
|
||||||
|
@ -193,6 +194,7 @@ set(SOURCES ${SOURCES}
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/serialization/trojan.cpp
|
${CMAKE_CURRENT_LIST_DIR}/core/serialization/trojan.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/serialization/vmess.cpp
|
${CMAKE_CURRENT_LIST_DIR}/core/serialization/vmess.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/serialization/vmess_new.cpp
|
${CMAKE_CURRENT_LIST_DIR}/core/serialization/vmess_new.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/../common/logger/logger.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
# Mozilla sources
|
# Mozilla sources
|
||||||
|
|
|
@ -164,7 +164,7 @@ void AmneziaApplication::init()
|
||||||
bool enabled = m_settings->isSaveLogs();
|
bool enabled = m_settings->isSaveLogs();
|
||||||
#ifndef Q_OS_ANDROID
|
#ifndef Q_OS_ANDROID
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
if (!Logger::init()) {
|
if (!Logger::init(false)) {
|
||||||
qWarning() << "Initialization of debug subsystem failed";
|
qWarning() << "Initialization of debug subsystem failed";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,6 @@ ErrorCode ServerController::runScript(const ServerCredentials &credentials, QStr
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug().noquote() << lineToExec;
|
qDebug().noquote() << lineToExec;
|
||||||
Logger::appendSshLog("Run command:" + lineToExec);
|
|
||||||
|
|
||||||
error = m_sshClient.executeCommand(lineToExec, cbReadStdOut, cbReadStdErr);
|
error = m_sshClient.executeCommand(lineToExec, cbReadStdOut, cbReadStdErr);
|
||||||
if (error != ErrorCode::NoError) {
|
if (error != ErrorCode::NoError) {
|
||||||
|
@ -100,7 +99,6 @@ ErrorCode ServerController::runContainerScript(const ServerCredentials &credenti
|
||||||
const std::function<ErrorCode(const QString &, libssh::Client &)> &cbReadStdErr)
|
const std::function<ErrorCode(const QString &, libssh::Client &)> &cbReadStdErr)
|
||||||
{
|
{
|
||||||
QString fileName = "/opt/amnezia/" + Utils::getRandomString(16) + ".sh";
|
QString fileName = "/opt/amnezia/" + Utils::getRandomString(16) + ".sh";
|
||||||
Logger::appendSshLog("Run container script for " + ContainerProps::containerToString(container) + ":\n" + script);
|
|
||||||
|
|
||||||
ErrorCode e = uploadTextFileToContainer(container, credentials, script, fileName);
|
ErrorCode e = uploadTextFileToContainer(container, credentials, script, fileName);
|
||||||
if (e)
|
if (e)
|
||||||
|
|
107
client/logger.h
107
client/logger.h
|
@ -1,107 +0,0 @@
|
||||||
#ifndef LOGGER_H
|
|
||||||
#define LOGGER_H
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QDir>
|
|
||||||
#include <QFile>
|
|
||||||
#include <QString>
|
|
||||||
#include <QTextStream>
|
|
||||||
|
|
||||||
#include "ui/property_helper.h"
|
|
||||||
|
|
||||||
#include "mozilla/shared/loglevel.h"
|
|
||||||
|
|
||||||
class Logger : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
AUTO_PROPERTY(QString, sshLog)
|
|
||||||
AUTO_PROPERTY(QString, allLog)
|
|
||||||
|
|
||||||
public:
|
|
||||||
static Logger& Instance();
|
|
||||||
|
|
||||||
static void appendSshLog(const QString &log);
|
|
||||||
static void appendAllLog(const QString &log);
|
|
||||||
|
|
||||||
|
|
||||||
static bool init();
|
|
||||||
static void deInit();
|
|
||||||
static bool setServiceLogsEnabled(bool enabled);
|
|
||||||
static bool openLogsFolder();
|
|
||||||
static bool openServiceLogsFolder();
|
|
||||||
static QString appLogFileNamePath();
|
|
||||||
static void clearLogs();
|
|
||||||
static void clearServiceLogs();
|
|
||||||
static void cleanUp();
|
|
||||||
|
|
||||||
static QString userLogsFilePath();
|
|
||||||
static QString getLogFile();
|
|
||||||
|
|
||||||
// compat with Mozilla logger
|
|
||||||
Logger(const QString &className) { m_className = className; }
|
|
||||||
const QString& className() const { return m_className; }
|
|
||||||
|
|
||||||
class Log {
|
|
||||||
public:
|
|
||||||
Log(Logger* logger, LogLevel level);
|
|
||||||
~Log();
|
|
||||||
|
|
||||||
Log& operator<<(uint64_t t);
|
|
||||||
Log& operator<<(const char* t);
|
|
||||||
Log& operator<<(const QString& t);
|
|
||||||
Log& operator<<(const QStringList& t);
|
|
||||||
Log& operator<<(const QByteArray& t);
|
|
||||||
Log& operator<<(const QJsonObject& t);
|
|
||||||
Log& operator<<(QTextStreamFunction t);
|
|
||||||
Log& operator<<(const void* t);
|
|
||||||
|
|
||||||
// Q_ENUM
|
|
||||||
template <typename T>
|
|
||||||
typename std::enable_if<QtPrivate::IsQEnumHelper<T>::Value, Log&>::type
|
|
||||||
operator<<(T t) {
|
|
||||||
const QMetaObject* meta = qt_getEnumMetaObject(t);
|
|
||||||
const char* name = qt_getEnumName(t);
|
|
||||||
addMetaEnum(typename QFlags<T>::Int(t), meta, name);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void addMetaEnum(quint64 value, const QMetaObject* meta, const char* name);
|
|
||||||
|
|
||||||
Logger* m_logger;
|
|
||||||
LogLevel m_logLevel;
|
|
||||||
|
|
||||||
struct Data {
|
|
||||||
Data() : m_ts(&m_buffer, QIODevice::WriteOnly) {}
|
|
||||||
|
|
||||||
QString m_buffer;
|
|
||||||
QTextStream m_ts;
|
|
||||||
};
|
|
||||||
|
|
||||||
Data* m_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
Log error();
|
|
||||||
Log warning();
|
|
||||||
Log info();
|
|
||||||
Log debug();
|
|
||||||
QString sensitive(const QString& input);
|
|
||||||
|
|
||||||
private:
|
|
||||||
Logger() {}
|
|
||||||
Logger(Logger const &) = delete;
|
|
||||||
Logger& operator= (Logger const&) = delete;
|
|
||||||
|
|
||||||
static QString userLogsDir();
|
|
||||||
|
|
||||||
static QFile m_file;
|
|
||||||
static QTextStream m_textStream;
|
|
||||||
static QString m_logFileName;
|
|
||||||
|
|
||||||
friend void debugMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg);
|
|
||||||
|
|
||||||
// compat with Mozilla logger
|
|
||||||
QString m_className;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // LOGGER_H
|
|
|
@ -227,7 +227,7 @@ void Settings::setSaveLogs(bool enabled)
|
||||||
if (!isSaveLogs()) {
|
if (!isSaveLogs()) {
|
||||||
Logger::deInit();
|
Logger::deInit();
|
||||||
} else {
|
} else {
|
||||||
if (!Logger::init()) {
|
if (!Logger::init(false)) {
|
||||||
qWarning() << "Initialization of debug subsystem failed";
|
qWarning() << "Initialization of debug subsystem failed";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,12 @@ void SettingsController::toggleLogging(bool enable)
|
||||||
|
|
||||||
void SettingsController::openLogsFolder()
|
void SettingsController::openLogsFolder()
|
||||||
{
|
{
|
||||||
Logger::openLogsFolder();
|
Logger::openLogsFolder(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsController::openServiceLogsFolder()
|
||||||
|
{
|
||||||
|
Logger::openLogsFolder(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsController::exportLogsFile(const QString &fileName)
|
void SettingsController::exportLogsFile(const QString &fileName)
|
||||||
|
@ -100,12 +105,21 @@ void SettingsController::exportLogsFile(const QString &fileName)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SettingsController::exportServiceLogsFile(const QString &fileName)
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
AndroidController::instance()->exportLogsFile(fileName);
|
||||||
|
#else
|
||||||
|
SystemController::saveFile(fileName, Logger::getServiceLogFile());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void SettingsController::clearLogs()
|
void SettingsController::clearLogs()
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
AndroidController::instance()->clearLogs();
|
AndroidController::instance()->clearLogs();
|
||||||
#else
|
#else
|
||||||
Logger::clearLogs();
|
Logger::clearLogs(false);
|
||||||
Logger::clearServiceLogs();
|
Logger::clearServiceLogs();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,9 @@ public slots:
|
||||||
void toggleLogging(bool enable);
|
void toggleLogging(bool enable);
|
||||||
|
|
||||||
void openLogsFolder();
|
void openLogsFolder();
|
||||||
|
void openServiceLogsFolder();
|
||||||
void exportLogsFile(const QString &fileName);
|
void exportLogsFile(const QString &fileName);
|
||||||
|
void exportServiceLogsFile(const QString &fileName);
|
||||||
void clearLogs();
|
void clearLogs();
|
||||||
|
|
||||||
void backupAppConfig(const QString &fileName);
|
void backupAppConfig(const QString &fileName);
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
#ifndef PROPERTY_HELPER_H
|
|
||||||
#define PROPERTY_HELPER_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
|
|
||||||
#define AUTO_PROPERTY(TYPE, NAME) \
|
|
||||||
Q_PROPERTY(TYPE NAME READ NAME WRITE set_ ## NAME NOTIFY NAME ## Changed ) \
|
|
||||||
public: \
|
|
||||||
TYPE NAME() const { return m_ ## NAME ; } \
|
|
||||||
void set_ ## NAME(TYPE value) { \
|
|
||||||
if (m_ ## NAME == value) return; \
|
|
||||||
m_ ## NAME = value; \
|
|
||||||
emit NAME ## Changed(value); \
|
|
||||||
} \
|
|
||||||
Q_SIGNAL void NAME ## Changed(TYPE value);\
|
|
||||||
private: \
|
|
||||||
TYPE m_ ## NAME{};
|
|
||||||
|
|
||||||
#define READONLY_PROPERTY(TYPE, NAME) \
|
|
||||||
Q_PROPERTY(TYPE NAME READ NAME CONSTANT ) \
|
|
||||||
public: \
|
|
||||||
TYPE NAME() const { return m_ ## NAME ; } \
|
|
||||||
private: \
|
|
||||||
void NAME(TYPE value) {m_ ## NAME = value; } \
|
|
||||||
TYPE m_ ## NAME{};
|
|
||||||
|
|
||||||
#endif // PROPERTY_HELPER_H
|
|
|
@ -20,7 +20,8 @@ Item {
|
||||||
property string buttonImageSource
|
property string buttonImageSource
|
||||||
property string rightImageSource
|
property string rightImageSource
|
||||||
property string leftImageSource
|
property string leftImageSource
|
||||||
property bool isLeftImageHoverEnabled: true //todo separete this qml file to 3
|
property bool isLeftImageHoverEnabled: true
|
||||||
|
property bool isSmallLeftImage: false
|
||||||
|
|
||||||
property alias rightButton: rightImage
|
property alias rightButton: rightImage
|
||||||
property alias eyeButton: eyeImage
|
property alias eyeButton: eyeImage
|
||||||
|
@ -114,9 +115,9 @@ Item {
|
||||||
|
|
||||||
visible: leftImageSource ? true : false
|
visible: leftImageSource ? true : false
|
||||||
|
|
||||||
Layout.preferredHeight: rightImageSource || !isLeftImageHoverEnabled ? leftImage.implicitHeight : 56
|
Layout.preferredHeight: (rightImageSource || !isLeftImageHoverEnabled || isSmallLeftImage) ? 40 : 56
|
||||||
Layout.preferredWidth: rightImageSource || !isLeftImageHoverEnabled ? leftImage.implicitWidth : 56
|
Layout.preferredWidth: (rightImageSource || !isLeftImageHoverEnabled || isSmallLeftImage)? 40 : 56
|
||||||
Layout.rightMargin: rightImageSource || !isLeftImageHoverEnabled ? 16 : 0
|
Layout.rightMargin: isSmallLeftImage ? 8 : (rightImageSource || !isLeftImageHoverEnabled) ? 16 : 0
|
||||||
|
|
||||||
radius: 12
|
radius: 12
|
||||||
color: AmneziaStyle.color.transparent
|
color: AmneziaStyle.color.transparent
|
||||||
|
|
|
@ -102,8 +102,7 @@ Switch {
|
||||||
contentItem: ColumnLayout {
|
contentItem: ColumnLayout {
|
||||||
id: content
|
id: content
|
||||||
|
|
||||||
anchors.top: parent.top
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|
||||||
ListItemTitleType {
|
ListItemTitleType {
|
||||||
|
|
|
@ -16,18 +16,6 @@ import "../Controls2/TextTypes"
|
||||||
PageType {
|
PageType {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: SettingsController
|
|
||||||
|
|
||||||
function onLoggingStateChanged() {
|
|
||||||
if (SettingsController.isLoggingEnabled) {
|
|
||||||
var message = qsTr("Logging is enabled. Note that logs will be automatically \
|
|
||||||
disabled after 14 days, and all log files will be deleted.")
|
|
||||||
PageController.showNotificationMessage(message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
defaultActiveFocusItem: focusItem
|
defaultActiveFocusItem: focusItem
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
@ -58,13 +46,12 @@ disabled after 14 days, and all log files will be deleted.")
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.leftMargin: 16
|
spacing: 0
|
||||||
anchors.rightMargin: 16
|
|
||||||
|
|
||||||
spacing: 16
|
|
||||||
|
|
||||||
HeaderType {
|
HeaderType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: 16
|
||||||
|
Layout.rightMargin: 16
|
||||||
|
|
||||||
headerText: qsTr("Logging")
|
headerText: qsTr("Logging")
|
||||||
descriptionText: qsTr("Enabling this function will save application's logs automatically. " +
|
descriptionText: qsTr("Enabling this function will save application's logs automatically. " +
|
||||||
|
@ -75,11 +62,13 @@ disabled after 14 days, and all log files will be deleted.")
|
||||||
id: switcher
|
id: switcher
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
|
Layout.leftMargin: 16
|
||||||
|
Layout.rightMargin: 16
|
||||||
|
|
||||||
text: qsTr("Save logs")
|
text: qsTr("Enable logs")
|
||||||
|
|
||||||
checked: SettingsController.isLoggingEnabled
|
checked: SettingsController.isLoggingEnabled
|
||||||
KeyNavigation.tab: openFolderButton
|
//KeyNavigation.tab: openFolderButton
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
if (checked !== SettingsController.isLoggingEnabled) {
|
if (checked !== SettingsController.isLoggingEnabled) {
|
||||||
SettingsController.isLoggingEnabled = checked
|
SettingsController.isLoggingEnabled = checked
|
||||||
|
@ -87,132 +76,200 @@ disabled after 14 days, and all log files will be deleted.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
DividerType {}
|
||||||
|
|
||||||
|
LabelWithButtonType {
|
||||||
|
// id: labelWithButton2
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: -8
|
||||||
|
|
||||||
ColumnLayout {
|
text: qsTr("Clear logs")
|
||||||
Layout.alignment: Qt.AlignBaseline
|
leftImageSource: "qrc:/images/controls/trash.svg"
|
||||||
Layout.preferredWidth: GC.isMobile() ? 0 : root.width / 3
|
isSmallLeftImage: true
|
||||||
visible: !GC.isMobile()
|
|
||||||
|
|
||||||
ImageButtonType {
|
// KeyNavigation.tab: labelWithButton3
|
||||||
id: openFolderButton
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
|
|
||||||
implicitWidth: 56
|
clickedFunction: function() {
|
||||||
implicitHeight: 56
|
var headerText = qsTr("Clear logs?")
|
||||||
|
var yesButtonText = qsTr("Continue")
|
||||||
|
var noButtonText = qsTr("Cancel")
|
||||||
|
|
||||||
image: "qrc:/images/controls/folder-open.svg"
|
var yesButtonFunction = function() {
|
||||||
KeyNavigation.tab: saveButton
|
PageController.showBusyIndicator(true)
|
||||||
|
SettingsController.clearLogs()
|
||||||
onClicked: SettingsController.openLogsFolder()
|
PageController.showBusyIndicator(false)
|
||||||
Keys.onReturnPressed: openFolderButton.clicked()
|
PageController.showNotificationMessage(qsTr("Logs have been cleaned up"))
|
||||||
Keys.onEnterPressed: openFolderButton.clicked()
|
if (!GC.isMobile()) {
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
var noButtonFunction = function() {
|
||||||
CaptionTextType {
|
if (!GC.isMobile()) {
|
||||||
horizontalAlignment: Text.AlignHCenter
|
focusItem.forceActiveFocus()
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
text: qsTr("Open folder with logs")
|
|
||||||
color: AmneziaStyle.color.paleGray
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
Layout.alignment: Qt.AlignBaseline
|
|
||||||
Layout.preferredWidth: root.width / ( GC.isMobile() ? 2 : 3 )
|
|
||||||
|
|
||||||
ImageButtonType {
|
|
||||||
id: saveButton
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
|
|
||||||
implicitWidth: 56
|
|
||||||
implicitHeight: 56
|
|
||||||
|
|
||||||
image: "qrc:/images/controls/save.svg"
|
|
||||||
KeyNavigation.tab: clearButton
|
|
||||||
|
|
||||||
Keys.onReturnPressed: saveButton.clicked()
|
|
||||||
Keys.onEnterPressed: saveButton.clicked()
|
|
||||||
onClicked: {
|
|
||||||
var fileName = ""
|
|
||||||
if (GC.isMobile()) {
|
|
||||||
fileName = "AmneziaVPN.log"
|
|
||||||
} else {
|
|
||||||
fileName = SystemController.getFileName(qsTr("Save"),
|
|
||||||
qsTr("Logs files (*.log)"),
|
|
||||||
StandardPaths.standardLocations(StandardPaths.DocumentsLocation) + "/AmneziaVPN",
|
|
||||||
true,
|
|
||||||
".log")
|
|
||||||
}
|
|
||||||
if (fileName !== "") {
|
|
||||||
PageController.showBusyIndicator(true)
|
|
||||||
SettingsController.exportLogsFile(fileName)
|
|
||||||
PageController.showBusyIndicator(false)
|
|
||||||
PageController.showNotificationMessage(qsTr("Logs file saved"))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CaptionTextType {
|
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
||||||
horizontalAlignment: Text.AlignHCenter
|
}
|
||||||
Layout.fillWidth: true
|
}
|
||||||
|
|
||||||
text: qsTr("Save logs to file")
|
ListItemTitleType {
|
||||||
color: AmneziaStyle.color.paleGray
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 8
|
||||||
|
Layout.leftMargin: 16
|
||||||
|
Layout.rightMargin: 16
|
||||||
|
|
||||||
|
text: qsTr("Client logs")
|
||||||
|
}
|
||||||
|
|
||||||
|
ParagraphTextType {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 8
|
||||||
|
Layout.leftMargin: 16
|
||||||
|
Layout.rightMargin: 16
|
||||||
|
|
||||||
|
color: AmneziaStyle.color.mutedGray
|
||||||
|
text: qsTr("AmneziaVPN logs")
|
||||||
|
}
|
||||||
|
|
||||||
|
LabelWithButtonType {
|
||||||
|
// id: labelWithButton2
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: -8
|
||||||
|
Layout.bottomMargin: -8
|
||||||
|
|
||||||
|
text: qsTr("Open logs folder")
|
||||||
|
leftImageSource: "qrc:/images/controls/folder-open.svg"
|
||||||
|
isSmallLeftImage: true
|
||||||
|
|
||||||
|
// KeyNavigation.tab: labelWithButton3
|
||||||
|
|
||||||
|
clickedFunction: function() {
|
||||||
|
SettingsController.openLogsFolder()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DividerType {}
|
||||||
|
|
||||||
|
LabelWithButtonType {
|
||||||
|
// id: labelWithButton2
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: -8
|
||||||
|
Layout.bottomMargin: -8
|
||||||
|
|
||||||
|
text: qsTr("Export logs")
|
||||||
|
leftImageSource: "qrc:/images/controls/save.svg"
|
||||||
|
isSmallLeftImage: true
|
||||||
|
|
||||||
|
// KeyNavigation.tab: labelWithButton3
|
||||||
|
|
||||||
|
clickedFunction: function() {
|
||||||
|
var fileName = ""
|
||||||
|
if (GC.isMobile()) {
|
||||||
|
fileName = "AmneziaVPN.log"
|
||||||
|
} else {
|
||||||
|
fileName = SystemController.getFileName(qsTr("Save"),
|
||||||
|
qsTr("Logs files (*.log)"),
|
||||||
|
StandardPaths.standardLocations(StandardPaths.DocumentsLocation) + "/AmneziaVPN",
|
||||||
|
true,
|
||||||
|
".log")
|
||||||
|
}
|
||||||
|
if (fileName !== "") {
|
||||||
|
PageController.showBusyIndicator(true)
|
||||||
|
SettingsController.exportLogsFile(fileName)
|
||||||
|
PageController.showBusyIndicator(false)
|
||||||
|
PageController.showNotificationMessage(qsTr("Logs file saved"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
DividerType {}
|
||||||
Layout.alignment: Qt.AlignBaseline
|
|
||||||
Layout.preferredWidth: root.width / ( GC.isMobile() ? 2 : 3 )
|
|
||||||
|
|
||||||
ImageButtonType {
|
ListItemTitleType {
|
||||||
id: clearButton
|
visible: !GC.isMobile()
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
|
|
||||||
implicitWidth: 56
|
Layout.fillWidth: true
|
||||||
implicitHeight: 56
|
Layout.topMargin: 32
|
||||||
|
Layout.leftMargin: 16
|
||||||
|
Layout.rightMargin: 16
|
||||||
|
|
||||||
image: "qrc:/images/controls/delete.svg"
|
text: qsTr("Service logs")
|
||||||
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
}
|
||||||
|
|
||||||
Keys.onReturnPressed: clearButton.clicked()
|
ParagraphTextType {
|
||||||
Keys.onEnterPressed: clearButton.clicked()
|
visible: !GC.isMobile()
|
||||||
onClicked: function() {
|
|
||||||
var headerText = qsTr("Clear logs?")
|
|
||||||
var yesButtonText = qsTr("Continue")
|
|
||||||
var noButtonText = qsTr("Cancel")
|
|
||||||
|
|
||||||
var yesButtonFunction = function() {
|
Layout.fillWidth: true
|
||||||
PageController.showBusyIndicator(true)
|
Layout.topMargin: 8
|
||||||
SettingsController.clearLogs()
|
Layout.leftMargin: 16
|
||||||
PageController.showBusyIndicator(false)
|
Layout.rightMargin: 16
|
||||||
PageController.showNotificationMessage(qsTr("Logs have been cleaned up"))
|
|
||||||
if (!GC.isMobile()) {
|
|
||||||
focusItem.forceActiveFocus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var noButtonFunction = function() {
|
|
||||||
if (!GC.isMobile()) {
|
|
||||||
focusItem.forceActiveFocus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
color: AmneziaStyle.color.mutedGray
|
||||||
}
|
text: qsTr("AmneziaVPN-service logs")
|
||||||
|
}
|
||||||
|
|
||||||
|
LabelWithButtonType {
|
||||||
|
// id: labelWithButton2
|
||||||
|
|
||||||
|
visible: !GC.isMobile()
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: -8
|
||||||
|
Layout.bottomMargin: -8
|
||||||
|
|
||||||
|
text: qsTr("Open logs folder")
|
||||||
|
leftImageSource: "qrc:/images/controls/folder-open.svg"
|
||||||
|
isSmallLeftImage: true
|
||||||
|
|
||||||
|
// KeyNavigation.tab: labelWithButton3
|
||||||
|
|
||||||
|
clickedFunction: function() {
|
||||||
|
SettingsController.openServiceLogsFolder()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DividerType {
|
||||||
|
visible: !GC.isMobile()
|
||||||
|
}
|
||||||
|
|
||||||
|
LabelWithButtonType {
|
||||||
|
// id: labelWithButton2
|
||||||
|
|
||||||
|
visible: !GC.isMobile()
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: -8
|
||||||
|
Layout.bottomMargin: -8
|
||||||
|
|
||||||
|
text: qsTr("Export logs")
|
||||||
|
leftImageSource: "qrc:/images/controls/save.svg"
|
||||||
|
isSmallLeftImage: true
|
||||||
|
|
||||||
|
// KeyNavigation.tab: labelWithButton3
|
||||||
|
|
||||||
|
clickedFunction: function() {
|
||||||
|
var fileName = ""
|
||||||
|
if (GC.isMobile()) {
|
||||||
|
fileName = "AmneziaVPN-service.log"
|
||||||
|
} else {
|
||||||
|
fileName = SystemController.getFileName(qsTr("Save"),
|
||||||
|
qsTr("Logs files (*.log)"),
|
||||||
|
StandardPaths.standardLocations(StandardPaths.DocumentsLocation) + "/AmneziaVPN-service",
|
||||||
|
true,
|
||||||
|
".log")
|
||||||
}
|
}
|
||||||
|
if (fileName !== "") {
|
||||||
CaptionTextType {
|
PageController.showBusyIndicator(true)
|
||||||
horizontalAlignment: Text.AlignHCenter
|
SettingsController.exportServiceLogsFile(fileName)
|
||||||
Layout.fillWidth: true
|
PageController.showBusyIndicator(false)
|
||||||
|
PageController.showNotificationMessage(qsTr("Logs file saved"))
|
||||||
text: qsTr("Clear logs")
|
|
||||||
color: AmneziaStyle.color.paleGray
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DividerType {
|
||||||
|
visible: !GC.isMobile()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,51 @@ PageType {
|
||||||
Layout.leftMargin: 16
|
Layout.leftMargin: 16
|
||||||
|
|
||||||
headerText: qsTr("Connection")
|
headerText: qsTr("Connection")
|
||||||
|
|
||||||
|
actionButtonImage: PageController.isStartPageVisible() ? "qrc:/images/controls/more-vertical.svg" : ""
|
||||||
|
actionButtonFunction: function() {
|
||||||
|
moreActionsDrawer.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawerType2 {
|
||||||
|
id: moreActionsDrawer
|
||||||
|
|
||||||
|
parent: root
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
expandedHeight: root.height * 0.35
|
||||||
|
|
||||||
|
expandedContent: ColumnLayout {
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.leftMargin: 16
|
||||||
|
anchors.rightMargin: 16
|
||||||
|
|
||||||
|
HeaderType {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 32
|
||||||
|
|
||||||
|
headerText: qsTr("Settings")
|
||||||
|
}
|
||||||
|
|
||||||
|
SwitcherType {
|
||||||
|
id: switcher
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
|
text: qsTr("Enable logs")
|
||||||
|
|
||||||
|
checked: SettingsController.isLoggingEnabled
|
||||||
|
onCheckedChanged: {
|
||||||
|
if (checked !== SettingsController.isLoggingEnabled) {
|
||||||
|
SettingsController.isLoggingEnabled = checked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ParagraphTextType {
|
ParagraphTextType {
|
||||||
|
|
|
@ -202,6 +202,14 @@ PageType {
|
||||||
PageController.showNotificationMessage(qsTr("Settings restored from backup file"))
|
PageController.showNotificationMessage(qsTr("Settings restored from backup file"))
|
||||||
PageController.goToPageHome()
|
PageController.goToPageHome()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onLoggingStateChanged() {
|
||||||
|
if (SettingsController.isLoggingEnabled) {
|
||||||
|
var message = qsTr("Logging is enabled. Note that logs will be automatically" +
|
||||||
|
"disabled after 14 days, and all log files will be deleted.")
|
||||||
|
PageController.showNotificationMessage(message)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StackViewType {
|
StackViewType {
|
||||||
|
|
|
@ -69,22 +69,6 @@ QString Utils::JsonToString(const QJsonArray &array, QJsonDocument::JsonFormat f
|
||||||
return doc.toJson(format);
|
return doc.toJson(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Utils::systemLogPath()
|
|
||||||
{
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
QStringList locationList = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
|
|
||||||
QString primaryLocation = "ProgramData";
|
|
||||||
foreach (const QString &location, locationList) {
|
|
||||||
if (location.contains(primaryLocation)) {
|
|
||||||
return QString("%1/%2/log").arg(location).arg(APPLICATION_NAME);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QString();
|
|
||||||
#else
|
|
||||||
return QString("/var/log/%1").arg(APPLICATION_NAME);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Utils::initializePath(const QString &path)
|
bool Utils::initializePath(const QString &path)
|
||||||
{
|
{
|
||||||
QDir dir;
|
QDir dir;
|
||||||
|
|
|
@ -23,7 +23,6 @@ public:
|
||||||
static QJsonObject JsonFromString(const QString &string);
|
static QJsonObject JsonFromString(const QString &string);
|
||||||
static QString executable(const QString &baseName, bool absPath);
|
static QString executable(const QString &baseName, bool absPath);
|
||||||
static QString usrExecutable(const QString &baseName);
|
static QString usrExecutable(const QString &baseName);
|
||||||
static QString systemLogPath();
|
|
||||||
static bool createEmptyFile(const QString &path);
|
static bool createEmptyFile(const QString &path);
|
||||||
static bool initializePath(const QString &path);
|
static bool initializePath(const QString &path);
|
||||||
|
|
||||||
|
|
|
@ -4,18 +4,18 @@
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QMetaEnum>
|
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
|
#include <QMetaEnum>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "version.h"
|
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
#ifdef AMNEZIA_DESKTOP
|
#ifdef AMNEZIA_DESKTOP
|
||||||
#include <core/ipcclient.h>
|
#include <core/ipcclient.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Q_OS_IOS
|
#ifdef Q_OS_IOS
|
||||||
|
@ -25,8 +25,9 @@
|
||||||
QFile Logger::m_file;
|
QFile Logger::m_file;
|
||||||
QTextStream Logger::m_textStream;
|
QTextStream Logger::m_textStream;
|
||||||
QString Logger::m_logFileName = QString("%1.log").arg(APPLICATION_NAME);
|
QString Logger::m_logFileName = QString("%1.log").arg(APPLICATION_NAME);
|
||||||
|
QString Logger::m_serviceLogFileName = QString("%1.log").arg(SERVICE_NAME);
|
||||||
|
|
||||||
void debugMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg)
|
void debugMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
|
||||||
{
|
{
|
||||||
if (msg.simplified().isEmpty()) {
|
if (msg.simplified().isEmpty()) {
|
||||||
return;
|
return;
|
||||||
|
@ -37,12 +38,12 @@ void debugMessageHandler(QtMsgType type, const QMessageLogContext& context, cons
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg.startsWith("Unknown property") || msg.startsWith("Could not create pixmap") || msg.startsWith("Populating font") || msg.startsWith("stale focus object")) {
|
if (msg.startsWith("Unknown property") || msg.startsWith("Could not create pixmap") || msg.startsWith("Populating font")
|
||||||
|
|| msg.startsWith("stale focus object")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::m_textStream << qFormatLogMessage(type, context, msg) << Qt::endl << Qt::flush;
|
Logger::m_textStream << qFormatLogMessage(type, context, msg) << Qt::endl << Qt::flush;
|
||||||
Logger::appendAllLog(qFormatLogMessage(type, context, msg));
|
|
||||||
|
|
||||||
std::cout << qFormatLogMessage(type, context, msg).toStdString() << std::endl << std::flush;
|
std::cout << qFormatLogMessage(type, context, msg).toStdString() << std::endl << std::flush;
|
||||||
}
|
}
|
||||||
|
@ -53,36 +54,24 @@ Logger &Logger::Instance()
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Logger::appendSshLog(const QString &log)
|
bool Logger::init(bool isServiceLogger)
|
||||||
{
|
{
|
||||||
QString dt = QDateTime::currentDateTime().toString();
|
QString path = isServiceLogger ? systemLogDir() : userLogsDir();
|
||||||
Instance().m_sshLog.append(dt + ": " + log + "\n");
|
QString logFileName = isServiceLogger ? m_serviceLogFileName : m_logFileName ;
|
||||||
emit Instance().sshLogChanged(Instance().sshLog());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Logger::appendAllLog(const QString &log)
|
|
||||||
{
|
|
||||||
Instance().m_allLog.append(log + "\n");
|
|
||||||
emit Instance().allLogChanged(Instance().allLog());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Logger::init()
|
|
||||||
{
|
|
||||||
qSetMessagePattern("%{time yyyy-MM-dd hh:mm:ss} %{type} %{message}");
|
|
||||||
|
|
||||||
QString path = userLogsDir();
|
|
||||||
QDir appDir(path);
|
QDir appDir(path);
|
||||||
if (!appDir.mkpath(path)) {
|
if (!appDir.mkpath(path)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_file.setFileName(appDir.filePath(m_logFileName));
|
m_file.setFileName(appDir.filePath(logFileName));
|
||||||
if (!m_file.open(QIODevice::Append)) {
|
if (!m_file.open(QIODevice::Append)) {
|
||||||
qWarning() << "Cannot open log file:" << m_logFileName;
|
qWarning() << "Cannot open log file:" << logFileName;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_file.setTextModeEnabled(true);
|
m_file.setTextModeEnabled(true);
|
||||||
m_textStream.setDevice(&m_file);
|
m_textStream.setDevice(&m_file);
|
||||||
|
qSetMessagePattern("%{time yyyy-MM-dd hh:mm:ss} %{type} %{message}");
|
||||||
|
|
||||||
#if !defined(QT_DEBUG) || defined(Q_OS_IOS)
|
#if !defined(QT_DEBUG) || defined(Q_OS_IOS)
|
||||||
qInstallMessageHandler(debugMessageHandler);
|
qInstallMessageHandler(debugMessageHandler);
|
||||||
|
@ -99,7 +88,8 @@ void Logger::deInit()
|
||||||
m_file.close();
|
m_file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Logger::setServiceLogsEnabled(bool enabled) {
|
bool Logger::setServiceLogsEnabled(bool enabled)
|
||||||
|
{
|
||||||
#ifdef AMNEZIA_DESKTOP
|
#ifdef AMNEZIA_DESKTOP
|
||||||
IpcClient *m_IpcClient = new IpcClient;
|
IpcClient *m_IpcClient = new IpcClient;
|
||||||
|
|
||||||
|
@ -112,8 +102,7 @@ bool Logger::setServiceLogsEnabled(bool enabled) {
|
||||||
|
|
||||||
if (m_IpcClient->Interface()) {
|
if (m_IpcClient->Interface()) {
|
||||||
m_IpcClient->Interface()->setLogsEnabled(enabled);
|
m_IpcClient->Interface()->setLogsEnabled(enabled);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
qWarning() << "Error occurred setting up service logs";
|
qWarning() << "Error occurred setting up service logs";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -127,11 +116,32 @@ QString Logger::userLogsDir()
|
||||||
return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/log";
|
return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/log";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString Logger::systemLogDir()
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
QStringList locationList = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
|
||||||
|
QString primaryLocation = "ProgramData";
|
||||||
|
foreach (const QString &location, locationList) {
|
||||||
|
if (location.contains(primaryLocation)) {
|
||||||
|
return QString("%1/%2/log").arg(location).arg(APPLICATION_NAME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QString();
|
||||||
|
#else
|
||||||
|
return QString("/var/log/%1").arg(APPLICATION_NAME);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
QString Logger::userLogsFilePath()
|
QString Logger::userLogsFilePath()
|
||||||
{
|
{
|
||||||
return userLogsDir() + QDir::separator() + m_logFileName;
|
return userLogsDir() + QDir::separator() + m_logFileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString Logger::serviceLogsFilePath()
|
||||||
|
{
|
||||||
|
return systemLogDir() + QDir::separator() + m_serviceLogFileName;
|
||||||
|
}
|
||||||
|
|
||||||
QString Logger::getLogFile()
|
QString Logger::getLogFile()
|
||||||
{
|
{
|
||||||
m_file.flush();
|
m_file.flush();
|
||||||
|
@ -139,18 +149,32 @@ QString Logger::getLogFile()
|
||||||
|
|
||||||
file.open(QIODevice::ReadOnly);
|
file.open(QIODevice::ReadOnly);
|
||||||
QString qtLog = file.readAll();
|
QString qtLog = file.readAll();
|
||||||
|
|
||||||
#ifdef Q_OS_IOS
|
#ifdef Q_OS_IOS
|
||||||
return QString().fromStdString(AmneziaVPN::swiftUpdateLogData(qtLog.toStdString()));
|
return QString().fromStdString(AmneziaVPN::swiftUpdateLogData(qtLog.toStdString()));
|
||||||
#else
|
#else
|
||||||
return qtLog;
|
return qtLog;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Logger::openLogsFolder()
|
QString Logger::getServiceLogFile()
|
||||||
{
|
{
|
||||||
QString path = userLogsDir();
|
m_file.flush();
|
||||||
|
QFile file(serviceLogsFilePath());
|
||||||
|
|
||||||
|
file.open(QIODevice::ReadOnly);
|
||||||
|
QString qtLog = file.readAll();
|
||||||
|
|
||||||
|
#ifdef Q_OS_IOS
|
||||||
|
return QString().fromStdString(AmneziaVPN::swiftUpdateLogData(qtLog.toStdString()));
|
||||||
|
#else
|
||||||
|
return qtLog;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Logger::openLogsFolder(bool isServiceLogger)
|
||||||
|
{
|
||||||
|
QString path = isServiceLogger ? systemLogDir() : userLogsDir();
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
path = "file:///" + path;
|
path = "file:///" + path;
|
||||||
#endif
|
#endif
|
||||||
|
@ -161,38 +185,23 @@ bool Logger::openLogsFolder()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Logger::openServiceLogsFolder()
|
void Logger::clearLogs(bool isServiceLogger)
|
||||||
{
|
|
||||||
QString path = Utils::systemLogPath();
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
path = "file:///" + path;
|
|
||||||
#endif
|
|
||||||
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Logger::appLogFileNamePath()
|
|
||||||
{
|
|
||||||
return m_file.fileName();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Logger::clearLogs()
|
|
||||||
{
|
{
|
||||||
bool isLogActive = m_file.isOpen();
|
bool isLogActive = m_file.isOpen();
|
||||||
m_file.close();
|
m_file.close();
|
||||||
|
|
||||||
QFile file(userLogsFilePath());
|
QFile file(isServiceLogger ? serviceLogsFilePath() : userLogsFilePath());
|
||||||
|
|
||||||
file.open(QIODevice::WriteOnly | QIODevice::Truncate);
|
file.open(QIODevice::WriteOnly | QIODevice::Truncate);
|
||||||
file.resize(0);
|
file.resize(0);
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
#ifdef Q_OS_IOS
|
#ifdef Q_OS_IOS
|
||||||
AmneziaVPN::swiftDeleteLog();
|
AmneziaVPN::swiftDeleteLog();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (isLogActive) {
|
if (isLogActive) {
|
||||||
init();
|
init(isServiceLogger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,8 +219,7 @@ void Logger::clearServiceLogs()
|
||||||
|
|
||||||
if (m_IpcClient->Interface()) {
|
if (m_IpcClient->Interface()) {
|
||||||
m_IpcClient->Interface()->clearLogs();
|
m_IpcClient->Interface()->clearLogs();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
qWarning() << "Error occurred cleaning up service logs";
|
qWarning() << "Error occurred cleaning up service logs";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -219,26 +227,41 @@ void Logger::clearServiceLogs()
|
||||||
|
|
||||||
void Logger::cleanUp()
|
void Logger::cleanUp()
|
||||||
{
|
{
|
||||||
clearLogs();
|
clearLogs(false);
|
||||||
QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
|
QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
|
||||||
dir.removeRecursively();
|
dir.removeRecursively();
|
||||||
|
|
||||||
clearServiceLogs();
|
clearLogs(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::Log::Log(Logger* logger, LogLevel logLevel)
|
Logger::Log::Log(Logger *logger, LogLevel logLevel) : m_logger(logger), m_logLevel(logLevel), m_data(new Data())
|
||||||
: m_logger(logger), m_logLevel(logLevel), m_data(new Data()) {}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Logger::Log::~Log() {
|
Logger::Log::~Log()
|
||||||
|
{
|
||||||
qDebug() << "Amnezia" << m_logger->className() << m_data->m_buffer.trimmed();
|
qDebug() << "Amnezia" << m_logger->className() << m_data->m_buffer.trimmed();
|
||||||
delete m_data;
|
delete m_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::Log Logger::error() { return Log(this, LogLevel::Error); }
|
Logger::Log Logger::error()
|
||||||
Logger::Log Logger::warning() { return Log(this, LogLevel::Warning); }
|
{
|
||||||
Logger::Log Logger::info() { return Log(this, LogLevel::Info); }
|
return Log(this, LogLevel::Error);
|
||||||
Logger::Log Logger::debug() { return Log(this, LogLevel::Debug); }
|
}
|
||||||
QString Logger::sensitive(const QString& input) {
|
Logger::Log Logger::warning()
|
||||||
|
{
|
||||||
|
return Log(this, LogLevel::Warning);
|
||||||
|
}
|
||||||
|
Logger::Log Logger::info()
|
||||||
|
{
|
||||||
|
return Log(this, LogLevel::Info);
|
||||||
|
}
|
||||||
|
Logger::Log Logger::debug()
|
||||||
|
{
|
||||||
|
return Log(this, LogLevel::Debug);
|
||||||
|
}
|
||||||
|
QString Logger::sensitive(const QString &input)
|
||||||
|
{
|
||||||
#ifdef Q_DEBUG
|
#ifdef Q_DEBUG
|
||||||
return input;
|
return input;
|
||||||
#else
|
#else
|
||||||
|
@ -247,48 +270,51 @@ QString Logger::sensitive(const QString& input) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define CREATE_LOG_OP_REF(x) \
|
||||||
#define CREATE_LOG_OP_REF(x) \
|
Logger::Log &Logger::Log::operator<<(x t) \
|
||||||
Logger::Log& Logger::Log::operator<<(x t) { \
|
{ \
|
||||||
m_data->m_ts << t << ' '; \
|
m_data->m_ts << t << ' '; \
|
||||||
return *this; \
|
return *this; \
|
||||||
}
|
}
|
||||||
|
|
||||||
CREATE_LOG_OP_REF(uint64_t);
|
CREATE_LOG_OP_REF(uint64_t);
|
||||||
CREATE_LOG_OP_REF(const char*);
|
CREATE_LOG_OP_REF(const char *);
|
||||||
CREATE_LOG_OP_REF(const QString&);
|
CREATE_LOG_OP_REF(const QString &);
|
||||||
CREATE_LOG_OP_REF(const QByteArray&);
|
CREATE_LOG_OP_REF(const QByteArray &);
|
||||||
CREATE_LOG_OP_REF(const void*);
|
CREATE_LOG_OP_REF(const void *);
|
||||||
|
|
||||||
#undef CREATE_LOG_OP_REF
|
#undef CREATE_LOG_OP_REF
|
||||||
|
|
||||||
Logger::Log& Logger::Log::operator<<(const QStringList& t) {
|
Logger::Log &Logger::Log::operator<<(const QStringList &t)
|
||||||
|
{
|
||||||
m_data->m_ts << '[' << t.join(",") << ']' << ' ';
|
m_data->m_ts << '[' << t.join(",") << ']' << ' ';
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::Log& Logger::Log::operator<<(const QJsonObject& t) {
|
Logger::Log &Logger::Log::operator<<(const QJsonObject &t)
|
||||||
|
{
|
||||||
m_data->m_ts << QJsonDocument(t).toJson(QJsonDocument::Indented) << ' ';
|
m_data->m_ts << QJsonDocument(t).toJson(QJsonDocument::Indented) << ' ';
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::Log& Logger::Log::operator<<(QTextStreamFunction t) {
|
Logger::Log &Logger::Log::operator<<(QTextStreamFunction t)
|
||||||
|
{
|
||||||
m_data->m_ts << t;
|
m_data->m_ts << t;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Logger::Log::addMetaEnum(quint64 value, const QMetaObject* meta,
|
void Logger::Log::addMetaEnum(quint64 value, const QMetaObject *meta, const char *name)
|
||||||
const char* name) {
|
{
|
||||||
QMetaEnum me = meta->enumerator(meta->indexOfEnumerator(name));
|
QMetaEnum me = meta->enumerator(meta->indexOfEnumerator(name));
|
||||||
|
|
||||||
QString out;
|
QString out;
|
||||||
QTextStream ts(&out);
|
QTextStream ts(&out);
|
||||||
|
|
||||||
if (const char* scope = me.scope()) {
|
if (const char *scope = me.scope()) {
|
||||||
ts << scope << "::";
|
ts << scope << "::";
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* key = me.valueToKey(static_cast<int>(value));
|
const char *key = me.valueToKey(static_cast<int>(value));
|
||||||
const bool scoped = me.isScoped();
|
const bool scoped = me.isScoped();
|
||||||
if (scoped || !key) {
|
if (scoped || !key) {
|
||||||
ts << me.enumName() << (!key ? "(" : "::");
|
ts << me.enumName() << (!key ? "(" : "::");
|
114
common/logger/logger.h
Normal file
114
common/logger/logger.h
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
#ifndef LOGGER_H
|
||||||
|
#define LOGGER_H
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QString>
|
||||||
|
#include <QTextStream>
|
||||||
|
|
||||||
|
#include "mozilla/shared/loglevel.h"
|
||||||
|
|
||||||
|
class Logger : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
static Logger &Instance();
|
||||||
|
|
||||||
|
static bool init(bool isServiceLogger);
|
||||||
|
static void deInit();
|
||||||
|
|
||||||
|
static bool setServiceLogsEnabled(bool enabled);
|
||||||
|
|
||||||
|
static bool openLogsFolder(bool isServiceLogger);
|
||||||
|
|
||||||
|
static void clearLogs(bool isServiceLogger);
|
||||||
|
static void clearServiceLogs();
|
||||||
|
static void cleanUp();
|
||||||
|
|
||||||
|
static QString userLogsFilePath();
|
||||||
|
static QString serviceLogsFilePath();
|
||||||
|
static QString systemLogDir();
|
||||||
|
|
||||||
|
static QString getLogFile();
|
||||||
|
static QString getServiceLogFile();
|
||||||
|
|
||||||
|
// compat with Mozilla logger
|
||||||
|
Logger(const QString &className)
|
||||||
|
{
|
||||||
|
m_className = className;
|
||||||
|
}
|
||||||
|
const QString &className() const
|
||||||
|
{
|
||||||
|
return m_className;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Log
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Log(Logger *logger, LogLevel level);
|
||||||
|
~Log();
|
||||||
|
|
||||||
|
Log &operator<<(uint64_t t);
|
||||||
|
Log &operator<<(const char *t);
|
||||||
|
Log &operator<<(const QString &t);
|
||||||
|
Log &operator<<(const QStringList &t);
|
||||||
|
Log &operator<<(const QByteArray &t);
|
||||||
|
Log &operator<<(const QJsonObject &t);
|
||||||
|
Log &operator<<(QTextStreamFunction t);
|
||||||
|
Log &operator<<(const void *t);
|
||||||
|
|
||||||
|
// Q_ENUM
|
||||||
|
template<typename T> typename std::enable_if<QtPrivate::IsQEnumHelper<T>::Value, Log &>::type operator<<(T t)
|
||||||
|
{
|
||||||
|
const QMetaObject *meta = qt_getEnumMetaObject(t);
|
||||||
|
const char *name = qt_getEnumName(t);
|
||||||
|
addMetaEnum(typename QFlags<T>::Int(t), meta, name);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void addMetaEnum(quint64 value, const QMetaObject *meta, const char *name);
|
||||||
|
|
||||||
|
Logger *m_logger;
|
||||||
|
LogLevel m_logLevel;
|
||||||
|
|
||||||
|
struct Data
|
||||||
|
{
|
||||||
|
Data() : m_ts(&m_buffer, QIODevice::WriteOnly)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QString m_buffer;
|
||||||
|
QTextStream m_ts;
|
||||||
|
};
|
||||||
|
|
||||||
|
Data *m_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
Log error();
|
||||||
|
Log warning();
|
||||||
|
Log info();
|
||||||
|
Log debug();
|
||||||
|
QString sensitive(const QString &input);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Logger() {};
|
||||||
|
Logger(Logger const &) = delete;
|
||||||
|
Logger &operator=(Logger const &) = delete;
|
||||||
|
|
||||||
|
static QString userLogsDir();
|
||||||
|
|
||||||
|
static QFile m_file;
|
||||||
|
static QTextStream m_textStream;
|
||||||
|
static QString m_logFileName;
|
||||||
|
static QString m_serviceLogFileName;
|
||||||
|
|
||||||
|
friend void debugMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg);
|
||||||
|
|
||||||
|
// compat with Mozilla logger
|
||||||
|
QString m_className;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // LOGGER_H
|
|
@ -1,32 +1,32 @@
|
||||||
#include "ipcserver.h"
|
#include "ipcserver.h"
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QLocalSocket>
|
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
#include <QLocalSocket>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
#include "router.h"
|
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
|
#include "router.h"
|
||||||
|
|
||||||
#include "../client/protocols/protocols_defs.h"
|
#include "../client/protocols/protocols_defs.h"
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
#include "tapcontroller_win.h"
|
#include "../client/platforms/windows/daemon/windowsdaemon.h"
|
||||||
#include "../client/platforms/windows/daemon/windowsfirewall.h"
|
#include "../client/platforms/windows/daemon/windowsfirewall.h"
|
||||||
#include "../client/platforms/windows/daemon/windowsdaemon.h"
|
#include "tapcontroller_win.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
#include "../client/platforms/linux/daemon/linuxfirewall.h"
|
#include "../client/platforms/linux/daemon/linuxfirewall.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Q_OS_MACOS
|
#ifdef Q_OS_MACOS
|
||||||
#include "../client/platforms/macos/daemon/macosfirewall.h"
|
#include "../client/platforms/macos/daemon/macosfirewall.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
IpcServer::IpcServer(QObject *parent):
|
IpcServer::IpcServer(QObject *parent) : IpcInterfaceSource(parent)
|
||||||
IpcInterfaceSource(parent)
|
|
||||||
|
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
int IpcServer::createPrivilegedProcess()
|
int IpcServer::createPrivilegedProcess()
|
||||||
{
|
{
|
||||||
|
@ -58,23 +58,10 @@ int IpcServer::createPrivilegedProcess()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
QObject::connect(pd.serverNode.data(), &QRemoteObjectHost::error, this, [pd](QRemoteObjectNode::ErrorCode errorCode) {
|
QObject::connect(pd.serverNode.data(), &QRemoteObjectHost::error, this,
|
||||||
qDebug() << "QRemoteObjectHost::error" << errorCode;
|
[pd](QRemoteObjectNode::ErrorCode errorCode) { qDebug() << "QRemoteObjectHost::error" << errorCode; });
|
||||||
});
|
|
||||||
|
|
||||||
QObject::connect(pd.serverNode.data(), &QRemoteObjectHost::destroyed, this, [pd]() {
|
QObject::connect(pd.serverNode.data(), &QRemoteObjectHost::destroyed, this, [pd]() { qDebug() << "QRemoteObjectHost::destroyed"; });
|
||||||
qDebug() << "QRemoteObjectHost::destroyed";
|
|
||||||
});
|
|
||||||
|
|
||||||
// connect(pd.ipcProcess.data(), &IpcServerProcess::finished, this, [this, pid=m_localpid](int exitCode, QProcess::ExitStatus exitStatus){
|
|
||||||
// qDebug() << "IpcServerProcess finished" << exitCode << exitStatus;
|
|
||||||
//// if (m_processes.contains(pid)) {
|
|
||||||
//// m_processes[pid].ipcProcess.reset();
|
|
||||||
//// m_processes[pid].serverNode.reset();
|
|
||||||
//// m_processes[pid].localServer.reset();
|
|
||||||
//// m_processes.remove(pid);
|
|
||||||
//// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
m_processes.insert(m_localpid, pd);
|
m_processes.insert(m_localpid, pd);
|
||||||
|
|
||||||
|
@ -105,7 +92,7 @@ bool IpcServer::routeDeleteList(const QString &gw, const QStringList &ips)
|
||||||
qDebug() << "IpcServer::routeDeleteList";
|
qDebug() << "IpcServer::routeDeleteList";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return Router::routeDeleteList(gw ,ips);
|
return Router::routeDeleteList(gw, ips);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IpcServer::flushDns()
|
void IpcServer::flushDns()
|
||||||
|
@ -158,12 +145,13 @@ void IpcServer::cleanUp()
|
||||||
qDebug() << "IpcServer::cleanUp";
|
qDebug() << "IpcServer::cleanUp";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Logger::deinit();
|
Logger::deInit();
|
||||||
Logger::cleanUp();
|
Logger::cleanUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IpcServer::clearLogs() {
|
void IpcServer::clearLogs()
|
||||||
Logger::clearLogs();
|
{
|
||||||
|
Logger::clearLogs(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IpcServer::createTun(const QString &dev, const QString &subnet)
|
bool IpcServer::createTun(const QString &dev, const QString &subnet)
|
||||||
|
@ -176,7 +164,7 @@ bool IpcServer::deleteTun(const QString &dev)
|
||||||
return Router::deleteTun(dev);
|
return Router::deleteTun(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IpcServer::updateResolvers(const QString& ifname, const QList<QHostAddress>& resolvers)
|
bool IpcServer::updateResolvers(const QString &ifname, const QList<QHostAddress> &resolvers)
|
||||||
{
|
{
|
||||||
return Router::updateResolvers(ifname, resolvers);
|
return Router::updateResolvers(ifname, resolvers);
|
||||||
}
|
}
|
||||||
|
@ -197,14 +185,12 @@ void IpcServer::setLogsEnabled(bool enabled)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
Logger::init();
|
Logger::init(true);
|
||||||
}
|
} else {
|
||||||
else {
|
Logger::deInit();
|
||||||
Logger::deinit();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool IpcServer::enableKillSwitch(const QJsonObject &configStr, int vpnAdapterIndex)
|
bool IpcServer::enableKillSwitch(const QJsonObject &configStr, int vpnAdapterIndex)
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
|
@ -220,13 +206,11 @@ bool IpcServer::enableKillSwitch(const QJsonObject &configStr, int vpnAdapterInd
|
||||||
QStringList allownets;
|
QStringList allownets;
|
||||||
QStringList blocknets;
|
QStringList blocknets;
|
||||||
|
|
||||||
if (splitTunnelType == 0)
|
if (splitTunnelType == 0) {
|
||||||
{
|
|
||||||
blockAll = true;
|
blockAll = true;
|
||||||
allowNets = true;
|
allowNets = true;
|
||||||
allownets.append(configStr.value(amnezia::config_key::hostName).toString());
|
allownets.append(configStr.value(amnezia::config_key::hostName).toString());
|
||||||
} else if (splitTunnelType == 1)
|
} else if (splitTunnelType == 1) {
|
||||||
{
|
|
||||||
blockNets = true;
|
blockNets = true;
|
||||||
for (auto v : splitTunnelSites) {
|
for (auto v : splitTunnelSites) {
|
||||||
blocknets.append(v.toString());
|
blocknets.append(v.toString());
|
||||||
|
@ -268,18 +252,17 @@ bool IpcServer::enableKillSwitch(const QJsonObject &configStr, int vpnAdapterInd
|
||||||
|
|
||||||
// double-check + ensure our firewall is installed and enabled. This is necessary as
|
// double-check + ensure our firewall is installed and enabled. This is necessary as
|
||||||
// other software may disable pfctl before re-enabling with their own rules (e.g other VPNs)
|
// other software may disable pfctl before re-enabling with their own rules (e.g other VPNs)
|
||||||
if (!MacOSFirewall::isInstalled()) MacOSFirewall::install();
|
if (!MacOSFirewall::isInstalled())
|
||||||
|
MacOSFirewall::install();
|
||||||
|
|
||||||
MacOSFirewall::ensureRootAnchorPriority();
|
MacOSFirewall::ensureRootAnchorPriority();
|
||||||
MacOSFirewall::setAnchorEnabled(QStringLiteral("000.allowLoopback"), true);
|
MacOSFirewall::setAnchorEnabled(QStringLiteral("000.allowLoopback"), true);
|
||||||
MacOSFirewall::setAnchorEnabled(QStringLiteral("100.blockAll"), blockAll);
|
MacOSFirewall::setAnchorEnabled(QStringLiteral("100.blockAll"), blockAll);
|
||||||
MacOSFirewall::setAnchorEnabled(QStringLiteral("110.allowNets"), allowNets);
|
MacOSFirewall::setAnchorEnabled(QStringLiteral("110.allowNets"), allowNets);
|
||||||
MacOSFirewall::setAnchorTable(QStringLiteral("110.allowNets"), allowNets,
|
MacOSFirewall::setAnchorTable(QStringLiteral("110.allowNets"), allowNets, QStringLiteral("allownets"), allownets);
|
||||||
QStringLiteral("allownets"), allownets);
|
|
||||||
|
|
||||||
MacOSFirewall::setAnchorEnabled(QStringLiteral("120.blockNets"), blockNets);
|
MacOSFirewall::setAnchorEnabled(QStringLiteral("120.blockNets"), blockNets);
|
||||||
MacOSFirewall::setAnchorTable(QStringLiteral("120.blockNets"), blockNets,
|
MacOSFirewall::setAnchorTable(QStringLiteral("120.blockNets"), blockNets, QStringLiteral("blocknets"), blocknets);
|
||||||
QStringLiteral("blocknets"), blocknets);
|
|
||||||
MacOSFirewall::setAnchorEnabled(QStringLiteral("200.allowVPN"), true);
|
MacOSFirewall::setAnchorEnabled(QStringLiteral("200.allowVPN"), true);
|
||||||
MacOSFirewall::setAnchorEnabled(QStringLiteral("250.blockIPv6"), true);
|
MacOSFirewall::setAnchorEnabled(QStringLiteral("250.blockIPv6"), true);
|
||||||
MacOSFirewall::setAnchorEnabled(QStringLiteral("290.allowDHCP"), true);
|
MacOSFirewall::setAnchorEnabled(QStringLiteral("290.allowDHCP"), true);
|
||||||
|
@ -330,10 +313,8 @@ bool IpcServer::enablePeerTraffic(const QJsonObject &configStr)
|
||||||
|
|
||||||
// Use APP split tunnel
|
// Use APP split tunnel
|
||||||
if (splitTunnelType == 0 || splitTunnelType == 2) {
|
if (splitTunnelType == 0 || splitTunnelType == 2) {
|
||||||
config.m_allowedIPAddressRanges.append(
|
config.m_allowedIPAddressRanges.append(IPAddress(QHostAddress("0.0.0.0"), 0));
|
||||||
IPAddress(QHostAddress("0.0.0.0"), 0));
|
config.m_allowedIPAddressRanges.append(IPAddress(QHostAddress("::"), 0));
|
||||||
config.m_allowedIPAddressRanges.append(
|
|
||||||
IPAddress(QHostAddress("::"), 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (splitTunnelType == 1) {
|
if (splitTunnelType == 1) {
|
||||||
|
@ -341,10 +322,9 @@ bool IpcServer::enablePeerTraffic(const QJsonObject &configStr)
|
||||||
QString ipRange = v.toString();
|
QString ipRange = v.toString();
|
||||||
if (ipRange.split('/').size() > 1) {
|
if (ipRange.split('/').size() > 1) {
|
||||||
config.m_allowedIPAddressRanges.append(
|
config.m_allowedIPAddressRanges.append(
|
||||||
IPAddress(QHostAddress(ipRange.split('/')[0]), atoi(ipRange.split('/')[1].toLocal8Bit())));
|
IPAddress(QHostAddress(ipRange.split('/')[0]), atoi(ipRange.split('/')[1].toLocal8Bit())));
|
||||||
} else {
|
} else {
|
||||||
config.m_allowedIPAddressRanges.append(
|
config.m_allowedIPAddressRanges.append(IPAddress(QHostAddress(ipRange), 32));
|
||||||
IPAddress(QHostAddress(ipRange), 32));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -357,7 +337,7 @@ bool IpcServer::enablePeerTraffic(const QJsonObject &configStr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const QJsonValue& i : configStr.value(amnezia::config_key::splitTunnelApps).toArray()) {
|
for (const QJsonValue &i : configStr.value(amnezia::config_key::splitTunnelApps).toArray()) {
|
||||||
if (!i.isString()) {
|
if (!i.isString()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ set(HEADERS
|
||||||
${CMAKE_CURRENT_LIST_DIR}/../../ipc/ipcserver.h
|
${CMAKE_CURRENT_LIST_DIR}/../../ipc/ipcserver.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/../../ipc/ipcserverprocess.h
|
${CMAKE_CURRENT_LIST_DIR}/../../ipc/ipcserverprocess.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/localserver.h
|
${CMAKE_CURRENT_LIST_DIR}/localserver.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/logger.h
|
${CMAKE_CURRENT_LIST_DIR}/../../common/logger/logger.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/router.h
|
${CMAKE_CURRENT_LIST_DIR}/router.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/systemservice.h
|
${CMAKE_CURRENT_LIST_DIR}/systemservice.h
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/version.h
|
${CMAKE_CURRENT_BINARY_DIR}/version.h
|
||||||
|
@ -31,7 +31,7 @@ set(SOURCES
|
||||||
${CMAKE_CURRENT_LIST_DIR}/../../ipc/ipcserver.cpp
|
${CMAKE_CURRENT_LIST_DIR}/../../ipc/ipcserver.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/../../ipc/ipcserverprocess.cpp
|
${CMAKE_CURRENT_LIST_DIR}/../../ipc/ipcserverprocess.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/localserver.cpp
|
${CMAKE_CURRENT_LIST_DIR}/localserver.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/logger.cpp
|
${CMAKE_CURRENT_LIST_DIR}/../../common/logger/logger.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/main.cpp
|
${CMAKE_CURRENT_LIST_DIR}/main.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/router.cpp
|
${CMAKE_CURRENT_LIST_DIR}/router.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/systemservice.cpp
|
${CMAKE_CURRENT_LIST_DIR}/systemservice.cpp
|
||||||
|
@ -238,6 +238,7 @@ include_directories(
|
||||||
${CMAKE_CURRENT_LIST_DIR}
|
${CMAKE_CURRENT_LIST_DIR}
|
||||||
${CMAKE_CURRENT_LIST_DIR}/../../client
|
${CMAKE_CURRENT_LIST_DIR}/../../client
|
||||||
${CMAKE_CURRENT_LIST_DIR}/../../ipc
|
${CMAKE_CURRENT_LIST_DIR}/../../ipc
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/../../common/logger
|
||||||
${CMAKE_CURRENT_BINARY_DIR}
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,185 +0,0 @@
|
||||||
#include "logger.h"
|
|
||||||
|
|
||||||
#include <QDir>
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QMetaEnum>
|
|
||||||
#include <QStandardPaths>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include "version.h"
|
|
||||||
#include "utilities.h"
|
|
||||||
|
|
||||||
QFile Logger::m_file;
|
|
||||||
QTextStream Logger::m_textStream;
|
|
||||||
QString Logger::m_logFileName = QString("%1.log").arg(SERVICE_NAME);
|
|
||||||
|
|
||||||
void debugMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg)
|
|
||||||
{
|
|
||||||
if (msg.simplified().isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger::m_textStream << qFormatLogMessage(type, context, msg) << Qt::endl << Qt::flush;
|
|
||||||
|
|
||||||
std::cout << qFormatLogMessage(type, context, msg).toStdString() << std::endl << std::flush;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Logger::init()
|
|
||||||
{
|
|
||||||
if (m_file.isOpen()) return true;
|
|
||||||
|
|
||||||
QString path = Utils::systemLogPath();
|
|
||||||
QDir appDir(path);
|
|
||||||
if (!appDir.mkpath(path)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
qSetMessagePattern("%{time yyyy-MM-dd hh:mm:ss} %{type} %{message}");
|
|
||||||
|
|
||||||
m_file.setFileName(appDir.filePath(m_logFileName));
|
|
||||||
if (!m_file.open(QIODevice::Append)) {
|
|
||||||
qWarning() << "Cannot open log file:" << m_logFileName;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
m_file.setTextModeEnabled(true);
|
|
||||||
m_textStream.setDevice(&m_file);
|
|
||||||
qInstallMessageHandler(debugMessageHandler);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Logger::deinit()
|
|
||||||
{
|
|
||||||
m_file.close();
|
|
||||||
m_textStream.setDevice(nullptr);
|
|
||||||
qInstallMessageHandler(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Logger::serviceLogFileNamePath()
|
|
||||||
{
|
|
||||||
return m_file.fileName();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Logger::clearLogs()
|
|
||||||
{
|
|
||||||
bool isLogActive = m_file.isOpen();
|
|
||||||
m_file.close();
|
|
||||||
|
|
||||||
|
|
||||||
QString path = Utils::systemLogPath();
|
|
||||||
QDir appDir(path);
|
|
||||||
QFile file;
|
|
||||||
file.setFileName(appDir.filePath(m_logFileName));
|
|
||||||
|
|
||||||
file.open(QIODevice::WriteOnly | QIODevice::Truncate);
|
|
||||||
file.resize(0);
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
if (isLogActive) {
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Logger::cleanUp()
|
|
||||||
{
|
|
||||||
clearLogs();
|
|
||||||
deinit();
|
|
||||||
|
|
||||||
QString path = Utils::systemLogPath();
|
|
||||||
QDir appDir(path);
|
|
||||||
|
|
||||||
{
|
|
||||||
QFile file;
|
|
||||||
file.setFileName(appDir.filePath(m_logFileName));
|
|
||||||
file.remove();
|
|
||||||
}
|
|
||||||
{
|
|
||||||
QFile file;
|
|
||||||
file.setFileName(appDir.filePath("openvpn.log"));
|
|
||||||
file.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef Q_OS_WINDOWS
|
|
||||||
QDir dir(Utils::systemLogPath());
|
|
||||||
dir.removeRecursively();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Logger::Log::Log(Logger* logger, LogLevel logLevel)
|
|
||||||
: m_logger(logger), m_logLevel(logLevel), m_data(new Data()) {}
|
|
||||||
|
|
||||||
Logger::Log::~Log() {
|
|
||||||
qDebug() << "Amnezia" << m_logger->className() << m_data->m_buffer.trimmed();
|
|
||||||
delete m_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger::Log Logger::error() { return Log(this, LogLevel::Error); }
|
|
||||||
Logger::Log Logger::warning() { return Log(this, LogLevel::Warning); }
|
|
||||||
Logger::Log Logger::info() { return Log(this, LogLevel::Info); }
|
|
||||||
Logger::Log Logger::debug() { return Log(this, LogLevel::Debug); }
|
|
||||||
QString Logger::sensitive(const QString& input) {
|
|
||||||
#ifdef Q_DEBUG
|
|
||||||
return input;
|
|
||||||
#else
|
|
||||||
Q_UNUSED(input);
|
|
||||||
return QString(8, 'X');
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define CREATE_LOG_OP_REF(x) \
|
|
||||||
Logger::Log& Logger::Log::operator<<(x t) { \
|
|
||||||
m_data->m_ts << t << ' '; \
|
|
||||||
return *this; \
|
|
||||||
}
|
|
||||||
|
|
||||||
CREATE_LOG_OP_REF(uint64_t);
|
|
||||||
CREATE_LOG_OP_REF(const char*);
|
|
||||||
CREATE_LOG_OP_REF(const QString&);
|
|
||||||
CREATE_LOG_OP_REF(const QByteArray&);
|
|
||||||
CREATE_LOG_OP_REF(const void*);
|
|
||||||
|
|
||||||
#undef CREATE_LOG_OP_REF
|
|
||||||
|
|
||||||
Logger::Log& Logger::Log::operator<<(const QStringList& t) {
|
|
||||||
m_data->m_ts << '[' << t.join(",") << ']' << ' ';
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger::Log& Logger::Log::operator<<(const QJsonObject& t) {
|
|
||||||
m_data->m_ts << QJsonDocument(t).toJson(QJsonDocument::Indented) << ' ';
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger::Log& Logger::Log::operator<<(QTextStreamFunction t) {
|
|
||||||
m_data->m_ts << t;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Logger::Log::addMetaEnum(quint64 value, const QMetaObject* meta,
|
|
||||||
const char* name) {
|
|
||||||
QMetaEnum me = meta->enumerator(meta->indexOfEnumerator(name));
|
|
||||||
|
|
||||||
QString out;
|
|
||||||
QTextStream ts(&out);
|
|
||||||
|
|
||||||
if (const char* scope = me.scope()) {
|
|
||||||
ts << scope << "::";
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* key = me.valueToKey(static_cast<int>(value));
|
|
||||||
const bool scoped = me.isScoped();
|
|
||||||
if (scoped || !key) {
|
|
||||||
ts << me.enumName() << (!key ? "(" : "::");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key) {
|
|
||||||
ts << key;
|
|
||||||
} else {
|
|
||||||
ts << value << ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
m_data->m_ts << out;
|
|
||||||
}
|
|
|
@ -1,83 +0,0 @@
|
||||||
#ifndef LOGGER_H
|
|
||||||
#define LOGGER_H
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QFile>
|
|
||||||
#include <QString>
|
|
||||||
#include <QTextStream>
|
|
||||||
|
|
||||||
#include "mozilla/shared/loglevel.h"
|
|
||||||
|
|
||||||
class Logger
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static bool init();
|
|
||||||
static void deinit();
|
|
||||||
|
|
||||||
static QString serviceLogFileNamePath();
|
|
||||||
|
|
||||||
static void clearLogs();
|
|
||||||
static void cleanUp();
|
|
||||||
|
|
||||||
// compat with Mozilla logger
|
|
||||||
Logger(const QString &className) { m_className = className; }
|
|
||||||
const QString& className() const { return m_className; }
|
|
||||||
|
|
||||||
class Log {
|
|
||||||
public:
|
|
||||||
Log(Logger* logger, LogLevel level);
|
|
||||||
~Log();
|
|
||||||
|
|
||||||
Log& operator<<(uint64_t t);
|
|
||||||
Log& operator<<(const char* t);
|
|
||||||
Log& operator<<(const QString& t);
|
|
||||||
Log& operator<<(const QStringList& t);
|
|
||||||
Log& operator<<(const QByteArray& t);
|
|
||||||
Log& operator<<(const QJsonObject& t);
|
|
||||||
Log& operator<<(QTextStreamFunction t);
|
|
||||||
Log& operator<<(const void* t);
|
|
||||||
|
|
||||||
// Q_ENUM
|
|
||||||
template <typename T>
|
|
||||||
typename std::enable_if<QtPrivate::IsQEnumHelper<T>::Value, Log&>::type
|
|
||||||
operator<<(T t) {
|
|
||||||
const QMetaObject* meta = qt_getEnumMetaObject(t);
|
|
||||||
const char* name = qt_getEnumName(t);
|
|
||||||
addMetaEnum(typename QFlags<T>::Int(t), meta, name);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void addMetaEnum(quint64 value, const QMetaObject* meta, const char* name);
|
|
||||||
|
|
||||||
Logger* m_logger;
|
|
||||||
LogLevel m_logLevel;
|
|
||||||
|
|
||||||
struct Data {
|
|
||||||
Data() : m_ts(&m_buffer, QIODevice::WriteOnly) {}
|
|
||||||
|
|
||||||
QString m_buffer;
|
|
||||||
QTextStream m_ts;
|
|
||||||
};
|
|
||||||
|
|
||||||
Data* m_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
Log error();
|
|
||||||
Log warning();
|
|
||||||
Log info();
|
|
||||||
Log debug();
|
|
||||||
QString sensitive(const QString& input);
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend void debugMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg);
|
|
||||||
|
|
||||||
static QFile m_file;
|
|
||||||
static QString m_logFileName;
|
|
||||||
static QTextStream m_textStream;
|
|
||||||
|
|
||||||
// compat with Mozilla logger
|
|
||||||
QString m_className;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // LOGGER_H
|
|
|
@ -44,7 +44,7 @@ int runApplication(int argc, char** argv)
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
Utils::initializePath(Utils::systemLogPath());
|
Utils::initializePath(Logger::systemLogDir());
|
||||||
|
|
||||||
if (argc >= 2) {
|
if (argc >= 2) {
|
||||||
qInfo() << "Started as console application";
|
qInfo() << "Started as console application";
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue