diff options
| author | Dan Engelbrecht <[email protected]> | 2025-05-06 16:50:57 +0200 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2025-05-06 16:50:57 +0200 |
| commit | 6d9ff7e404a22ed1cc7e529cfa77ef7d593d9547 (patch) | |
| tree | 5cfea359c44b02fe72ab5b166e9b03900444fcba /src/zenserver | |
| parent | cleanup changelog (diff) | |
| download | zen-6d9ff7e404a22ed1cc7e529cfa77ef7d593d9547.tar.xz zen-6d9ff7e404a22ed1cc7e529cfa77ef7d593d9547.zip | |
add sentry for zen command (#373)
* refactor sentry integration and add to zen command line tool
* move add_ldflags("-framework Security")
Diffstat (limited to 'src/zenserver')
| -rw-r--r-- | src/zenserver/main.cpp | 2 | ||||
| -rw-r--r-- | src/zenserver/sentryintegration.cpp | 324 | ||||
| -rw-r--r-- | src/zenserver/sentryintegration.h | 50 | ||||
| -rw-r--r-- | src/zenserver/xmake.lua | 15 | ||||
| -rw-r--r-- | src/zenserver/zenserver.cpp | 3 |
5 files changed, 2 insertions, 392 deletions
diff --git a/src/zenserver/main.cpp b/src/zenserver/main.cpp index 78ddd39a0..0f647cd5c 100644 --- a/src/zenserver/main.cpp +++ b/src/zenserver/main.cpp @@ -10,6 +10,7 @@ #include <zencore/fmtutils.h> #include <zencore/logging.h> #include <zencore/scopeguard.h> +#include <zencore/sentryintegration.h> #include <zencore/session.h> #include <zencore/string.h> #include <zencore/thread.h> @@ -25,7 +26,6 @@ #include "config.h" #include "diag/logging.h" -#include "sentryintegration.h" #if ZEN_PLATFORM_WINDOWS # include <zencore/windows.h> diff --git a/src/zenserver/sentryintegration.cpp b/src/zenserver/sentryintegration.cpp deleted file mode 100644 index 7996f25bb..000000000 --- a/src/zenserver/sentryintegration.cpp +++ /dev/null @@ -1,324 +0,0 @@ -// Copyright Epic Games, Inc. All Rights Reserved. - -#include "sentryintegration.h" - -#include <zencore/config.h> -#include <zencore/logging.h> -#include <zencore/session.h> -#include <zencore/uid.h> - -#include <stdarg.h> -#include <stdio.h> - -#if ZEN_PLATFORM_LINUX -# include <pwd.h> -#endif - -#if ZEN_PLATFORM_MAC -# include <pwd.h> -#endif - -ZEN_THIRD_PARTY_INCLUDES_START -#include <spdlog/spdlog.h> -ZEN_THIRD_PARTY_INCLUDES_END - -#if ZEN_USE_SENTRY -# define SENTRY_BUILD_STATIC 1 -ZEN_THIRD_PARTY_INCLUDES_START -# include <sentry.h> -# include <spdlog/sinks/base_sink.h> -ZEN_THIRD_PARTY_INCLUDES_END - -namespace sentry { - -struct SentryAssertImpl : zen::AssertImpl -{ - virtual void ZEN_FORCENOINLINE ZEN_DEBUG_SECTION - OnAssert(const char* Filename, int LineNumber, const char* FunctionName, const char* Msg, zen::CallstackFrames* Callstack) override; -}; - -class sentry_sink final : public spdlog::sinks::base_sink<spdlog::details::null_mutex> -{ -public: - sentry_sink(); - ~sentry_sink(); - -protected: - void sink_it_(const spdlog::details::log_msg& msg) override; - void flush_() override; -}; - -////////////////////////////////////////////////////////////////////////// - -static constexpr sentry_level_t MapToSentryLevel[spdlog::level::level_enum::n_levels] = {SENTRY_LEVEL_DEBUG, - SENTRY_LEVEL_DEBUG, - SENTRY_LEVEL_INFO, - SENTRY_LEVEL_WARNING, - SENTRY_LEVEL_ERROR, - SENTRY_LEVEL_FATAL, - SENTRY_LEVEL_DEBUG}; - -sentry_sink::sentry_sink() -{ -} -sentry_sink::~sentry_sink() -{ -} - -void -sentry_sink::sink_it_(const spdlog::details::log_msg& msg) -{ - if (msg.level != spdlog::level::err && msg.level != spdlog::level::critical) - { - return; - } - try - { - std::string Message = fmt::format("{}\n{}({}) [{}]", msg.payload, msg.source.filename, msg.source.line, msg.source.funcname); - sentry_value_t event = sentry_value_new_message_event( - /* level */ MapToSentryLevel[msg.level], - /* logger */ nullptr, - /* message */ Message.c_str()); - sentry_event_value_add_stacktrace(event, NULL, 0); - sentry_capture_event(event); - } - catch (const std::exception&) - { - // If our logging with Message formatting fails we do a non-allocating version and just post the msg.payload raw - char TmpBuffer[256]; - size_t MaxCopy = zen::Min<size_t>(msg.payload.size(), size_t(255)); - memcpy(TmpBuffer, msg.payload.data(), MaxCopy); - TmpBuffer[MaxCopy] = '\0'; - sentry_value_t event = sentry_value_new_message_event( - /* level */ SENTRY_LEVEL_ERROR, - /* logger */ nullptr, - /* message */ TmpBuffer); - sentry_event_value_add_stacktrace(event, NULL, 0); - sentry_capture_event(event); - } -} -void -sentry_sink::flush_() -{ -} - -void -SentryAssertImpl::OnAssert(const char* Filename, int LineNumber, const char* FunctionName, const char* Msg, zen::CallstackFrames* Callstack) -{ - // Sentry will provide its own callstack - ZEN_UNUSED(Callstack); - try - { - std::string Message = fmt::format("ASSERT {}:({}) [{}]\n\"{}\"", Filename, LineNumber, FunctionName, Msg); - sentry_value_t event = sentry_value_new_message_event( - /* level */ SENTRY_LEVEL_ERROR, - /* logger */ nullptr, - /* message */ Message.c_str()); - sentry_event_value_add_stacktrace(event, NULL, 0); - sentry_capture_event(event); - } - catch (const std::exception&) - { - // If our logging with Message formatting fails we do a non-allocating version and just post the Msg raw - sentry_value_t event = sentry_value_new_message_event( - /* level */ SENTRY_LEVEL_ERROR, - /* logger */ nullptr, - /* message */ Msg); - sentry_event_value_add_stacktrace(event, NULL, 0); - sentry_capture_event(event); - } -} - -} // namespace sentry - -namespace zen { - -# if ZEN_USE_SENTRY -static void -SentryLogFunction(sentry_level_t Level, const char* Message, va_list Args, [[maybe_unused]] void* Userdata) -{ - char LogMessageBuffer[160]; - std::string LogMessage; - const char* MessagePtr = LogMessageBuffer; - - int n = vsnprintf(LogMessageBuffer, sizeof LogMessageBuffer, Message, Args); - - if (n >= int(sizeof LogMessageBuffer)) - { - LogMessage.resize(n + 1); - - n = vsnprintf(LogMessage.data(), LogMessage.size(), Message, Args); - - MessagePtr = LogMessage.c_str(); - } - - switch (Level) - { - case SENTRY_LEVEL_DEBUG: - ZEN_CONSOLE_DEBUG("sentry: {}", MessagePtr); - break; - - case SENTRY_LEVEL_INFO: - ZEN_CONSOLE_INFO("sentry: {}", MessagePtr); - break; - - case SENTRY_LEVEL_WARNING: - ZEN_CONSOLE_WARN("sentry: {}", MessagePtr); - break; - - case SENTRY_LEVEL_ERROR: - ZEN_CONSOLE_ERROR("sentry: {}", MessagePtr); - break; - - case SENTRY_LEVEL_FATAL: - ZEN_CONSOLE_CRITICAL("sentry: {}", MessagePtr); - break; - } -} -# endif - -SentryIntegration::SentryIntegration() -{ -} - -SentryIntegration::~SentryIntegration() -{ - if (m_IsInitialized && m_SentryErrorCode == 0) - { - logging::SetErrorLog(""); - m_SentryAssert.reset(); - sentry_close(); - } -} - -void -SentryIntegration::Initialize(std::string SentryDatabasePath, - std::string SentryAttachmentsPath, - bool AllowPII, - const std::string& CommandLine) -{ - m_AllowPII = AllowPII; - - if (SentryDatabasePath.starts_with("\\\\?\\")) - { - SentryDatabasePath = SentryDatabasePath.substr(4); - } - sentry_options_t* SentryOptions = sentry_options_new(); - sentry_options_set_dsn(SentryOptions, "https://[email protected]/5919284"); - sentry_options_set_database_path(SentryOptions, SentryDatabasePath.c_str()); - sentry_options_set_logger(SentryOptions, SentryLogFunction, this); - if (SentryAttachmentsPath.starts_with("\\\\?\\")) - { - SentryAttachmentsPath = SentryAttachmentsPath.substr(4); - } - sentry_options_add_attachment(SentryOptions, SentryAttachmentsPath.c_str()); - sentry_options_set_release(SentryOptions, ZEN_CFG_VERSION); - - // sentry_options_set_debug(SentryOptions, 1); - - m_SentryErrorCode = sentry_init(SentryOptions); - - if (m_SentryErrorCode == 0) - { - sentry_value_t SentryUserObject = sentry_value_new_object(); - - if (m_AllowPII) - { -# if ZEN_PLATFORM_WINDOWS - CHAR Buffer[511 + 1]; - DWORD BufferLength = sizeof(Buffer) / sizeof(CHAR); - BOOL OK = GetUserNameA(Buffer, &BufferLength); - if (OK && BufferLength) - { - m_SentryUserName = std::string(Buffer, BufferLength - 1); - } - BufferLength = sizeof(Buffer) / sizeof(CHAR); - OK = GetComputerNameA(Buffer, &BufferLength); - if (OK && BufferLength) - { - m_SentryHostName = std::string(Buffer, BufferLength); - } - else - { - m_SentryHostName = "unknown"; - } -# endif // ZEN_PLATFORM_WINDOWS - -# if (ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC) - uid_t uid = geteuid(); - struct passwd* pw = getpwuid(uid); - if (pw) - { - m_SentryUserName = std::string(pw->pw_name); - } - else - { - m_SentryUserName = "unknown"; - } - char HostNameBuffer[1023 + 1]; - int err = gethostname(HostNameBuffer, sizeof(HostNameBuffer)); - if (err == 0) - { - m_SentryHostName = std::string(HostNameBuffer); - } - else - { - m_SentryHostName = "unknown"; - } -# endif - m_SentryId = fmt::format("{}@{}", m_SentryUserName, m_SentryHostName); - sentry_value_set_by_key(SentryUserObject, "id", sentry_value_new_string(m_SentryId.c_str())); - sentry_value_set_by_key(SentryUserObject, "username", sentry_value_new_string(m_SentryUserName.c_str())); - sentry_value_set_by_key(SentryUserObject, "ip_address", sentry_value_new_string("{{auto}}")); - } - - sentry_value_set_by_key(SentryUserObject, "cmd", sentry_value_new_string(CommandLine.c_str())); - - const std::string SessionId(GetSessionIdString()); - sentry_value_set_by_key(SentryUserObject, "session", sentry_value_new_string(SessionId.c_str())); - - sentry_set_user(SentryUserObject); - - m_SentryLogger = spdlog::create<sentry::sentry_sink>("sentry"); - logging::SetErrorLog("sentry"); - - m_SentryAssert = std::make_unique<sentry::SentryAssertImpl>(); - } - - m_IsInitialized = true; -} - -void -SentryIntegration::LogStartupInformation() -{ - if (m_IsInitialized) - { - if (m_SentryErrorCode == 0) - { - if (m_AllowPII) - { - ZEN_INFO("sentry initialized, username: '{}', hostname: '{}', id: '{}'", m_SentryUserName, m_SentryHostName, m_SentryId); - } - else - { - ZEN_INFO("sentry initialized with anonymous reports"); - } - } - else - { - ZEN_WARN( - "sentry_init returned failure! (error code: {}) note that sentry expects crashpad_handler to exist alongside the running " - "executable", - m_SentryErrorCode); - } - } -} - -void -SentryIntegration::ClearCaches() -{ - sentry_clear_modulecache(); -} - -} // namespace zen -#endif diff --git a/src/zenserver/sentryintegration.h b/src/zenserver/sentryintegration.h deleted file mode 100644 index 40e22af4e..000000000 --- a/src/zenserver/sentryintegration.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright Epic Games, Inc. All Rights Reserved. - -#pragma once - -#include <zencore/intmath.h> -#include <zencore/zencore.h> - -#if !defined(ZEN_USE_SENTRY) -# define ZEN_USE_SENTRY 1 -#endif - -#if ZEN_USE_SENTRY - -# include <memory> - -ZEN_THIRD_PARTY_INCLUDES_START -# include <spdlog/logger.h> -ZEN_THIRD_PARTY_INCLUDES_END - -namespace sentry { - -struct SentryAssertImpl; - -} // namespace sentry - -namespace zen { - -class SentryIntegration -{ -public: - SentryIntegration(); - ~SentryIntegration(); - - void Initialize(std::string SentryDatabasePath, std::string SentryAttachmentsPath, bool AllowPII, const std::string& CommandLine); - void LogStartupInformation(); - static void ClearCaches(); - -private: - int m_SentryErrorCode = 0; - bool m_IsInitialized = false; - bool m_AllowPII = false; - std::unique_ptr<sentry::SentryAssertImpl> m_SentryAssert; - std::string m_SentryUserName; - std::string m_SentryHostName; - std::string m_SentryId; - std::shared_ptr<spdlog::logger> m_SentryLogger; -}; - -} // namespace zen -#endif diff --git a/src/zenserver/xmake.lua b/src/zenserver/xmake.lua index a3d7aa124..470fbd24e 100644 --- a/src/zenserver/xmake.lua +++ b/src/zenserver/xmake.lua @@ -28,8 +28,6 @@ target("zenserver") add_cxxflags("/bigobj") add_links("delayimp", "projectedfslib") add_ldflags("/delayload:ProjectedFSLib.dll") - - add_links("dbghelp", "winhttp", "version") -- for Sentry else remove_files("windows/**") end @@ -41,7 +39,6 @@ target("zenserver") add_ldflags("-framework Foundation") add_ldflags("-framework Security") add_ldflags("-framework SystemConfiguration") - add_syslinks("bsm") end add_options("compute") @@ -57,18 +54,6 @@ target("zenserver") "vcpkg::sol2" ) - if has_config("zensentry") then - add_packages("vcpkg::sentry-native") - end - - if is_plat("linux") then - -- As sentry_native uses symbols from breakpad_client, the latter must - -- be specified after the former with GCC-like toolchains. xmake however - -- is unaware of this and simply globs files from vcpkg's output. The - -- line below forces breakpad_client to be to the right of sentry_native - add_syslinks("breakpad_client") - end - -- to work around some unfortunate Ctrl-C behaviour on Linux/Mac due to -- our use of setsid() at startup we pass in `--no-detach` to zenserver -- ensure that it recieves signals when the user requests termination diff --git a/src/zenserver/zenserver.cpp b/src/zenserver/zenserver.cpp index 3f2f01d5a..366944ffc 100644 --- a/src/zenserver/zenserver.cpp +++ b/src/zenserver/zenserver.cpp @@ -2,8 +2,6 @@ #include "zenserver.h" -#include "sentryintegration.h" - #include <zenbase/refcount.h> #include <zencore/basicfile.h> #include <zencore/compactbinarybuilder.h> @@ -16,6 +14,7 @@ #include <zencore/jobqueue.h> #include <zencore/logging.h> #include <zencore/scopeguard.h> +#include <zencore/sentryintegration.h> #include <zencore/session.h> #include <zencore/string.h> #include <zencore/thread.h> |