diff --git a/internal/frontend/bridge-gui/bridge-gui/AppController.cpp b/internal/frontend/bridge-gui/bridge-gui/AppController.cpp
index 6b69b4d1..c745b784 100644
--- a/internal/frontend/bridge-gui/bridge-gui/AppController.cpp
+++ b/internal/frontend/bridge-gui/bridge-gui/AppController.cpp
@@ -76,10 +76,10 @@ ProcessMonitor *AppController::bridgeMonitor() const {
//****************************************************************************************************************************************************
void AppController::onFatalError(QString const &function, QString const &message) {
QString const fullMessage = QString("%1(): %2").arg(function, message);
- reportSentryException(SENTRY_LEVEL_ERROR, "AppController got notified of a fatal error", "Exception", fullMessage.toLocal8Bit());
+ auto uuid = reportSentryException(SENTRY_LEVEL_ERROR, "AppController got notified of a fatal error", "Exception", fullMessage.toLocal8Bit());
QMessageBox::critical(nullptr, tr("Error"), message);
restart(true);
- log().fatal(fullMessage);
+ log().fatal(QString("reportID: %1 Captured exception: %2").arg(QByteArray(uuid.bytes, 16).toHex()).arg(fullMessage));
qApp->exit(EXIT_FAILURE);
}
diff --git a/internal/frontend/bridge-gui/bridge-gui/SentryUtils.cpp b/internal/frontend/bridge-gui/bridge-gui/SentryUtils.cpp
index 7c26a756..6dafef9f 100644
--- a/internal/frontend/bridge-gui/bridge-gui/SentryUtils.cpp
+++ b/internal/frontend/bridge-gui/bridge-gui/SentryUtils.cpp
@@ -16,19 +16,38 @@
// along with Proton Mail Bridge. If not, see .
#include "SentryUtils.h"
+#include "Version.h"
+#include
+#include
+#include
+#include
+#include
static constexpr const char *LoggerName = "bridge-gui";
+QByteArray getProtectedHostname() {
+ QByteArray hostname = QCryptographicHash::hash(QSysInfo::machineHostName().toUtf8(), QCryptographicHash::Sha256);
+ return hostname.toHex();
+}
-void reportSentryEvent(sentry_level_t level, const char *message) {
+void setSentryReportScope() {
+ sentry_set_tag("OS", bridgepp::goos().toUtf8());
+ sentry_set_tag("Client", PROJECT_FULL_NAME);
+ sentry_set_tag("Version", PROJECT_VER);
+ sentry_set_tag("UserAgent", QString("/ (%1)").arg(bridgepp::goos()).toUtf8());
+ sentry_set_tag("HostArch", QSysInfo::currentCpuArchitecture().toUtf8());
+ sentry_set_tag("server_name", getProtectedHostname());
+}
+
+sentry_uuid_t reportSentryEvent(sentry_level_t level, const char *message) {
auto event = sentry_value_new_message_event(level, LoggerName, message);
- sentry_capture_event(event);
+ return sentry_capture_event(event);
}
-void reportSentryException(sentry_level_t level, const char *message, const char *exceptionType, const char *exception) {
+sentry_uuid_t 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);
+ return sentry_capture_event(event);
}
diff --git a/internal/frontend/bridge-gui/bridge-gui/SentryUtils.h b/internal/frontend/bridge-gui/bridge-gui/SentryUtils.h
index dfc0ffa9..14ed3824 100644
--- a/internal/frontend/bridge-gui/bridge-gui/SentryUtils.h
+++ b/internal/frontend/bridge-gui/bridge-gui/SentryUtils.h
@@ -21,8 +21,8 @@
#include
-
-void reportSentryEvent(sentry_level_t level, const char *message);
-void reportSentryException(sentry_level_t level, const char *message, const char *exceptionType, const char *exception);
+void setSentryReportScope();
+sentry_uuid_t reportSentryEvent(sentry_level_t level, const char *message);
+sentry_uuid_t reportSentryException(sentry_level_t level, const char *message, const char *exceptionType, const char *exception);
#endif //BRIDGE_GUI_SENTRYUTILS_H
diff --git a/internal/frontend/bridge-gui/bridge-gui/build.ps1 b/internal/frontend/bridge-gui/bridge-gui/build.ps1
index 16793360..20bd2f49 100644
--- a/internal/frontend/bridge-gui/bridge-gui/build.ps1
+++ b/internal/frontend/bridge-gui/bridge-gui/build.ps1
@@ -75,6 +75,7 @@ function check_exit() {
Write-host "Running build for version $bridgeVersion - $buildConfig in $buildDir"
+$REVISION_HASH = git rev-parse --short=10 HEAD
git submodule update --init --recursive $vcpkgRoot
. $vcpkgBootstrap -disableMetrics
. $vcpkgExe install sentry-native:x64-windows grpc:x64-windows --clean-after-build
@@ -82,6 +83,7 @@ git submodule update --init --recursive $vcpkgRoot
. $cmakeExe -G "Visual Studio 17 2022" -DCMAKE_BUILD_TYPE="$buildConfig" `
-DBRIDGE_APP_FULL_NAME="$bridgeFullName" `
-DBRIDGE_VENDOR="$bridgeVendor" `
+ -DBRIDGE_REVISION=$REVISION_HASH `
-DBRIDGE_APP_VERSION="$bridgeVersion" `
-S . -B $buildDir
diff --git a/internal/frontend/bridge-gui/bridge-gui/build.sh b/internal/frontend/bridge-gui/bridge-gui/build.sh
index bcd84158..c47663d5 100755
--- a/internal/frontend/bridge-gui/bridge-gui/build.sh
+++ b/internal/frontend/bridge-gui/bridge-gui/build.sh
@@ -55,7 +55,7 @@ BRIDGE_VENDOR=${BRIDGE_VENDOR:-"Proton AG"}
BUILD_CONFIG=${BRIDGE_GUI_BUILD_CONFIG:-Debug}
BUILD_DIR=$(echo "./cmake-build-${BUILD_CONFIG}" | tr '[:upper:]' '[:lower:]')
VCPKG_ROOT="${BRIDGE_REPO_ROOT}/extern/vcpkg"
-
+BRIDGE_REVISION=$(git rev-parse --short=10 HEAD)
git submodule update --init --recursive ${VCPKG_ROOT}
check_exit "Failed to initialize vcpkg as a submodule."
@@ -93,6 +93,7 @@ cmake \
-DCMAKE_BUILD_TYPE="${BUILD_CONFIG}" \
-DBRIDGE_APP_FULL_NAME="${BRIDGE_APP_FULL_NAME}" \
-DBRIDGE_VENDOR="${BRIDGE_VENDOR}" \
+ -DBRIDGE_REVISION="${BRIDGE_REVISION}" \
-DBRIDGE_APP_VERSION="${BRIDGE_APP_VERSION}" "${BRIDGE_CMAKE_MACOS_OPTS}" \
-G Ninja \
-S . \
diff --git a/internal/frontend/bridge-gui/bridge-gui/main.cpp b/internal/frontend/bridge-gui/bridge-gui/main.cpp
index 47a75a28..7e2f89c7 100644
--- a/internal/frontend/bridge-gui/bridge-gui/main.cpp
+++ b/internal/frontend/bridge-gui/bridge-gui/main.cpp
@@ -28,6 +28,7 @@
#include
#include
#include
+#include
#include
@@ -238,7 +239,8 @@ void focusOtherInstance() {
}
catch (Exception const &e) {
app().log().error(e.qwhat());
- reportSentryException(SENTRY_LEVEL_ERROR, "Exception occurred during focusOtherInstance()", "Exception", e.what());
+ auto uuid = reportSentryException(SENTRY_LEVEL_ERROR, "Exception occurred during focusOtherInstance()", "Exception", e.what());
+ app().log().fatal(QString("reportID: %1 Captured exception: %2").arg(QByteArray(uuid.bytes, 16).toHex()).arg(e.qwhat()));
}
}
@@ -296,13 +298,13 @@ int main(int argc, char *argv[]) {
const QString sentryCachePath = sentryCacheDir();
sentry_options_set_database_path(sentryOptions, sentryCachePath.toStdString().c_str());
}
- sentry_options_set_release(sentryOptions, SentryProductID);
+ sentry_options_set_release(sentryOptions, QByteArray(PROJECT_REVISION).toHex());
// Enable this for debugging sentry.
// sentry_options_set_debug(sentryOptions, 1);
if (sentry_init(sentryOptions) != 0) {
std::cerr << "Failed to initialize sentry" << std::endl;
}
-
+ setSentryReportScope();
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,
@@ -426,9 +428,9 @@ int main(int argc, char *argv[]) {
return result;
}
catch (Exception const &e) {
- reportSentryException(SENTRY_LEVEL_ERROR, "Exception occurred during main", "Exception", e.what());
+ auto uuid = reportSentryException(SENTRY_LEVEL_ERROR, "Exception occurred during main", "Exception", e.what());
QMessageBox::critical(nullptr, "Error", e.qwhat());
- QTextStream(stderr) << e.qwhat() << "\n";
+ QTextStream(stderr) << "reportID: " << QByteArray(uuid.bytes, 16).toHex() << "Captured exception :" << e.qwhat() << "\n";
return EXIT_FAILURE;
}
}
diff --git a/internal/sentry/reporter.go b/internal/sentry/reporter.go
index c8c54ef8..f9697f00 100644
--- a/internal/sentry/reporter.go
+++ b/internal/sentry/reporter.go
@@ -18,6 +18,7 @@
package sentry
import (
+ "crypto/sha256"
"errors"
"fmt"
"log"
@@ -62,12 +63,21 @@ type Reporter struct {
appVersion string
identifier Identifier
hostArch string
+ serverName string
}
type Identifier interface {
GetUserAgent() string
}
+func getProtectedHostname() string {
+ hostname, err := os.Hostname()
+ if err != nil {
+ return "Unknown"
+ }
+ return fmt.Sprintf("%x", sha256.Sum256([]byte(hostname)))
+}
+
// NewReporter creates new sentry reporter with appName and appVersion to report.
func NewReporter(appName, appVersion string, identifier Identifier) *Reporter {
return &Reporter{
@@ -75,6 +85,7 @@ func NewReporter(appName, appVersion string, identifier Identifier) *Reporter {
appVersion: appVersion,
identifier: identifier,
hostArch: getHostArch(),
+ serverName: getProtectedHostname(),
}
}
@@ -126,11 +137,12 @@ func (r *Reporter) scopedReport(context map[string]interface{}, doReport func())
}
tags := map[string]string{
- "OS": runtime.GOOS,
- "Client": r.appName,
- "Version": r.appVersion,
- "UserAgent": r.identifier.GetUserAgent(),
- "HostArch": r.hostArch,
+ "OS": runtime.GOOS,
+ "Client": r.appName,
+ "Version": r.appVersion,
+ "UserAgent": r.identifier.GetUserAgent(),
+ "HostArch": r.hostArch,
+ "server_name": r.serverName,
}
sentry.WithScope(func(scope *sentry.Scope) {