Skip to content
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

Work-in-progress extension #3

Merged
merged 75 commits into from
Oct 21, 2024
Merged

Conversation

limbonaut
Copy link
Collaborator

@limbonaut limbonaut commented Oct 9, 2024

Godot SDK initial development. Currently, works on Linux. Windows target has issues with the build process at the moment.

Requirements: Git, C++ compiler, python & SCons build tool, CMake.

Features so far:

  • Sentry singleton exported to GDScript to be used by game devs
  • Tags
  • Breadcrumbs
  • Contexts
    • Device, App, etc.
    • Including useful engine-specific stats in custom contexts
    • User-supplied contexts
  • Configuration (project-specific)
  • Capture message events
  • Capture crashes on Linux and Windows*
  • Detecting environments (release export, editor, headless server, etc.)
  • Log file attachment

Screenshots

Demo project

2024-10-10_12-48-29

Sentry extension settings

2024-10-10_12-46-20

What's included:
* Minimal Godot C++ extension code - buildable and runnable.
* .gdextension manifest template (most targets specified except iOS for now)
* SCons build file
    * Automatic cloning of godot-cpp (we may decide to use submodule though)
    * .gdextension manifest deployment with substitutions
* clang format file for consistent style and automatic formatting
* .git-ignore with common offenders
Edit sentry/config/dsn to assing your project's DSN. Later, we can add GUI for settings.
Executable is expected to be in the addons/sentrysdk/bin/ folder for the editor, and in the same folder as executable for exported projects.
Expected names:
- Linux: crashpad_handler
- Windows: crashpad_handler.exe
Will be used when hints are needed in project settings.
@bruno-garcia
Copy link
Member

Do you plan on adding some unit tests (and/or integration tests) on this PR already or is that landing after we get this into main?

@limbonaut
Copy link
Collaborator Author

Need to consider, from a technical perspective, what can be tested and how it can be tested.

@limbonaut
Copy link
Collaborator Author

Hello, Windows.
image

- Use the same build steps for sentry-native on Linux as on Windows
- Linux sentry-native build script
- Don't build sentry-native in parallel
- Use `sentry-native/src` source dir as dependency
- Remove sentry-native/{install,build} on `scons --clean`
@bruno-garcia
Copy link
Member

woo awesome.

Should we merge this?

@limbonaut
Copy link
Collaborator Author

@bruno-garcia
I'm going to test if I didn't break anything on Windows, update the README with the new instructions, and check the sources if I didn't leave any weird bits. And then I think it can be merged.

Also, we need a license in the repo, so it's clear what the terms are for the source code. Can you add it?

@limbonaut limbonaut marked this pull request as ready for review October 11, 2024 18:36
Copy link

@bitsandfoxes bitsandfoxes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is coming together so nicely!

README.md Show resolved Hide resolved
The build process should produce a GDExtension library file for the ***editor target*** at `project/addons/sentrysdk/bin/libsentrysdk.*.editor.*`.

To export a project in Godot that uses this extension, you'll also need the libraries for the export templates:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, so you need two sets of libraries: Editor and Release. The Release ones actually make it into the exported game. Makes sense.
I wonder if there is something that we can do with that. This way we have a guaranteed way of knowing whether the SDK is in use in the editor or in production. I'm thinking of debug logging, verbosity levels, error capture. We probably should not mess with default options tho.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are preprocessor defines for build options, and you can add your own, of course. Useful for conditional code inclusion for different builds, platforms, etc.

SConstruct Show resolved Hide resolved

def build_sentry_native(target, source, env):
result = subprocess.run(
["sh", "scripts/build-sentry-native.sh"],

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've not looked at the script (yet) but any way to unify this in one script? I see there's also a scripts/build-sentry-native.ps1.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both can be used, really. I figured it's better to stick to something that is guaranteed to exist on a target platform. PowerShell is not really a standard on Linux, for instance, but shell is, and vice versa. On my distro, I don't even have a native powershell package - putting it as a requirement would create an unnecessary barrier. I could try rewriting it in Python - not sure how it would interact with Windows, but it's a possibility.

SConstruct Outdated Show resolved Hide resolved
src/sentry_settings.h Outdated Show resolved Hide resolved
Comment on lines +300 to +308
// double fps_metric = Engine::get_singleton()->get_frames_per_second();
// if (fps_metric) {
// sentry_value_set_by_key(perf_context, "fps",
// sentry_value_new_double(fps_metric));
// }

// Frames drawn since engine started - age metric.
// sentry_value_set_by_key(perf_context, "frames_drawn",
// sentry_value_new_int32(Engine::get_singleton()->get_frames_drawn()));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That'll be really nice at some point!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is some additional context. I commented it out, because I'm not sure if those are useful on crash/error.

}

// TODO: Collect more useful metrics: physics, navigation, audio...
// TODO: Q: Split into categories and make it optional?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do have some developer docs regarding existing contexts here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I consulted with that doc on contexts, but what if we can provide useful info outside established protocols? How do you deal with such? This Performance context is just an idea to provide information that is mostly Godot engine-specific, but nevertheless is quite useful for debugging.

src/sentry_settings.h Outdated Show resolved Hide resolved
src/sentry_singleton.h Show resolved Hide resolved
@bruno-garcia
Copy link
Member

Hey folks, how about we merge this and continue follow ups on main?

Btw please merge it as opposed to squashing it.

@limbonaut
Copy link
Collaborator Author

limbonaut commented Oct 20, 2024

I agree. I continue the work in other branches for now, waiting for this one to be merged. Only adding small fixes.

Copy link
Member

@bruno-garcia bruno-garcia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking great. Please get any open review items in github tickets (or a ticket with checkboxes for smaller stuff), lets get this into main.

Please use branches in this repo instead of a fork to make it easier for collaboration (e.g: branch off of branches etc)

README.md Outdated Show resolved Hide resolved
@@ -0,0 +1,8 @@
#!/bin/sh

pushd sentry-native
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we remove this in favor of the ps1? Or have this wrap that with pwsh ./a.ps1?

// Generates an error on wasm builds.
String unique_id = OS::get_singleton()->get_unique_id();
if (!unique_id.is_empty()) {
sentry_value_set_by_key(device_context, "device_unique_identifier", sentry_value_new_string(unique_id.utf8()));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this identifier consistant across installs? If so, we might want to use a different identifier.
We usually create a new uuid that's unique to that installation. On mobile it's easier since if the app is reinstalled that file is deleted in the process and we get a new id.

The key is, we don't want this id to be the same across different 'godot' apps in the user device, because we don't want this to be used in a tracking manner. The goal is only to allow this app developer to know how many users were impacted by crashes

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is basically like installation ID? Random UUID then?

// Read project config since ProjectSettings singleton may not be initialized at this point.
Ref<ConfigFile> conf = memnew(ConfigFile);
Error err = conf->load("res://project.godot");
ERR_FAIL_COND_MSG(err > 0, "Sentry: Fatal error: Failed to open project config.");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this cause the app/game to crash? We have a policy of supressing errors while logging it all to console (if option.debug=true) but we absolutely can't cause a crash if the SDK fails to do something

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a macro that logs an error to godot logger and returns from the current function. In practice, such error is added to "Errors" tab in the editor if debugging, and in production it is printed to stderr and the log file if enabled. The crash macro has CRASH in the name.

@bruno-garcia bruno-garcia merged commit 83747c3 into getsentry:main Oct 21, 2024
1 check passed
@limbonaut limbonaut deleted the develop branch December 13, 2024 21:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

3 participants