GODT-2157: Add Sentry to Bridge-Gui

This commit is contained in:
Leander Beernaert
2022-11-28 13:36:36 +01:00
committed by Romain Le Jeune
parent 1c374b59d3
commit 2747f3b492
9 changed files with 123 additions and 6 deletions

View File

@ -80,6 +80,26 @@ qt_standard_project_setup()
set(CMAKE_AUTORCC ON)
message(STATUS "Using Qt ${Qt6_VERSION}")
#*****************************************************************************************************************************************************
# Sentry Native
#*****************************************************************************************************************************************************
find_package(sentry CONFIG REQUIRED)
set(DSN_SENTRY "https://ea31dfe8574849108fb8ba044fec3620@api.protonmail.ch/core/v4/reports/sentry/7")
set(SENTRY_CONFIG_GENERATED_FILE_DIR ${CMAKE_CURRENT_BINARY_DIR}/sentry-generated)
set(SENTRY_CONFIG_FILE ${SENTRY_CONFIG_GENERATED_FILE_DIR}/project_sentry_config.h)
file(GENERATE OUTPUT ${SENTRY_CONFIG_FILE} CONTENT
"// AUTO GENERATED FILE, DO NOT MODIFY\n#pragma once\nconst char* SentryDNS=\"${DSN_SENTRY}\";\nconst char* SentryProductID=\"bridge-mail@${BRIDGE_APP_VERSION}\";\n"
)
if (APPLE)
#TODO: Find a better way to extract this information
install(PROGRAMS "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/tools/sentry-native/crashpad_handler" DESTINATION "${CMAKE_INSTALL_PREFIX}/bridge-gui.app/Contents/MacOS/")
endif()
if (WIN32)
install(PROGRAMS "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/tools/sentry-native/crashpad_handler.exe" DESTINATION "${CMAKE_INSTALL_PREFIX}")
endif()
#*****************************************************************************************************************************************************
# Source files and output
@ -111,6 +131,7 @@ add_executable(bridge-gui
Version.h
QMLBackend.cpp QMLBackend.h
UserList.cpp UserList.h
SentryUtils.cpp SentryUtils.h
${DOCK_ICON_SRC_FILE} DockIcon/DockIcon.h
)
@ -127,13 +148,14 @@ if (WIN32) # on Windows, we add a (non-Qt) resource file that contains the appli
endif()
target_precompile_headers(bridge-gui PRIVATE Pch.h)
target_include_directories(bridge-gui PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(bridge-gui PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${SENTRY_CONFIG_GENERATED_FILE_DIR})
target_link_libraries(bridge-gui
Qt6::Widgets
Qt6::Core
Qt6::Quick
Qt6::Qml
Qt6::QuickControls2
sentry::sentry
bridgepp
)
@ -169,4 +191,4 @@ else()
set(DEPLOY_OS Windows)
endif()
include(Deploy${DEPLOY_OS}.cmake)
include(Deploy${DEPLOY_OS}.cmake)

View File

@ -17,6 +17,7 @@
#include "EventStreamWorker.h"
#include "SentryUtils.h"
#include <bridgepp/GRPC/GRPCClient.h>
#include <bridgepp/Exception/Exception.h>
#include <bridgepp/Log/Log.h>
@ -54,6 +55,7 @@ void EventStreamReader::run()
}
catch (Exception const &e)
{
reportSentryException(SENTRY_LEVEL_ERROR, "Error during event stream read", "Exception", e.what());
emit error(e.qwhat());
}
}

View File

@ -0,0 +1,31 @@
// 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 "SentryUtils.h"
static constexpr const char* LoggerName = "bridge-gui";
void reportSentryEvent(sentry_level_t level, const char* message) {
auto event = sentry_value_new_message_event(level, LoggerName, message);
sentry_capture_event(event);
}
void reportSentryException(sentry_level_t level, const char* message, const char* exceptionType, const char* exception) {
auto event = sentry_value_new_message_event(level, LoggerName, message);
sentry_event_add_exception(event, sentry_value_new_exception(exceptionType, exception));
sentry_capture_event(event);
}

View File

@ -0,0 +1,26 @@
// 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_SENTRYUTILS_H
#define BRIDGE_GUI_SENTRYUTILS_H
#include <sentry.h>
void reportSentryEvent(sentry_level_t level, const char* message);
void reportSentryException(sentry_level_t level, const char* message, const char* exceptionType, const char* exception);
#endif //BRIDGE_GUI_SENTRYUTILS_H

View File

@ -77,7 +77,7 @@ Write-host "Running build for version $bridgeVersion - $buildConfig in $buildDir
git submodule update --init --recursive $vcpkgRoot
. $vcpkgBootstrap -disableMetrics
. $vcpkgExe install grpc:x64-windows --clean-after-build
. $vcpkgExe install sentry-native:x64-windows grpc:x64-windows --clean-after-build
. $vcpkgExe upgrade --no-dry-run
. $cmakeExe -G "Visual Studio 17 2022" -DCMAKE_BUILD_TYPE="$buildConfig" `
-DBRIDGE_APP_FULL_NAME="$bridgeFullName" `

