diff --git a/CHANGELOG.md b/CHANGELOG.md index 8430908d..a117ea24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ - Add functionality to give/revoke user consent for crash uploads ([#1053](https://github.com/getsentry/sentry-unreal/pull/1053)) - Add new API for capturing user feedback ([#1051](https://github.com/getsentry/sentry-unreal/pull/1051)) +- Read `DSN`, `Environment` and `Release` options from environment variables ([#1054](https://github.com/getsentry/sentry-unreal/pull/1054)) ### Dependencies diff --git a/plugin-dev/Source/Sentry/Private/Android/AndroidSentrySubsystem.cpp b/plugin-dev/Source/Sentry/Private/Android/AndroidSentrySubsystem.cpp index 512fcd70..24c75818 100644 --- a/plugin-dev/Source/Sentry/Private/Android/AndroidSentrySubsystem.cpp +++ b/plugin-dev/Source/Sentry/Private/Android/AndroidSentrySubsystem.cpp @@ -33,8 +33,8 @@ void FAndroidSentrySubsystem::InitWithSettings(const USentrySettings* settings, { TSharedPtr SettingsJson = MakeShareable(new FJsonObject); SettingsJson->SetStringField(TEXT("dsn"), settings->Dsn); - SettingsJson->SetStringField(TEXT("release"), settings->OverrideReleaseName ? settings->Release : settings->GetFormattedReleaseName()); - SettingsJson->SetStringField(TEXT("environment"), settings->Environment); + SettingsJson->SetStringField(TEXT("release"), settings->GetEffectiveRelease()); + SettingsJson->SetStringField(TEXT("environment"), settings->GetEffectiveEnvironment()); SettingsJson->SetStringField(TEXT("dist"), settings->Dist); SettingsJson->SetBoolField(TEXT("autoSessionTracking"), settings->EnableAutoSessionTracking); SettingsJson->SetNumberField(TEXT("sessionTimeout"), settings->SessionTimeout); diff --git a/plugin-dev/Source/Sentry/Private/Apple/AppleSentrySubsystem.cpp b/plugin-dev/Source/Sentry/Private/Apple/AppleSentrySubsystem.cpp index 637f5596..6ea15a65 100644 --- a/plugin-dev/Source/Sentry/Private/Apple/AppleSentrySubsystem.cpp +++ b/plugin-dev/Source/Sentry/Private/Apple/AppleSentrySubsystem.cpp @@ -51,11 +51,11 @@ void FAppleSentrySubsystem::InitWithSettings(const USentrySettings* settings, US dispatch_async(dispatch_get_main_queue(), ^{ [SENTRY_APPLE_CLASS(SentrySDK) startWithConfigureOptions:^(SentryOptions* options) { options.dsn = settings->GetEffectiveDsn().GetNSString(); - options.environment = settings->Environment.GetNSString(); + options.releaseName = settings->GetEffectiveRelease().GetNSString(); + options.environment = settings->GetEffectiveEnvironment().GetNSString(); options.dist = settings->Dist.GetNSString(); options.enableAutoSessionTracking = settings->EnableAutoSessionTracking; options.sessionTrackingIntervalMillis = settings->SessionTimeout; - options.releaseName = settings->OverrideReleaseName ? settings->Release.GetNSString() : settings->GetFormattedReleaseName().GetNSString(); options.attachStacktrace = settings->AttachStacktrace; options.debug = settings->Debug; options.sampleRate = [NSNumber numberWithFloat:settings->SampleRate]; diff --git a/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentrySubsystem.cpp b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentrySubsystem.cpp index f2fb3c3d..3821b723 100644 --- a/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentrySubsystem.cpp +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentrySubsystem.cpp @@ -298,10 +298,9 @@ void FGenericPlatformSentrySubsystem::InitWithSettings(const USentrySettings* se ConfigureCertsPath(options); ConfigureNetworkConnectFunc(options); - sentry_options_set_release(options, TCHAR_TO_ANSI(settings->OverrideReleaseName ? *settings->Release : *settings->GetFormattedReleaseName())); - sentry_options_set_dsn(options, TCHAR_TO_ANSI(*settings->GetEffectiveDsn())); - sentry_options_set_environment(options, TCHAR_TO_ANSI(*settings->Environment)); + sentry_options_set_release(options, TCHAR_TO_ANSI(*settings->GetEffectiveRelease())); + sentry_options_set_environment(options, TCHAR_TO_ANSI(*settings->GetEffectiveEnvironment())); sentry_options_set_dist(options, TCHAR_TO_ANSI(*settings->Dist)); sentry_options_set_logger(options, PrintVerboseLog, nullptr); sentry_options_set_debug(options, settings->Debug); diff --git a/plugin-dev/Source/Sentry/Private/Linux/LinuxSentrySubsystem.cpp b/plugin-dev/Source/Sentry/Private/Linux/LinuxSentrySubsystem.cpp index 393f943d..791f9b6c 100644 --- a/plugin-dev/Source/Sentry/Private/Linux/LinuxSentrySubsystem.cpp +++ b/plugin-dev/Source/Sentry/Private/Linux/LinuxSentrySubsystem.cpp @@ -16,7 +16,7 @@ void FLinuxSentrySubsystem::InitWithSettings(const USentrySettings* Settings, US { FGenericPlatformSentrySubsystem::InitWithSettings(Settings, BeforeSendHandler, BeforeBreadcrumbHandler, TraceSampler); - InitCrashReporter(Settings->Release, Settings->Environment); + InitCrashReporter(Settings->GetEffectiveRelease(), Settings->GetEffectiveEnvironment()); } void FLinuxSentrySubsystem::ConfigureHandlerPath(sentry_options_t* Options) diff --git a/plugin-dev/Source/Sentry/Private/Microsoft/MicrosoftSentrySubsystem.cpp b/plugin-dev/Source/Sentry/Private/Microsoft/MicrosoftSentrySubsystem.cpp index 451f79c5..92f74c4e 100644 --- a/plugin-dev/Source/Sentry/Private/Microsoft/MicrosoftSentrySubsystem.cpp +++ b/plugin-dev/Source/Sentry/Private/Microsoft/MicrosoftSentrySubsystem.cpp @@ -31,10 +31,10 @@ void FMicrosoftSentrySubsystem::InitWithSettings(const USentrySettings* Settings if (FPlatformMisc::GetCrashHandlingType() == ECrashHandlingType::Default) { - InitCrashReporter(Settings->Release, Settings->Environment); + InitCrashReporter(Settings->GetEffectiveRelease(), Settings->GetEffectiveEnvironment()); } #else - InitCrashReporter(Settings->Release, Settings->Environment); + InitCrashReporter(Settings->GetEffectiveRelease(), Settings->GetEffectiveEnvironment()); #endif } diff --git a/plugin-dev/Source/Sentry/Private/SentrySettings.cpp b/plugin-dev/Source/Sentry/Private/SentrySettings.cpp index 5177c004..3ca138d8 100644 --- a/plugin-dev/Source/Sentry/Private/SentrySettings.cpp +++ b/plugin-dev/Source/Sentry/Private/SentrySettings.cpp @@ -14,7 +14,6 @@ USentrySettings::USentrySettings(const FObjectInitializer& ObjectInitializer) , InitAutomatically(true) , Dsn() , Debug(true) - , Environment(GetDefaultEnvironmentName()) , SampleRate(1.0f) , EnableAutoLogAttachment(false) , AttachStacktrace(true) @@ -86,34 +85,47 @@ void USentrySettings::PostEditChangeProperty(FPropertyChangedEvent& PropertyChan FString USentrySettings::GetEffectiveDsn() const { - return GIsEditor && !EditorDsn.IsEmpty() ? EditorDsn : Dsn; -} + if (GIsEditor && !EditorDsn.IsEmpty()) + { + return EditorDsn; + } -FString USentrySettings::GetFormattedReleaseName() -{ - FString FormattedReleaseName = FApp::GetProjectName(); + if (!Dsn.IsEmpty()) + { + return Dsn; + } - FString Version = TEXT(""); - GConfig->GetString(TEXT("/Script/EngineSettings.GeneralProjectSettings"), TEXT("ProjectVersion"), Version, GGameIni); - if (!Version.IsEmpty()) + const FString& EnvVarDsn = FPlatformMisc::GetEnvironmentVariable(TEXT("SENTRY_DSN")); + if (!EnvVarDsn.IsEmpty()) { - FormattedReleaseName = FString::Printf(TEXT("%s@%s"), *FormattedReleaseName, *Version); + UE_LOG(LogSentrySdk, Log, TEXT("DSN is not set in plugin settings - using SENTRY_DSN environment variable instead.")); + return EnvVarDsn; } - return FormattedReleaseName; + UE_LOG(LogSentrySdk, Log, TEXT("DSN is not configured.")); + return FString(); } -bool USentrySettings::IsDirty() const +FString USentrySettings::GetEffectiveEnvironment() const { - return bIsDirty; -} + if (!Environment.IsEmpty()) + { + UE_LOG(LogSentrySdk, Verbose, TEXT("Using the value from plugin settings as Sentry environment.")); + return Environment; + } -void USentrySettings::ClearDirtyFlag() -{ - bIsDirty = false; + const FString& EnvVarEnvironment = FPlatformMisc::GetEnvironmentVariable(TEXT("SENTRY_ENVIRONMENT")); + if (!EnvVarEnvironment.IsEmpty()) + { + UE_LOG(LogSentrySdk, Log, TEXT("Using SENTRY_ENVIRONMENT variable as Sentry environment.")); + return EnvVarEnvironment; + } + + UE_LOG(LogSentrySdk, Log, TEXT("Using current build configuration as Sentry environment.")); + return GetEnvironmentFromBuildConfig(); } -FString USentrySettings::GetDefaultEnvironmentName() +FString USentrySettings::GetEnvironmentFromBuildConfig() const { if (GIsEditor) { @@ -129,6 +141,49 @@ FString USentrySettings::GetDefaultEnvironmentName() return LexToString(FApp::GetBuildConfiguration()); } +FString USentrySettings::GetEffectiveRelease() const +{ + if (OverrideReleaseName) + { + UE_LOG(LogSentrySdk, Verbose, TEXT("Using the value from plugin settings as Sentry release.")); + return Release; + } + + const FString& EnvVarRelease = FPlatformMisc::GetEnvironmentVariable(TEXT("SENTRY_RELEASE")); + if (!EnvVarRelease.IsEmpty()) + { + UE_LOG(LogSentrySdk, Log, TEXT("Using SENTRY_RELEASE variable as Sentry release.")); + return EnvVarRelease; + } + + UE_LOG(LogSentrySdk, Log, TEXT("Using current project name and version as Sentry release.")); + return GetReleaseFromProjectSettings(); +} + +FString USentrySettings::GetReleaseFromProjectSettings() const +{ + FString FormattedReleaseName = FApp::GetProjectName(); + + FString Version = TEXT(""); + GConfig->GetString(TEXT("/Script/EngineSettings.GeneralProjectSettings"), TEXT("ProjectVersion"), Version, GGameIni); + if (!Version.IsEmpty()) + { + FormattedReleaseName = FString::Printf(TEXT("%s@%s"), *FormattedReleaseName, *Version); + } + + return FormattedReleaseName; +} + +bool USentrySettings::IsDirty() const +{ + return bIsDirty; +} + +void USentrySettings::ClearDirtyFlag() +{ + bIsDirty = false; +} + void USentrySettings::LoadDebugSymbolsProperties() { const FString PropertiesFilePath = FPaths::Combine(FPaths::ProjectDir(), TEXT("sentry.properties")); diff --git a/plugin-dev/Source/Sentry/Private/SentrySubsystem.cpp b/plugin-dev/Source/Sentry/Private/SentrySubsystem.cpp index b7fa7b36..582988db 100644 --- a/plugin-dev/Source/Sentry/Private/SentrySubsystem.cpp +++ b/plugin-dev/Source/Sentry/Private/SentrySubsystem.cpp @@ -78,7 +78,7 @@ void USentrySubsystem::Initialize() const USentrySettings* Settings = FSentryModule::Get().GetSettings(); check(Settings); - if (Settings->Dsn.IsEmpty()) + if (Settings->GetEffectiveDsn().IsEmpty()) { UE_LOG(LogSentrySdk, Warning, TEXT("Sentry requires minimal configuration for its initialization - please provide the DSN in plugin settings.")); return; diff --git a/plugin-dev/Source/Sentry/Public/SentrySettings.h b/plugin-dev/Source/Sentry/Public/SentrySettings.h index 7bc11377..cbb98e83 100644 --- a/plugin-dev/Source/Sentry/Public/SentrySettings.h +++ b/plugin-dev/Source/Sentry/Public/SentrySettings.h @@ -384,17 +384,46 @@ class SENTRY_API USentrySettings : public UObject * Gets the effective DSN based on current execution context. * * @return Editor DSN when running in the editor and one is set; otherwise, falls back to the default DSN. + * If neither is provided, the SDK will attempt to read it from the SENTRY_DSN environment variable. */ FString GetEffectiveDsn() const; - static FString GetFormattedReleaseName(); + /** + * Gets the effective environment based on current execution context. + * + * @return By default, the SDK uses the `Environment` value from the plugin settings if set. + * If not, the SDK will attempt to read it from SENTRY_ENVIRONMENT environment variable. + * If that is also not set, the environment is automatically derived from the current build configuration. + */ + FString GetEffectiveEnvironment() const; + + /** + * Gets the environment from the application's build configuration. + * + * @return Environment string based on build configuration (`Shipping` maps to `Release`, others map directly). + */ + FString GetEnvironmentFromBuildConfig() const; + + /** + * Gets the effective release name based on current execution context. + * + * @return By default, the SDK uses the `Release` value from the plugin settings if `OverrideReleaseName` flag is set. + * If not, the SDK will attempt to read it from SENTRY_RELEASE environment variable. + * If that is also not set, the release name is automatically derived from the current project name and version. + */ + FString GetEffectiveRelease() const; + + /** + * Gets the release name from the project settings. + * + * @return Release name derived from the current project name and version to match the format `@`. + */ + FString GetReleaseFromProjectSettings() const; bool IsDirty() const; void ClearDirtyFlag(); private: - FString GetDefaultEnvironmentName(); - void LoadDebugSymbolsProperties(); bool bIsDirty;