diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b67cf5a..b4409a62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Features - Add support for script context and variables on Apple platforms ([#306](https://github.com/getsentry/sentry-godot/pull/306)) +- Add SentryEvent.to_json() ([#329](https://github.com/getsentry/sentry-godot/pull/329)) ### Improvements diff --git a/android_lib/src/main/java/io/sentry/godotplugin/SentryAndroidGodotPlugin.kt b/android_lib/src/main/java/io/sentry/godotplugin/SentryAndroidGodotPlugin.kt index ea46b9f5..5c08fc1e 100644 --- a/android_lib/src/main/java/io/sentry/godotplugin/SentryAndroidGodotPlugin.kt +++ b/android_lib/src/main/java/io/sentry/godotplugin/SentryAndroidGodotPlugin.kt @@ -4,6 +4,7 @@ import android.util.Log import io.sentry.Attachment import io.sentry.Breadcrumb import io.sentry.Hint +import io.sentry.ISerializer import io.sentry.Sentry import io.sentry.SentryEvent import io.sentry.SentryLevel @@ -20,6 +21,7 @@ import org.godotengine.godot.plugin.GodotPlugin import org.godotengine.godot.plugin.UsedByGodot import org.godotengine.godot.variant.Callable import java.io.File +import java.io.StringWriter import kotlin.random.Random @@ -381,6 +383,15 @@ class SentryAndroidGodotPlugin(godot: Godot) : GodotPlugin(godot) { return getEvent(eventHandle)?.isCrashed == true } + @UsedByGodot + fun eventToJson(eventHandle: Int): String { + val event = getEvent(eventHandle) ?: return "" + val serializer: ISerializer = Sentry.getCurrentScopes().options.serializer + val writer = StringWriter() + serializer.serialize(event, writer) + return writer.toString() + } + @UsedByGodot fun createException(type: String, value: String): Int { val exception = SentryException() diff --git a/doc_classes/SentryEvent.xml b/doc_classes/SentryEvent.xml index e07c5ac4..0f8a7e78 100644 --- a/doc_classes/SentryEvent.xml +++ b/doc_classes/SentryEvent.xml @@ -38,6 +38,12 @@ Sets a tag with the specified [param key] to the given [param value]. + + + + Serializes the event to JSON string. + + diff --git a/src/sentry/android/android_event.cpp b/src/sentry/android/android_event.cpp index 025210a3..43038357 100644 --- a/src/sentry/android/android_event.cpp +++ b/src/sentry/android/android_event.cpp @@ -136,6 +136,11 @@ bool AndroidEvent::is_crash() const { return android_plugin->call(ANDROID_SN(eventIsCrash), event_handle); } +String AndroidEvent::to_json() const { + ERR_FAIL_NULL_V(android_plugin, String()); + return android_plugin->call(ANDROID_SN(eventToJson), event_handle); +} + AndroidEvent::AndroidEvent(Object *p_android_plugin, int32_t p_event_handle) { android_plugin = p_android_plugin; event_handle = p_event_handle; diff --git a/src/sentry/android/android_event.h b/src/sentry/android/android_event.h index 4f6b63cf..145f0c4d 100644 --- a/src/sentry/android/android_event.h +++ b/src/sentry/android/android_event.h @@ -57,6 +57,8 @@ class AndroidEvent : public SentryEvent { virtual bool is_crash() const override; + virtual String to_json() const override; + void set_as_borrowed() { is_borrowed = true; } AndroidEvent() {} diff --git a/src/sentry/android/android_string_names.cpp b/src/sentry/android/android_string_names.cpp index c4f8b4f0..e5f20d9b 100644 --- a/src/sentry/android/android_string_names.cpp +++ b/src/sentry/android/android_string_names.cpp @@ -53,6 +53,7 @@ AndroidStringNames::AndroidStringNames() { eventGetTag = StringName("eventGetTag"); eventMergeContext = StringName("eventMergeContext"); eventIsCrash = StringName("eventIsCrash"); + eventToJson = StringName("eventToJson"); // Exceptions. createException = StringName("createException"); diff --git a/src/sentry/android/android_string_names.h b/src/sentry/android/android_string_names.h index 3467cba7..81922a27 100644 --- a/src/sentry/android/android_string_names.h +++ b/src/sentry/android/android_string_names.h @@ -65,6 +65,7 @@ class AndroidStringNames { StringName eventGetTag; StringName eventMergeContext; StringName eventIsCrash; + StringName eventToJson; // Exceptions. StringName createException; diff --git a/src/sentry/cocoa/cocoa_event.h b/src/sentry/cocoa/cocoa_event.h index 95e060f4..4d037c5f 100644 --- a/src/sentry/cocoa/cocoa_event.h +++ b/src/sentry/cocoa/cocoa_event.h @@ -53,6 +53,8 @@ class CocoaEvent : public sentry::SentryEvent { virtual bool is_crash() const override; + virtual String to_json() const override; + CocoaEvent(objc::SentryEvent *p_cocoa_event); CocoaEvent(); virtual ~CocoaEvent() override; diff --git a/src/sentry/cocoa/cocoa_event.mm b/src/sentry/cocoa/cocoa_event.mm index c5d1ff8c..d3063e8b 100644 --- a/src/sentry/cocoa/cocoa_event.mm +++ b/src/sentry/cocoa/cocoa_event.mm @@ -270,6 +270,20 @@ return cocoa_event.error != nil; } +String CocoaEvent::to_json() const { + ERR_FAIL_NULL_V(cocoa_event, String()); + + NSDictionary *event_dict = [cocoa_event serialize]; + + NSError *error = nil; + NSData *json_data = [NSJSONSerialization dataWithJSONObject:event_dict + options:0 + error:&error]; + ERR_FAIL_COND_V(error != nil, "Sentry: Failed to serialize event to JSON: " + string_from_objc(error.localizedDescription)); + + return String::utf8((const char *)json_data.bytes, json_data.length); +} + CocoaEvent::CocoaEvent() : cocoa_event([[objc::SentryEvent alloc] init]) { } diff --git a/src/sentry/disabled/disabled_event.h b/src/sentry/disabled/disabled_event.h index 437e8ff3..90ad6200 100644 --- a/src/sentry/disabled/disabled_event.h +++ b/src/sentry/disabled/disabled_event.h @@ -56,6 +56,8 @@ class DisabledEvent : public SentryEvent { virtual void add_exception(const Exception &p_exception) override {} virtual bool is_crash() const override { return false; } + + virtual String to_json() const override { return ""; } }; } // namespace sentry diff --git a/src/sentry/native/native_event.cpp b/src/sentry/native/native_event.cpp index 20aa51b4..486c0512 100644 --- a/src/sentry/native/native_event.cpp +++ b/src/sentry/native/native_event.cpp @@ -215,6 +215,13 @@ bool NativeEvent::is_crash() const { return _is_crash; } +String NativeEvent::to_json() const { + char *json_value = sentry_value_to_json(native_event); + String json_str = String::utf8(json_value); + sentry_free(json_value); + return json_str; +} + NativeEvent::NativeEvent(sentry_value_t p_native_event, bool p_is_crash) : _is_crash(p_is_crash) { if (sentry_value_refcount(p_native_event) > 0) { diff --git a/src/sentry/native/native_event.h b/src/sentry/native/native_event.h index 9f813512..136d79c4 100644 --- a/src/sentry/native/native_event.h +++ b/src/sentry/native/native_event.h @@ -56,6 +56,8 @@ class NativeEvent : public SentryEvent { virtual bool is_crash() const override; + virtual String to_json() const override; + NativeEvent(sentry_value_t p_event, bool p_is_crash); NativeEvent(); virtual ~NativeEvent() override; diff --git a/src/sentry/sentry_event.cpp b/src/sentry/sentry_event.cpp index 6f374aa0..b797f329 100644 --- a/src/sentry/sentry_event.cpp +++ b/src/sentry/sentry_event.cpp @@ -27,6 +27,7 @@ void SentryEvent::_bind_methods() { ClassDB::bind_method(D_METHOD("remove_tag", "key"), &SentryEvent::remove_tag); ClassDB::bind_method(D_METHOD("get_tag", "key"), &SentryEvent::get_tag); ClassDB::bind_method(D_METHOD("is_crash"), &SentryEvent::is_crash); + ClassDB::bind_method(D_METHOD("to_json"), &SentryEvent::to_json); ADD_PROPERTY(PropertyInfo(Variant::STRING, "id"), "", "get_id"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "message"), "set_message", "get_message"); diff --git a/src/sentry/sentry_event.h b/src/sentry/sentry_event.h index f58ab15e..98c4f8ff 100644 --- a/src/sentry/sentry_event.h +++ b/src/sentry/sentry_event.h @@ -76,6 +76,8 @@ class SentryEvent : public RefCounted { virtual bool is_crash() const = 0; + virtual String to_json() const = 0; + virtual ~SentryEvent() = default; };