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

CURA-11364 Add Sentry Support #1985

Merged
merged 22 commits into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
b932d37
Add sentry to CuraEngine
nallath Nov 20, 2023
7d6dc2c
Also add sentry to CMakeLists
nallath Nov 20, 2023
67b924d
Applied clang-format.
nallath Nov 20, 2023
5e22539
Correctly set the version number when sending to sentry
nallath Nov 20, 2023
10d66c5
Merge branch 'CURA-11364_add_sentry' of github.com:Ultimaker/CuraEngi…
nallath Nov 20, 2023
785490c
Applied clang-format.
nallath Nov 20, 2023
02cb17c
Store sentry logs in correct place
nallath Nov 21, 2023
b5d4754
Merge branch 'CURA-11364_add_sentry' of github.com:Ultimaker/CuraEngi…
nallath Nov 21, 2023
c6047b7
Add optional Sentry integration
jellespijker Nov 21, 2023
17466d0
Use format to create the versionstring
nallath Nov 21, 2023
adfa140
Applied clang-format.
nallath Nov 21, 2023
7af9a1a
Refactor sentry options and improve code readability
jellespijker Nov 21, 2023
2ad7536
Applied clang-format.
jellespijker Nov 21, 2023
7a6098c
Add instruction how to set sentry_url in the code
nallath Nov 21, 2023
14e8ec0
Only send sentry data if use_sentry env is set
nallath Nov 21, 2023
b9cbe33
Applied clang-format.
nallath Nov 21, 2023
c05b776
Refactor sentry config path generation
jellespijker Nov 21, 2023
f397fb5
Log Sentry URL and Path
jellespijker Nov 21, 2023
5ef89b5
Set sentry environment based on version
jellespijker Nov 21, 2023
d020d0f
Fix Sentry (crash logging) for Win64.
rburema Nov 22, 2023
67eb8e0
'Fix' weird Win64 issue with ranges-library.
rburema Nov 22, 2023
686df6a
Merge branch 'main' into CURA-11364_add_sentry
casperlamboo Nov 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ option(ENABLE_BENCHMARKS "Build with Benchmarks" OFF)
option(EXTENSIVE_WARNINGS "Build with all warnings" ON)
option(ENABLE_PLUGINS "Build with plugins" ON)
option(ENABLE_REMOTE_PLUGINS "Build with all warnings" OFF)
option(ENABLE_SENTRY "Send crash data via Sentry" OFF)
option(ENABLE_MORE_COMPILER_OPTIMIZATION_FLAGS "Enable more optimization flags" ON)
option(USE_SYSTEM_LIBS "Use the system libraries if available" OFF)
option(OLDER_APPLE_CLANG "Apple Clang <= 13 used" OFF)
Expand Down Expand Up @@ -203,6 +204,10 @@ find_package(range-v3 REQUIRED)
find_package(scripta REQUIRED)
find_package(semver REQUIRED)

if (ENABLE_SENTRY)
find_package(sentry REQUIRED)
endif ()

if (ENABLE_TESTING)
find_package(GTest REQUIRED)
endif ()
Expand Down Expand Up @@ -240,8 +245,14 @@ else ()
endif (NOT WIN32)

