diff --git a/Makefile b/Makefile index 54f9281e..0802ca10 100644 --- a/Makefile +++ b/Makefile @@ -23,10 +23,10 @@ REVISION:=$(shell git rev-parse --short=10 HEAD) BUILD_TIME:=$(shell date +%FT%T%z) MACOS_MIN_VERSION_ARM64=11.0 MACOS_MIN_VERSION_AMD64=10.15 +BUILD_ENV?=dev BUILD_FLAGS:=-tags='${BUILD_TAGS}' BUILD_FLAGS_LAUNCHER:=${BUILD_FLAGS} -BUILD_FLAGS_GUI:=-tags='${BUILD_TAGS} build_qt' GO_LDFLAGS:=$(addprefix -X github.com/ProtonMail/proton-bridge/v3/internal/constants., Version=${APP_VERSION} Revision=${REVISION} BuildTime=${BUILD_TIME}) GO_LDFLAGS+=-X "github.com/ProtonMail/proton-bridge/v3/internal/constants.FullAppName=${APP_FULL_NAME}" @@ -34,6 +34,10 @@ ifneq "${DSN_SENTRY}" "" GO_LDFLAGS+=-X github.com/ProtonMail/proton-bridge/v3/internal/constants.DSNSentry=${DSN_SENTRY} endif +ifneq "${BUILD_ENV}" "" + GO_LDFLAGS+=-X github.com/ProtonMail/proton-bridge/v3/internal/constants.BuildEnv=${BUILD_ENV} +endif + GO_LDFLAGS_LAUNCHER:=${GO_LDFLAGS} ifeq "${TARGET_OS}" "windows" #GO_LDFLAGS+=-H=windowsgui # Disabled so we can inspect trace logs from the bridge for debugging. @@ -41,7 +45,6 @@ ifeq "${TARGET_OS}" "windows" endif BUILD_FLAGS+=-ldflags '${GO_LDFLAGS}' -BUILD_FLAGS_GUI+=-ldflags "${GO_LDFLAGS}" BUILD_FLAGS_LAUNCHER+=-ldflags '${GO_LDFLAGS_LAUNCHER}' DEPLOY_DIR:=cmd/${TARGET_CMD}/deploy DIRNAME:=$(shell basename ${CURDIR}) @@ -158,6 +161,7 @@ ${EXE_TARGET}: check-build-essentials ${EXE_NAME} BRIDGE_DSN_SENTRY=${DSN_SENTRY} \ BRIDGE_BUILD_TIME=${BUILD_TIME} \ BRIDGE_GUI_BUILD_CONFIG=Release \ + BRIDGE_BUILD_ENV=BUILD_ENV \ BRIDGE_INSTALL_PATH=${ROOT_DIR}/${DEPLOY_DIR}/${GOOS} \ ./build.sh install mv "${ROOT_DIR}/${BRIDGE_EXE}" "$(ROOT_DIR)/${EXE_TARGET}" diff --git a/cmd/launcher/main.go b/cmd/launcher/main.go index f8b1ec98..32acdf6d 100644 --- a/cmd/launcher/main.go +++ b/cmd/launcher/main.go @@ -59,7 +59,7 @@ func main() { //nolint:funlen logrus.SetLevel(logrus.DebugLevel) l := logrus.WithField("launcher_version", constants.Version) - reporter := sentry.NewReporter(appName, constants.Version, useragent.New()) + reporter := sentry.NewReporter(appName, useragent.New()) crashHandler := crash.NewHandler(reporter.ReportException) defer crashHandler.HandlePanic() diff --git a/internal/app/app.go b/internal/app/app.go index 76a0c4cf..6e5c6a62 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -170,7 +170,7 @@ func run(c *cli.Context) error { //nolint:funlen identifier := useragent.New() // Create a new Sentry client that will be used to report crashes etc. - reporter := sentry.NewReporter(constants.FullAppName, constants.Version, identifier) + reporter := sentry.NewReporter(constants.FullAppName, identifier) // Determine the exe that should be used to restart/autostart the app. // By default, this is the launcher, if used. Otherwise, we try to get diff --git a/internal/constants/constants.go b/internal/constants/constants.go index 46df9e78..ac2942df 100644 --- a/internal/constants/constants.go +++ b/internal/constants/constants.go @@ -44,6 +44,9 @@ var ( // DSNSentry client keys to be able to report crashes to Sentry. DSNSentry = "" + + // BuildEnv tags used at build time. + BuildEnv = "" ) const ( diff --git a/internal/frontend/bridge-gui/bridge-gui/BuildConfig.h.in b/internal/frontend/bridge-gui/bridge-gui/BuildConfig.h.in index afcc58a5..2ebdf00d 100644 --- a/internal/frontend/bridge-gui/bridge-gui/BuildConfig.h.in +++ b/internal/frontend/bridge-gui/bridge-gui/BuildConfig.h.in @@ -25,5 +25,6 @@ #define PROJECT_REVISION "@BRIDGE_REVISION@" #define PROJECT_BUILD_TIME "@BRIDGE_BUILD_TIME@" #define PROJECT_DSN_SENTRY "@BRIDGE_DSN_SENTRY@" +#define PROJECT_BUILD_ENV "@BRIDGE_BUILD_ENV@" #endif // BRIDGE_GUI_VERSION_H diff --git a/internal/frontend/bridge-gui/bridge-gui/SentryUtils.cpp b/internal/frontend/bridge-gui/bridge-gui/SentryUtils.cpp index e2470412..0a22ad3d 100644 --- a/internal/frontend/bridge-gui/bridge-gui/SentryUtils.cpp +++ b/internal/frontend/bridge-gui/bridge-gui/SentryUtils.cpp @@ -31,13 +31,39 @@ QByteArray getProtectedHostname() { return hostname.toHex(); } +QString getApiOS() { +#if defined(Q_OS_DARWIN) + return "macos"; +#elif defined(Q_OS_WINDOWS) + return "windows"; +#else + return "linux"; +#endif +} + +QString appVersion(const QString& version) { + return QString("%1-bridge@%2").arg(getApiOS()).arg(version); +} + 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_set_tag("Version", QByteArray(PROJECT_REVISION).toHex()); + sentry_set_tag("HostArch", QSysInfo::currentCpuArchitecture().toUtf8()); + sentry_set_tag("server_name", getProtectedHostname()); +} + +sentry_options_t* newSentryOptions(const char *sentryDNS, const char *cacheDir) { + sentry_options_t *sentryOptions = sentry_options_new(); + sentry_options_set_dsn(sentryOptions, sentryDNS); + sentry_options_set_database_path(sentryOptions, cacheDir); + sentry_options_set_release(sentryOptions, appVersion(PROJECT_VER).toUtf8()); + sentry_options_set_max_breadcrumbs(sentryOptions, 50); + sentry_options_set_environment(sentryOptions, PROJECT_BUILD_ENV); + // Enable this for debugging sentry. + // sentry_options_set_debug(sentryOptions, 1); + + return sentryOptions; } sentry_uuid_t reportSentryEvent(sentry_level_t level, const char *message) { @@ -51,3 +77,5 @@ sentry_uuid_t reportSentryException(sentry_level_t level, const char *message, c sentry_event_add_exception(event, sentry_value_new_exception(exceptionType, exception)); 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 14ed3824..7b721066 100644 --- a/internal/frontend/bridge-gui/bridge-gui/SentryUtils.h +++ b/internal/frontend/bridge-gui/bridge-gui/SentryUtils.h @@ -22,6 +22,7 @@ #include void setSentryReportScope(); +sentry_options_t* newSentryOptions(const char * sentryDNS, const char * cacheDir); 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); diff --git a/internal/frontend/bridge-gui/bridge-gui/build.ps1 b/internal/frontend/bridge-gui/bridge-gui/build.ps1 index b11821c3..004b1a54 100644 --- a/internal/frontend/bridge-gui/bridge-gui/build.ps1 +++ b/internal/frontend/bridge-gui/bridge-gui/build.ps1 @@ -79,6 +79,12 @@ $REVISION_HASH = git rev-parse --short=10 HEAD $bridgeDsnSentry = ($env:BRIDGE_DSN_SENTRY) $bridgeBuidTime = ($env:BRIDGE_BUILD_TIME) +$bridgeBuildEnv = ($env:BRIDGE_BUILD_ENV) +if ($null -eq $bridgeBuildEnv) +{ + $bridgeBuildEnv = "dev" +} + git submodule update --init --recursive $vcpkgRoot . $vcpkgBootstrap -disableMetrics . $vcpkgExe install sentry-native:x64-windows grpc:x64-windows --clean-after-build @@ -90,6 +96,7 @@ git submodule update --init --recursive $vcpkgRoot -DBRIDGE_APP_VERSION="$bridgeVersion" ` -DBRIDGE_BUILD_TIME="$bridgeBuidTime" ` -DBRIDGE_DSN_SENTRY="$bridgeDsnSentry" ` + -DBRIDGE_BUILD_ENV="$bridgeBuildEnv" ` -S . -B $buildDir check_exit "CMake failed" diff --git a/internal/frontend/bridge-gui/bridge-gui/build.sh b/internal/frontend/bridge-gui/bridge-gui/build.sh index 832749e2..ed970d37 100755 --- a/internal/frontend/bridge-gui/bridge-gui/build.sh +++ b/internal/frontend/bridge-gui/bridge-gui/build.sh @@ -58,6 +58,7 @@ VCPKG_ROOT="${BRIDGE_REPO_ROOT}/extern/vcpkg" BRIDGE_REVISION=$(git rev-parse --short=10 HEAD) BRIDGE_DSN_SENTRY=${BRIDGE_DSN_SENTRY} BRIDGE_BUILD_TIME=${BRIDGE_BUILD_TIME} +BRIDGE_BUILD_ENV= ${BRIDGE_BUILD_ENV:-"dev"} git submodule update --init --recursive ${VCPKG_ROOT} check_exit "Failed to initialize vcpkg as a submodule." @@ -98,6 +99,7 @@ cmake \ -DBRIDGE_REVISION="${BRIDGE_REVISION}" \ -DBRIDGE_DSN_SENTRY="${BRIDGE_DSN_SENTRY}" \ -DBRIDGE_BRIDGE_TIME="${BRIDGE_BRIDGE_TIME}" \ + -DBRIDGE_BUILD_ENV="${BRIDGE_BUILD_ENV}" \ -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 513d91b6..0064bde5 100644 --- a/internal/frontend/bridge-gui/bridge-gui/main.cpp +++ b/internal/frontend/bridge-gui/bridge-gui/main.cpp @@ -291,15 +291,8 @@ void closeBridgeApp() { //**************************************************************************************************************************************************** int main(int argc, char *argv[]) { // Init sentry. - sentry_options_t *sentryOptions = sentry_options_new(); - sentry_options_set_dsn(sentryOptions, PROJECT_DSN_SENTRY); - { - const QString sentryCachePath = sentryCacheDir(); - sentry_options_set_database_path(sentryOptions, sentryCachePath.toStdString().c_str()); - } - sentry_options_set_release(sentryOptions, QByteArray(PROJECT_REVISION).toHex()); - // Enable this for debugging sentry. - // sentry_options_set_debug(sentryOptions, 1); + sentry_options_t *sentryOptions = newSentryOptions(PROJECT_DSN_SENTRY, sentryCacheDir().toStdString().c_str()); + if (sentry_init(sentryOptions) != 0) { std::cerr << "Failed to initialize sentry" << std::endl; } diff --git a/internal/sentry/reporter.go b/internal/sentry/reporter.go index 4f6ae466..6c416528 100644 --- a/internal/sentry/reporter.go +++ b/internal/sentry/reporter.go @@ -26,7 +26,7 @@ import ( "runtime" "time" - "github.com/ProtonMail/gluon/reporter" + "github.com/Masterminds/semver/v3" "github.com/ProtonMail/proton-bridge/v3/internal/constants" "github.com/ProtonMail/proton-bridge/v3/pkg/restarter" "github.com/getsentry/sentry-go" @@ -38,13 +38,23 @@ var skippedFunctions = []string{} //nolint:gochecknoglobals func init() { //nolint:gochecknoinits sentrySyncTransport := sentry.NewHTTPSyncTransport() sentrySyncTransport.Timeout = time.Second * 3 + appVersion := constants.Version + version, _ := semver.NewVersion(appVersion) + if version != nil { + appVersion = version.Original() + } - if err := sentry.Init(sentry.ClientOptions{ - Dsn: constants.DSNSentry, - Release: constants.Revision, - BeforeSend: EnhanceSentryEvent, - Transport: sentrySyncTransport, - }); err != nil { + options := sentry.ClientOptions{ + Dsn: constants.DSNSentry, + Release: constants.AppVersion(appVersion), + BeforeSend: EnhanceSentryEvent, + Transport: sentrySyncTransport, + ServerName: getProtectedHostname(), + Environment: constants.BuildEnv, + MaxBreadcrumbs: 50, + } + + if err := sentry.Init(options); err != nil { logrus.WithError(err).Error("Failed to initialize sentry options") } @@ -64,7 +74,6 @@ type Reporter struct { appVersion string identifier Identifier hostArch string - serverName string } type Identifier interface { @@ -80,13 +89,12 @@ func getProtectedHostname() string { } // NewReporter creates new sentry reporter with appName and appVersion to report. -func NewReporter(appName, appVersion string, identifier Identifier) *Reporter { +func NewReporter(appName string, identifier Identifier) *Reporter { return &Reporter{ appName: appName, - appVersion: appVersion, + appVersion: constants.Revision, identifier: identifier, hostArch: getHostArch(), - serverName: getProtectedHostname(), } } @@ -138,12 +146,11 @@ 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, - "server_name": r.serverName, + "OS": runtime.GOOS, + "Client": r.appName, + "Version": r.appVersion, + "UserAgent": r.identifier.GetUserAgent(), + "HostArch": r.hostArch, } sentry.WithScope(func(scope *sentry.Scope) {