-
-
Notifications
You must be signed in to change notification settings - Fork 46
Fix invalid log file being attached to crash events on Mac/iOS #873
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
cb1209c
3040265
015b187
665e974
3e72b60
211e10d
28a8a93
5ace245
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,6 +26,9 @@ | |
#include "Convenience/SentryInclude.h" | ||
#include "Convenience/SentryMacro.h" | ||
|
||
#include "Utils/SentryFileUtils.h" | ||
#include "Utils/SentryLogUtils.h" | ||
|
||
#include "GenericPlatform/GenericPlatformOutputDevices.h" | ||
#include "HAL/FileManager.h" | ||
#include "HAL/PlatformSentryAttachment.h" | ||
|
@@ -34,10 +37,12 @@ | |
#include "Misc/Paths.h" | ||
#include "UObject/GarbageCollection.h" | ||
#include "UObject/UObjectThreadContext.h" | ||
#include "Utils/SentryLogUtils.h" | ||
|
||
void FAppleSentrySubsystem::InitWithSettings(const USentrySettings* settings, USentryBeforeSendHandler* beforeSendHandler, USentryBeforeBreadcrumbHandler* beforeBreadcrumbHandler, USentryTraceSampler* traceSampler) | ||
{ | ||
isScreenshotAttachmentEnabled = settings->AttachScreenshot; | ||
isGameLogAttachmentEnabled = settings->EnableAutoLogAttachment; | ||
Comment on lines
+43
to
+44
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should these go on the actual
This will also make it easier for users to browse and explore and for us to reason through the SDK's behaviour. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These two flags are cached separately here since they don't necessarily have a direct representation in Cocoa SDK options:
Accessing them using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This option (with this name) also exists on Android, .NET, Godot, Unity. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I might be missing the concern here. |
||
|
||
[SENTRY_APPLE_CLASS(PrivateSentrySDKOnly) setSdkName:@"sentry.cocoa.unreal"]; | ||
|
||
dispatch_group_t sentryDispatchGroup = dispatch_group_create(); | ||
|
@@ -65,14 +70,6 @@ void FAppleSentrySubsystem::InitWithSettings(const USentrySettings* settings, US | |
#if SENTRY_UIKIT_AVAILABLE | ||
options.attachScreenshot = settings->AttachScreenshot; | ||
#endif | ||
options.initialScope = ^(SentryScope* scope) { | ||
if(settings->EnableAutoLogAttachment) { | ||
const FString logFilePath = IFileManager::Get().ConvertToAbsolutePathForExternalAppForRead(*FGenericPlatformOutputDevices::GetAbsoluteLogFilename()); | ||
SentryAttachment* logAttachment = [[SENTRY_APPLE_CLASS(SentryAttachment) alloc] initWithPath:logFilePath.GetNSString()]; | ||
[scope addAttachment:logAttachment]; | ||
} | ||
return scope; | ||
}; | ||
options.onCrashedLastRun = ^(SentryEvent* event) { | ||
if (settings->AttachScreenshot) | ||
{ | ||
|
@@ -81,7 +78,16 @@ void FAppleSentrySubsystem::InitWithSettings(const USentrySettings* settings, US | |
const FString& screenshotPath = GetLatestScreenshot(); | ||
if (!screenshotPath.IsEmpty()) | ||
{ | ||
UploadScreenshotForEvent(MakeShareable(new SentryIdApple(event.eventId)), screenshotPath); | ||
UploadAttachmentForEvent(MakeShareable(new SentryIdApple(event.eventId)), screenshotPath, TEXT("screenshot.png"), true); | ||
} | ||
} | ||
if(settings->EnableAutoLogAttachment) { | ||
// Unreal creates game log backups automatically on every app run. If logging is enabled for current configuration SDK can | ||
// find the most recent one and upload it to Sentry. | ||
const FString logFilePath = GetLatestGameLog(); | ||
if (!logFilePath.IsEmpty()) | ||
{ | ||
UploadAttachmentForEvent(MakeShareable(new SentryIdApple(event.eventId)), logFilePath, SentryFileUtils::GetGameLogName()); | ||
} | ||
} | ||
}; | ||
|
@@ -206,17 +212,19 @@ void FAppleSentrySubsystem::ClearBreadcrumbs() | |
|
||
TSharedPtr<ISentryId> FAppleSentrySubsystem::CaptureMessage(const FString& message, ESentryLevel level) | ||
{ | ||
SentryId* id = [SENTRY_APPLE_CLASS(SentrySDK) captureMessage:message.GetNSString() withScopeBlock:^(SentryScope* scope){ | ||
[scope setLevel:SentryConvertersApple::SentryLevelToNative(level)]; | ||
}]; | ||
|
||
return MakeShareable(new SentryIdApple(id)); | ||
FSentryScopeDelegate onConfigureScope; | ||
return CaptureMessageWithScope(message, onConfigureScope, level); | ||
} | ||
|
||
TSharedPtr<ISentryId> FAppleSentrySubsystem::CaptureMessageWithScope(const FString& message, const FSentryScopeDelegate& onConfigureScope, ESentryLevel level) | ||
{ | ||
SentryId* id = [SENTRY_APPLE_CLASS(SentrySDK) captureMessage:message.GetNSString() withScopeBlock:^(SentryScope* scope){ | ||
[scope setLevel:SentryConvertersApple::SentryLevelToNative(level)]; | ||
if(isGameLogAttachmentEnabled) { | ||
const FString logFilePath = GetGameLogPath(); | ||
SentryAttachment* logAttachment = [[SENTRY_APPLE_CLASS(SentryAttachment) alloc] initWithPath:logFilePath.GetNSString()]; | ||
[scope addAttachment:logAttachment]; | ||
} | ||
onConfigureScope.ExecuteIfBound(MakeShareable(new SentryScopeApple(scope))); | ||
}]; | ||
|
||
|
@@ -225,17 +233,20 @@ TSharedPtr<ISentryId> FAppleSentrySubsystem::CaptureMessageWithScope(const FStri | |
|
||
TSharedPtr<ISentryId> FAppleSentrySubsystem::CaptureEvent(TSharedPtr<ISentryEvent> event) | ||
{ | ||
TSharedPtr<SentryEventApple> eventIOS = StaticCastSharedPtr<SentryEventApple>(event); | ||
|
||
SentryId* id = [SENTRY_APPLE_CLASS(SentrySDK) captureEvent:eventIOS->GetNativeObject()]; | ||
return MakeShareable(new SentryIdApple(id)); | ||
FSentryScopeDelegate onConfigureScope; | ||
return CaptureEventWithScope(event, onConfigureScope); | ||
} | ||
|
||
TSharedPtr<ISentryId> FAppleSentrySubsystem::CaptureEventWithScope(TSharedPtr<ISentryEvent> event, const FSentryScopeDelegate& onConfigureScope) | ||
{ | ||
TSharedPtr<SentryEventApple> eventIOS = StaticCastSharedPtr<SentryEventApple>(event); | ||
|
||
SentryId* id = [SENTRY_APPLE_CLASS(SentrySDK) captureEvent:eventIOS->GetNativeObject() withScopeBlock:^(SentryScope* scope) { | ||
if(isGameLogAttachmentEnabled) { | ||
const FString logFilePath = GetGameLogPath(); | ||
SentryAttachment* logAttachment = [[SENTRY_APPLE_CLASS(SentryAttachment) alloc] initWithPath:logFilePath.GetNSString()]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm trying to diff the 3 versions of this snippet in this PR but they all seem the same? If we're changing things would you want them all to be consistent? |
||
[scope addAttachment:logAttachment]; | ||
} | ||
onConfigureScope.ExecuteIfBound(MakeShareable(new SentryScopeApple(scope))); | ||
}]; | ||
|
||
|
@@ -251,7 +262,14 @@ TSharedPtr<ISentryId> FAppleSentrySubsystem::CaptureEnsure(const FString& type, | |
SentryEvent *exceptionEvent = [[SENTRY_APPLE_CLASS(SentryEvent) alloc] init]; | ||
exceptionEvent.exceptions = nativeExceptionArray; | ||
|
||
SentryId* id = [SENTRY_APPLE_CLASS(SentrySDK) captureEvent:exceptionEvent]; | ||
SentryId* id = [SENTRY_APPLE_CLASS(SentrySDK) captureEvent:exceptionEvent withScopeBlock:^(SentryScope* scope) { | ||
if(isGameLogAttachmentEnabled) { | ||
const FString logFilePath = GetGameLogPath(); | ||
SentryAttachment* logAttachment = [[SENTRY_APPLE_CLASS(SentryAttachment) alloc] initWithPath:logFilePath.GetNSString()]; | ||
[scope addAttachment:logAttachment]; | ||
} | ||
}]; | ||
|
||
return MakeShareable(new SentryIdApple(id)); | ||
} | ||
|
||
|
@@ -389,18 +407,18 @@ TSharedPtr<ISentryTransactionContext> FAppleSentrySubsystem::ContinueTrace(const | |
return MakeShareable(new SentryTransactionContextApple(transactionContext)); | ||
} | ||
|
||
void FAppleSentrySubsystem::UploadScreenshotForEvent(TSharedPtr<ISentryId> eventId, const FString& screenshotPath) const | ||
void FAppleSentrySubsystem::UploadAttachmentForEvent(TSharedPtr<ISentryId> eventId, const FString& filePath, const FString& name, bool deleteAfterUpload) const | ||
{ | ||
IFileManager& fileManager = IFileManager::Get(); | ||
if (!fileManager.FileExists(*screenshotPath)) | ||
if (!fileManager.FileExists(*filePath)) | ||
{ | ||
UE_LOG(LogSentrySdk, Error, TEXT("Failed to upload screenshot - path provided did not exist: %s"), *screenshotPath); | ||
UE_LOG(LogSentrySdk, Error, TEXT("Failed to upload attachment - file path provided did not exist: %s"), *filePath); | ||
return; | ||
} | ||
|
||
const FString& screenshotFilePathExt = fileManager.ConvertToAbsolutePathForExternalAppForRead(*screenshotPath); | ||
const FString& filePathExt = fileManager.ConvertToAbsolutePathForExternalAppForRead(*filePath); | ||
|
||
SentryAttachment* screenshotAttachment = [[SENTRY_APPLE_CLASS(SentryAttachment) alloc] initWithPath:screenshotFilePathExt.GetNSString() filename:@"screenshot.png"]; | ||
SentryAttachment* screenshotAttachment = [[SENTRY_APPLE_CLASS(SentryAttachment) alloc] initWithPath:filePathExt.GetNSString() filename:name.GetNSString()]; | ||
|
||
SentryOptions* options = [SENTRY_APPLE_CLASS(PrivateSentrySDKOnly) options]; | ||
int32 size = options.maxAttachmentSize; | ||
|
@@ -413,10 +431,12 @@ void FAppleSentrySubsystem::UploadScreenshotForEvent(TSharedPtr<ISentryId> event | |
|
||
[SENTRY_APPLE_CLASS(PrivateSentrySDKOnly) captureEnvelope:envelope]; | ||
|
||
// After uploading screenshot it's no longer needed so delete | ||
if (!fileManager.Delete(*screenshotPath)) | ||
if (deleteAfterUpload) | ||
{ | ||
UE_LOG(LogSentrySdk, Error, TEXT("Failed to delete screenshot: %s"), *screenshotPath); | ||
if (!fileManager.Delete(*filePath)) | ||
{ | ||
UE_LOG(LogSentrySdk, Error, TEXT("Failed to delete file attachment after upload: %s"), *filePath); | ||
} | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,25 @@ | ||
#pragma once | ||
|
||
#include "Apple/AppleSentrySubsystem.h" | ||
|
||
class FIOSSentrySubsystem : public FAppleSentrySubsystem | ||
{ | ||
public: | ||
virtual void InitWithSettings( | ||
const USentrySettings* Settings, | ||
USentryBeforeSendHandler* BeforeSendHandler, | ||
USentryBeforeBreadcrumbHandler* BeforeBreadcrumbHandler, | ||
USentryTraceSampler* TraceSampler | ||
) override; | ||
|
||
virtual FString TryCaptureScreenshot() const override; | ||
}; | ||
|
||
typedef FIOSSentrySubsystem FPlatformSentrySubsystem; | ||
#pragma once | ||
|
||
#include "Apple/AppleSentrySubsystem.h" | ||
|
||
class FIOSSentrySubsystem : public FAppleSentrySubsystem | ||
{ | ||
public: | ||
virtual void InitWithSettings( | ||
const USentrySettings* Settings, | ||
USentryBeforeSendHandler* BeforeSendHandler, | ||
USentryBeforeBreadcrumbHandler* BeforeBreadcrumbHandler, | ||
USentryTraceSampler* TraceSampler | ||
) override; | ||
|
||
virtual FString TryCaptureScreenshot() const override; | ||
|
||
protected: | ||
virtual FString GetGameLogPath() const override; | ||
virtual FString GetLatestGameLog() const override; | ||
|
||
private: | ||
FString NormalizeToPublicIOSPath(const FString& logFilePath) const; | ||
}; | ||
|
||
typedef FIOSSentrySubsystem FPlatformSentrySubsystem; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The section on the changelog is already "Fixes" so we could (going forward, from the next release perhaps) avoid starting the message with Fix.
Personally I'd be more interested in which platform the fix relates to. So this is a iOS/Mac, could be:
Or something like that.