use_threads(CuraEngine)
target_link_libraries(CuraEngine PRIVATE _CuraEngine)
target_compile_definitions(CuraEngine PRIVATE VERSION=\"${CURA_ENGINE_VERSION}\")
target_link_libraries(CuraEngine PRIVATE
_CuraEngine
$<$<BOOL:${ENABLE_SENTRY}>:sentry::sentry>
)
target_compile_definitions(CuraEngine PRIVATE
$<$<BOOL:${ENABLE_SENTRY}>:SENTRY_URL=\"${SENTRY_URL}\">
VERSION=\"${CURA_ENGINE_VERSION}\"
)

# Compiling the test environment.
if (ENABLE_TESTING OR ENABLE_BENCHMARKS)
Expand Down
15 changes: 13 additions & 2 deletions conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
from conan.tools.files import copy, mkdir
from conan.tools.cmake import CMakeToolchain, CMakeDeps, CMake, cmake_layout
from conan.tools.build import check_min_cppstd
from conan.tools.scm import Version
from conan.tools.scm import Version, Git


required_conan_version = ">=1.58.0 <2.0.0"

Expand All @@ -28,19 +29,22 @@ class CuraEngineConan(ConanFile):
"enable_benchmarks": [True, False],
"enable_extensive_warnings": [True, False],
"enable_plugins": [True, False],
"enable_sentry": [True, False],
"enable_remote_plugins": [True, False],
}
default_options = {
"enable_arcus": True,
"enable_benchmarks": False,
"enable_extensive_warnings": False,
"enable_plugins": True,
"enable_sentry": False,
casperlamboo marked this conversation as resolved.
Show resolved Hide resolved
"enable_remote_plugins": False,
}

def set_version(self):
if not self.version:
self.version = "5.7.0-alpha"
git = Git(self)
self.version = f"5.7.0-alpha+{git.get_commit()[:6]}"

def export_sources(self):
copy(self, "CMakeLists.txt", self.recipe_folder, self.export_sources_folder)
Expand All @@ -57,6 +61,8 @@ def export_sources(self):
def config_options(self):
if not self.options.enable_plugins:
del self.options.enable_remote_plugins
if self.conf.get("user.curaengine:sentry_url", "", check_type=str) == "":
del self.options.enable_sentry

def configure(self):
self.options["boost"].header_only = True
Expand Down Expand Up @@ -85,6 +91,8 @@ def build_requirements(self):
def requirements(self):
if self.options.enable_arcus:
self.requires("arcus/5.3.0")
if self.options.get_safe("enable_sentry", False):
self.requires("sentry-native/0.6.5")
self.requires("asio-grpc/2.6.0")
self.requires("grpc/1.50.1")
self.requires("curaengine_grpc_definitions/(latest)@ultimaker/testing")
Expand Down Expand Up @@ -112,6 +120,9 @@ def generate(self):
tc.variables["ENABLE_BENCHMARKS"] = self.options.enable_benchmarks
tc.variables["EXTENSIVE_WARNINGS"] = self.options.enable_extensive_warnings
tc.variables["OLDER_APPLE_CLANG"] = self.settings.compiler == "apple-clang" and Version(self.settings.compiler.version) < "14"
if self.options.get_safe("enable_sentry", False):
tc.variables["ENABLE_SENTRY"] = True
tc.variables["SENTRY_URL"] = self.conf.get("user.curaengine:sentry_url", "", check_type=str)
if self.options.enable_plugins:
tc.variables["ENABLE_PLUGINS"] = True
tc.variables["ENABLE_REMOTE_PLUGINS"] = self.options.enable_remote_plugins
Expand Down
47 changes: 47 additions & 0 deletions include/utils/format/filesystem_path.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright (c) 2023 UltiMaker
// CuraEngine is released under the terms of the AGPLv3 or higher

#ifndef CURAENGINE_INCLUDE_UTILS_FORMAT_FILESYSTEM_PATH_H
#define CURAENGINE_INCLUDE_UTILS_FORMAT_FILESYSTEM_PATH_H

#include <cstdlib>
#include <filesystem>

#include <fmt/core.h>

namespace fmt
{
template<>
struct formatter<std::filesystem::path> : formatter<string_view>
{
static std::string USERNAME;
static constexpr std::string_view OBFUSCATED_STRING = "*******";

[[nodiscard]] static std::string anonymizePath(const std::string& path)
{
std::string anonymized_path = path;
size_t pos = anonymized_path.find(USERNAME);
while (pos != std::string::npos)
{
anonymized_path.replace(pos, USERNAME.size(), OBFUSCATED_STRING);
pos = anonymized_path.find(USERNAME, pos + OBFUSCATED_STRING.size());
}
return anonymized_path;
}

template<typename FormatContext>
auto format(const std::filesystem::path& path, FormatContext& ctx)
{
return formatter<string_view>::format(anonymizePath(path.generic_string()), ctx);
}
};

#ifdef _WIN32
std::string fmt::formatter<std::filesystem::path>::USERNAME = std::getenv("USERNAME") != nullptr ? std::getenv("USERNAME") : "";
#else
std::string fmt::formatter<std::filesystem::path>::USERNAME = std::getenv("USER") != nullptr ? std::getenv("USER") : "";
#endif

} // namespace fmt