View File

@ -69,12 +69,12 @@ ${VCPKG_BOOTSTRAP} -disableMetrics
check_exit "Failed to bootstrap vcpkg."
if [[ "$OSTYPE" == "darwin"* ]]; then
${VCPKG_EXE} install grpc:arm64-osx-min-11-0 --overlay-triplets=vcpkg/triplets --clean-after-build
${VCPKG_EXE} install sentry-native:arm64-osx-min-11-0 grpc:arm64-osx-min-11-0 --overlay-triplets=vcpkg/triplets --clean-after-build
check_exit "Failed installing gRPC for macOS / Apple Silicon"
${VCPKG_EXE} install grpc:x64-osx-min-11-0 --overlay-triplets=vcpkg/triplets --clean-after-build
${VCPKG_EXE} install sentry-native:x64-osx-min-11-0 grpc:x64-osx-min-11-0 --overlay-triplets=vcpkg/triplets --clean-after-build
check_exit "Failed installing gRPC for macOS / Intel x64"
elif [[ "$OSTYPE" == "linux"* ]]; then
${VCPKG_EXE} install grpc:x64-linux --clean-after-build
${VCPKG_EXE} install sentry-native:x64-linux grpc:x64-linux --clean-after-build
check_exit "Failed installing gRPC for Linux / Intel x64"
else
echo "For Windows, use the build.ps1 Powershell script."

View File

@ -19,12 +19,16 @@
#include "Pch.h"
#include "CommandLine.h"
#include "QMLBackend.h"
#include "SentryUtils.h"
#include "Version.h"
#include <bridgepp/BridgeUtils.h>
#include <bridgepp/Exception/Exception.h>
#include <bridgepp/FocusGRPC/FocusGRPCClient.h>
#include <bridgepp/Log/Log.h>
#include <bridgepp/ProcessMonitor.h>
#include <sentry.h>
#include <project_sentry_config.h>
using namespace bridgepp;
@ -236,6 +240,7 @@ void focusOtherInstance()
catch (Exception const& e)
{
app().log().error(e.qwhat());
reportSentryException(SENTRY_LEVEL_ERROR, "Exception occurred during focusOtherInstance()", "Exception", e.what());
}
}
@ -288,6 +293,25 @@ void closeBridgeApp()
//****************************************************************************************************************************************************
int main(int argc, char *argv[])
{
// Init sentry.
sentry_options_t* options = sentry_options_new();
sentry_options_set_dsn(options, SentryDNS);
{
const QString sentryCachePath = sentryCacheDir();
sentry_options_set_database_path(options, sentryCachePath.toStdString().c_str());
}
sentry_options_set_release(options, SentryProductID);
// Enable this for debugging sentry.
// sentry_options_set_debug(options, 1);
if (sentry_init(options) != 0) {
std::cerr << "Failed to initialize sentry" << std::endl;
}
reportSentryException(SENTRY_LEVEL_ERROR, "Exception occurred during main", "Exception-Type", "mac os message");
auto sentryClose = qScopeGuard([]{sentry_close();});
// The application instance is needed to display system message boxes. As we may have to do it in the exception handler,
// application instance is create outside the try/catch clause.
if (QSysInfo::productType() != "windows")
@ -403,6 +427,7 @@ int main(int argc, char *argv[])
}
catch (Exception const &e)
{
reportSentryException(SENTRY_LEVEL_ERROR, "Exception occurred during main", "Exception", e.what());
QMessageBox::critical(nullptr, "Error", e.qwhat());
QTextStream(stderr) << e.qwhat() << "\n";
return EXIT_FAILURE;

View File

@ -167,6 +167,16 @@ QString userLogsDir()
return path;
}
//****************************************************************************************************************************************************
/// \return sentry cache directory used by bridge.
//****************************************************************************************************************************************************
QString sentryCacheDir()
{
QString const path = QDir(userDataDir()).absoluteFilePath("sentry_cache");
QDir().mkpath(path);
return path;
}
//****************************************************************************************************************************************************
/// \return The value GOOS would return for the current platform.

View File

@ -40,6 +40,7 @@ enum class OS {
QString userConfigDir(); ///< Get the path of the user configuration folder.
QString userCacheDir(); ///< Get the path of the user cache folder.
QString userLogsDir(); ///< Get the path of the user logs folder.
QString sentryCacheDir(); ///< Get the path of the sentry cache folder.
QString goos(); ///< return the value of Go's GOOS for the current platform ("darwin", "linux" and "windows" are supported).
qint64 randN(qint64 n); ///< return a random integer in the half open range [0,n)
QString randomFirstName(); ///< Get a random first name from a pre-determined list.