feat(GODT-2278): improve sentry logs.

This commit is contained in:
Romain Le Jeune
2023-02-02 15:36:37 +00:00
parent 219400de8d
commit 5ec1da34b4
7 changed files with 56 additions and 20 deletions

View File

@ -76,10 +76,10 @@ ProcessMonitor *AppController::bridgeMonitor() const {
//**************************************************************************************************************************************************** //****************************************************************************************************************************************************
void AppController::onFatalError(QString const &function, QString const &message) { void AppController::onFatalError(QString const &function, QString const &message) {
QString const fullMessage = QString("%1(): %2").arg(function, 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); QMessageBox::critical(nullptr, tr("Error"), message);
restart(true); 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); qApp->exit(EXIT_FAILURE);
} }

View File

@ -16,19 +16,38 @@
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
#include "SentryUtils.h" #include "SentryUtils.h"
#include "Version.h"
#include <bridgepp/BridgeUtils.h>
#include <QByteArray>
#include <QCryptographicHash>
#include <QString>
#include <QSysInfo>
static constexpr const char *LoggerName = "bridge-gui"; 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); 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); auto event = sentry_value_new_message_event(level, LoggerName, message);
sentry_event_add_exception(event, sentry_value_new_exception(exceptionType, exception)); sentry_event_add_exception(event, sentry_value_new_exception(exceptionType, exception));
sentry_capture_event(event); return sentry_capture_event(event);
} }

View File

@ -21,8 +21,8 @@
#include <sentry.h> #include <sentry.h>
void setSentryReportScope();
void reportSentryEvent(sentry_level_t level, const char *message); sentry_uuid_t reportSentryEvent(sentry_level_t level, const char *message);
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);
#endif //BRIDGE_GUI_SENTRYUTILS_H #endif //BRIDGE_GUI_SENTRYUTILS_H

View File