#endif // CURAENGINE_INCLUDE_UTILS_FORMAT_FILESYSTEM_PATH_H
76 changes: 75 additions & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2022 Ultimaker B.V.
// Copyright (c) 2023 UltiMaker
// CuraEngine is released under the terms of the AGPLv3 or higher

#include <iostream> //To change the formatting of std::cerr.
Expand All @@ -7,6 +7,19 @@
#include <sys/resource.h> //For setpriority.
#endif

#ifdef SENTRY_URL
#include <filesystem>
#include <semver.hpp>
#include <sentry.h>
#include <string>

#include <range/v3/algorithm/contains.hpp>
#include <range/v3/range/conversion.hpp>

#include "utils/format/filesystem_path.h"
#endif
#include <cstdlib>

#include <spdlog/spdlog.h>

#include "Application.h"
Expand Down Expand Up @@ -37,7 +50,68 @@ int main(int argc, char** argv)
#endif
std::cerr << std::boolalpha;


// Want to set the sentry URL? Use '-c user.curaengine:sentry_url=<url> -o curaengine:enable_sentry=True' with conan install
#ifdef SENTRY_URL
bool use_sentry = true;
if (const char* use_sentry_env = std::getenv("use_sentry"))
{
if (std::strcmp(use_sentry_env, "0") == 0)
{
use_sentry = false;
}
}
if (use_sentry)
{
// Setup sentry error handling.
sentry_options_t* options = sentry_options_new();
sentry_options_set_dsn(options, std::string(SENTRY_URL).c_str());
spdlog::info("Sentry url: {}", std::string(SENTRY_URL).c_str());
// This is also the default-path. For further information and recommendations:
// https://docs.sentry.io/platforms/native/configuration/options/#database-path
#if defined(__linux__)
const auto config_path = std::filesystem::path(fmt::format("{}/.local/share/cura/.sentry-native", std::getenv("HOME")));
#elif defined(__APPLE__) && defined(__MACH__)
const auto config_path = std::filesystem::path(fmt::format("{}/Library/Application Support/cura/.sentry-native", std::getenv("HOME")));
#elif defined(_WIN64)
const auto config_path = std::filesystem::path(fmt::format("{}\\cura\\.sentry-native", std::getenv("APPDATA")));
#endif
spdlog::info("Sentry config path: {}", config_path);
sentry_options_set_database_path(options, std::filesystem::absolute(config_path).generic_string().c_str());
constexpr std::string_view cura_engine_version{ CURA_ENGINE_VERSION };
const auto version = semver::from_string(cura_engine_version.substr(0, cura_engine_version.find_first_of('+')));
if (ranges::contains(cura_engine_version, '+') || version.prerelease_type == semver::prerelease::alpha)
{
// Not a production build
sentry_options_set_environment(options, "development");
sentry_options_set_release(
options,
fmt::format(
"curaengine@{}.{}.{}-{}.{}",
version.major,
version.minor,
version.patch,
version.prerelease_type == semver::prerelease::alpha ? "alpha" : "beta",
version.prerelease_number)
.c_str());
}
else
{
sentry_options_set_environment(options, "production");
sentry_options_set_release(options, fmt::format("curaengine@{}", version.to_string()).c_str());
}
sentry_init(options);
}
#endif

cura::Application::getInstance().run(argc, argv);

#ifdef SENTRY_URL
if (use_sentry)
{
sentry_close();
}
#endif

return 0;
}
Loading