diff options
| author | Dan Engelbrecht <[email protected]> | 2023-04-25 14:50:29 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-04-25 14:50:29 +0200 |
| commit | 0d0697cbe19ed2ef385408f72d754cea99c7bc9a (patch) | |
| tree | 9d05fec6bf2356b56fa432e3e97946adacfc9466 | |
| parent | 0.2.5 (diff) | |
| download | zen-0d0697cbe19ed2ef385408f72d754cea99c7bc9a.tar.xz zen-0d0697cbe19ed2ef385408f72d754cea99c7bc9a.zip | |
fix sentry report callstack (#256)
* Include file, line and function in sentry log error messages
* use sync direct error logger to get correct call stacks on error
* changelog
* use d1trimfile on windows to shorten file path on windows
* constexpr -> consteval
| -rw-r--r-- | CHANGELOG.md | 5 | ||||
| -rw-r--r-- | xmake.lua | 1 | ||||
| -rw-r--r-- | zencore/include/zencore/logging.h | 35 | ||||
| -rw-r--r-- | zencore/logging.cpp | 14 | ||||
| -rw-r--r-- | zencore/testing.cpp | 2 | ||||
| -rw-r--r-- | zenserver/diag/logging.cpp | 51 | ||||
| -rw-r--r-- | zenserver/zenserver.cpp | 38 |
7 files changed, 85 insertions, 61 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 15e24ccee..4d321c1a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,9 @@ ## +- Strip __FILE__ macro names in logging to only include the file name as to not expose file paths of the machine building the executable +- Bugfix: Reporting the correct callstack to sentry on ERROR/CRITICAL failure. +- Extend sentry message with triggering file/line/function + +## 0.2.5 - Feature: Zen command line tool `rpc-record-start` to record all RPC requests to the structured cache - `--path` Recording file path where the rpc requests will be stored - Feature: Zen command line tool `rpc-record-stop` stop the currently active RPC request recording started with `rpc-record-start` @@ -62,6 +62,7 @@ if is_os("windows") then "WIN32_LEAN_AND_MEAN", -- cut down Windows.h "_WIN32_WINNT=0x0A00" ) + add_cxxflags("/d1trimfile:$(curdir)\\") -- add_ldflags("/MAP") end diff --git a/zencore/include/zencore/logging.h b/zencore/include/zencore/logging.h index 8c36c69f0..44e3d40d4 100644 --- a/zencore/include/zencore/logging.h +++ b/zencore/include/zencore/logging.h @@ -17,6 +17,8 @@ spdlog::logger& Default(); void SetDefault(std::shared_ptr<spdlog::logger> NewDefaultLogger); spdlog::logger& ConsoleLog(); spdlog::logger& Get(std::string_view Name); +spdlog::logger* ErrorLog(); +void SetErrorLog(std::shared_ptr<spdlog::logger>&& NewErrorLogger); void InitializeLogging(); void ShutdownLogging(); @@ -33,9 +35,11 @@ Log() } using logging::ConsoleLog; +using logging::ErrorLog; } // namespace zen using zen::ConsoleLog; +using zen::ErrorLog; using zen::Log; struct LogCategory @@ -51,14 +55,27 @@ struct LogCategory std::string Category; }; -#define ZEN_LOG_WITH_LOCATION(logger, loc, level, fmtstr, ...) \ - do \ - { \ - using namespace std::literals; \ - if (logger.should_log(level)) \ - { \ - logger.log(loc, level, fmtstr, ##__VA_ARGS__); \ - } \ +inline consteval bool +LogIsErrorLevel(int level) +{ + return (level == spdlog::level::err || level == spdlog::level::critical); +}; + +#define ZEN_LOG_WITH_LOCATION(logger, loc, level, fmtstr, ...) \ + do \ + { \ + using namespace std::literals; \ + if (logger.should_log(level)) \ + { \ + if (LogIsErrorLevel(level)) \ + { \ + if (auto ErrLogger = zen::logging::ErrorLog(); ErrLogger != nullptr) \ + { \ + ErrLogger->log(loc, level, fmtstr, ##__VA_ARGS__); \ + } \ + } \ + logger.log(loc, level, fmtstr, ##__VA_ARGS__); \ + } \ } while (false); #define ZEN_LOG(logger, level, fmtstr, ...) ZEN_LOG_WITH_LOCATION(logger, spdlog::source_loc{}, level, fmtstr, ##__VA_ARGS__) @@ -91,7 +108,7 @@ struct LogCategory fmtstr##sv, \ ##__VA_ARGS__) -// Helper macros for logging + // Helper macros for logging #define ZEN_TRACE(fmtstr, ...) ZEN_LOG(Log(), spdlog::level::trace, fmtstr##sv, ##__VA_ARGS__) diff --git a/zencore/logging.cpp b/zencore/logging.cpp index c5c0b6446..a6423e2dc 100644 --- a/zencore/logging.cpp +++ b/zencore/logging.cpp @@ -55,6 +55,20 @@ ConsoleLog() return *ConLogger; } +std::shared_ptr<spdlog::logger> TheErrorLogger; + +spdlog::logger* +ErrorLog() +{ + return TheErrorLogger.get(); +} + +void +SetErrorLog(std::shared_ptr<spdlog::logger>&& NewErrorLogger) +{ + TheErrorLogger = std::move(NewErrorLogger); +} + void InitializeLogging() { diff --git a/zencore/testing.cpp b/zencore/testing.cpp index 15be4b716..1599e9d1f 100644 --- a/zencore/testing.cpp +++ b/zencore/testing.cpp @@ -1,3 +1,5 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + #include "zencore/testing.h" #include "zencore/logging.h" diff --git a/zenserver/diag/logging.cpp b/zenserver/diag/logging.cpp index ca569c467..24c7572f4 100644 --- a/zenserver/diag/logging.cpp +++ b/zenserver/diag/logging.cpp @@ -4,15 +4,6 @@ #include "config.h" -#if !defined(ZEN_USE_SENTRY) -# if ZEN_PLATFORM_MAC && ZEN_ARCH_ARM64 -// vcpkg's sentry-native port does not support Arm on Mac. -# define ZEN_USE_SENTRY 0 -# else -# define ZEN_USE_SENTRY 1 -# endif -#endif - ZEN_THIRD_PARTY_INCLUDES_START #include <spdlog/async.h> #include <spdlog/async_logger.h> @@ -23,9 +14,6 @@ ZEN_THIRD_PARTY_INCLUDES_START #include <spdlog/sinks/msvc_sink.h> #include <spdlog/sinks/rotating_file_sink.h> #include <spdlog/sinks/stdout_color_sinks.h> -#if ZEN_USE_SENTRY -# include <sentry.h> -#endif ZEN_THIRD_PARTY_INCLUDES_END #include <zencore/compactbinary.h> @@ -356,38 +344,6 @@ EnableVTMode() } // namespace logging -#if ZEN_USE_SENTRY - -class sentry_sink final : public spdlog::sinks::base_sink<spdlog::details::null_mutex> -{ -public: - sentry_sink() {} - -protected: - 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}; - - void sink_it_(const spdlog::details::log_msg& msg) override - { - if (msg.level >= SPDLOG_LEVEL_ERROR && msg.level <= SPDLOG_LEVEL_CRITICAL) - { - sentry_value_t event = sentry_value_new_message_event( - /* level */ MapToSentryLevel[msg.level], - /* logger */ nullptr, - /* message */ std::string(msg.payload.data(), msg.payload.size()).c_str()); - sentry_event_value_add_stacktrace(event, NULL, 0); - sentry_capture_event(event); - } - } - void flush_() override {} -}; -#endif - void InitializeLogging(const ZenServerOptions& GlobalOptions) { @@ -439,10 +395,6 @@ InitializeLogging(const ZenServerOptions& GlobalOptions) /* rotate on open */ true); #endif -#if ZEN_USE_SENTRY - auto SentrySink = std::make_shared<sentry_sink>(); -#endif - std::set_terminate([]() { ZEN_CRITICAL("Program exited abnormally via std::terminate()"); }); // Default @@ -453,9 +405,6 @@ InitializeLogging(const ZenServerOptions& GlobalOptions) Sinks.clear(); Sinks.push_back(ConsoleSink); Sinks.push_back(FileSink); -#if ZEN_USE_SENTRY - Sinks.push_back(SentrySink); -#endif #if ZEN_PLATFORM_WINDOWS if (zen::IsDebuggerPresent() && GlobalOptions.IsDebug) diff --git a/zenserver/zenserver.cpp b/zenserver/zenserver.cpp index 5b861f1bc..635fd04e0 100644 --- a/zenserver/zenserver.cpp +++ b/zenserver/zenserver.cpp @@ -80,6 +80,7 @@ ZEN_THIRD_PARTY_INCLUDES_END # define SENTRY_BUILD_STATIC 1 ZEN_THIRD_PARTY_INCLUDES_START # include <sentry.h> +# include <spdlog/sinks/base_sink.h> ZEN_THIRD_PARTY_INCLUDES_END // Sentry currently does not automatically add all required Windows @@ -121,6 +122,35 @@ namespace zen { using namespace std::literals; namespace utils { +#if ZEN_USE_SENTRY + class sentry_sink final : public spdlog::sinks::base_sink<spdlog::details::null_mutex> + { + public: + sentry_sink() {} + + protected: + 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}; + + void sink_it_(const spdlog::details::log_msg& msg) override + { + 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); + } + void flush_() override {} + }; +#endif + asio::error_code ResolveHostname(asio::io_context& Ctx, std::string_view Host, std::string_view DefaultPort, @@ -937,9 +967,15 @@ ZenEntryPoint::Run() // sentry_options_set_debug(SentryOptions, 1); SentryErrorCode = sentry_init(SentryOptions); + + auto SentrySink = spdlog::create<utils::sentry_sink>("sentry"); + zen::logging::SetErrorLog(std::move(SentrySink)); } - auto _ = zen::MakeGuard([] { sentry_close(); }); + auto _ = zen::MakeGuard([] { + zen::logging::SetErrorLog(std::shared_ptr<spdlog::logger>()); + sentry_close(); + }); #endif auto& ServerOptions = m_ServerOptions; |