@ -75,6 +75,7 @@ function check_exit() {
Write-host "Running build for version $bridgeVersion - $buildConfig in $buildDir" Write-host "Running build for version $bridgeVersion - $buildConfig in $buildDir"
$REVISION_HASH = git rev-parse --short=10 HEAD
git submodule update --init --recursive $vcpkgRoot git submodule update --init --recursive $vcpkgRoot
. $vcpkgBootstrap -disableMetrics . $vcpkgBootstrap -disableMetrics
. $vcpkgExe install sentry-native:x64-windows grpc:x64-windows --clean-after-build . $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" ` . $cmakeExe -G "Visual Studio 17 2022" -DCMAKE_BUILD_TYPE="$buildConfig" `
-DBRIDGE_APP_FULL_NAME="$bridgeFullName" ` -DBRIDGE_APP_FULL_NAME="$bridgeFullName" `
-DBRIDGE_VENDOR="$bridgeVendor" ` -DBRIDGE_VENDOR="$bridgeVendor" `
-DBRIDGE_REVISION=$REVISION_HASH `
-DBRIDGE_APP_VERSION="$bridgeVersion" ` -DBRIDGE_APP_VERSION="$bridgeVersion" `
-S . -B $buildDir -S . -B $buildDir

View File

@ -55,7 +55,7 @@ BRIDGE_VENDOR=${BRIDGE_VENDOR:-"Proton AG"}
BUILD_CONFIG=${BRIDGE_GUI_BUILD_CONFIG:-Debug} BUILD_CONFIG=${BRIDGE_GUI_BUILD_CONFIG:-Debug}
BUILD_DIR=$(echo "./cmake-build-${BUILD_CONFIG}" | tr '[:upper:]' '[:lower:]') BUILD_DIR=$(echo "./cmake-build-${BUILD_CONFIG}" | tr '[:upper:]' '[:lower:]')
VCPKG_ROOT="${BRIDGE_REPO_ROOT}/extern/vcpkg" VCPKG_ROOT="${BRIDGE_REPO_ROOT}/extern/vcpkg"
BRIDGE_REVISION=$(git rev-parse --short=10 HEAD)
git submodule update --init --recursive ${VCPKG_ROOT} git submodule update --init --recursive ${VCPKG_ROOT}
check_exit "Failed to initialize vcpkg as a submodule." check_exit "Failed to initialize vcpkg as a submodule."
@ -93,6 +93,7 @@ cmake \
-DCMAKE_BUILD_TYPE="${BUILD_CONFIG}" \ -DCMAKE_BUILD_TYPE="${BUILD_CONFIG}" \
-DBRIDGE_APP_FULL_NAME="${BRIDGE_APP_FULL_NAME}" \ -DBRIDGE_APP_FULL_NAME="${BRIDGE_APP_FULL_NAME}" \
-DBRIDGE_VENDOR="${BRIDGE_VENDOR}" \ -DBRIDGE_VENDOR="${BRIDGE_VENDOR}" \
-DBRIDGE_REVISION="${BRIDGE_REVISION}" \
-DBRIDGE_APP_VERSION="${BRIDGE_APP_VERSION}" "${BRIDGE_CMAKE_MACOS_OPTS}" \ -DBRIDGE_APP_VERSION="${BRIDGE_APP_VERSION}" "${BRIDGE_CMAKE_MACOS_OPTS}" \
-G Ninja \ -G Ninja \
-S . \ -S . \

View File

@ -28,6 +28,7 @@
#include <bridgepp/Log/Log.h> #include <bridgepp/Log/Log.h>
#include <bridgepp/ProcessMonitor.h> #include <bridgepp/ProcessMonitor.h>
#include <sentry.h> #include <sentry.h>
#include <SentryUtils.h>
#include <project_sentry_config.h> #include <project_sentry_config.h>
@ -238,7 +239,8 @@ void focusOtherInstance() {
} }
catch (Exception const &e) { catch (Exception const &e) {
app().log().error(e.qwhat()); 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(); const QString sentryCachePath = sentryCacheDir();
sentry_options_set_database_path(sentryOptions, sentryCachePath.toStdString().c_str()); 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. // Enable this for debugging sentry.
// sentry_options_set_debug(sentryOptions, 1); // sentry_options_set_debug(sentryOptions, 1);
if (sentry_init(sentryOptions) != 0) { if (sentry_init(sentryOptions) != 0) {
std::cerr << "Failed to initialize sentry" << std::endl; std::cerr << "Failed to initialize sentry" << std::endl;
} }
setSentryReportScope();
auto sentryClose = qScopeGuard([] { sentry_close(); }); 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, // 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; return result;
} }
catch (Exception const &e) { 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()); 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; return EXIT_FAILURE;
} }
} }

View File

@ -18,6 +18,7 @@
package sentry package sentry
import ( import (
"crypto/sha256"
"errors" "errors"
"fmt" "fmt"
"log" "log"
@ -62,12 +63,21 @@ type Reporter struct {
appVersion string appVersion string
identifier Identifier identifier Identifier
hostArch string hostArch string
serverName string
} }
type Identifier interface { type Identifier interface {
GetUserAgent() string 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. // NewReporter creates new sentry reporter with appName and appVersion to report.
func NewReporter(appName, appVersion string, identifier Identifier) *Reporter { func NewReporter(appName, appVersion string, identifier Identifier) *Reporter {
return &Reporter{ return &Reporter{
@ -75,6 +85,7 @@ func NewReporter(appName, appVersion string, identifier Identifier) *Reporter {
appVersion: appVersion, appVersion: appVersion,
identifier: identifier, identifier: identifier,
hostArch: getHostArch(), hostArch: getHostArch(),
serverName: getProtectedHostname(),
} }
} }
@ -131,6 +142,7 @@ func (r *Reporter) scopedReport(context map[string]interface{}, doReport func())
"Version": r.appVersion, "Version": r.appVersion,
"UserAgent": r.identifier.GetUserAgent(), "UserAgent": r.identifier.GetUserAgent(),
"HostArch": r.hostArch, "HostArch": r.hostArch,
"server_name": r.serverName,
} }
sentry.WithScope(func(scope *sentry.Scope) { sentry.WithScope(func(scope *sentry.Scope) {