aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2023-04-25 14:50:29 +0200
committerGitHub <[email protected]>2023-04-25 14:50:29 +0200
commit0d0697cbe19ed2ef385408f72d754cea99c7bc9a (patch)
tree9d05fec6bf2356b56fa432e3e97946adacfc9466
parent0.2.5 (diff)
downloadzen-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.md5
-rw-r--r--xmake.lua1
-rw-r--r--zencore/include/zencore/logging.h35
-rw-r--r--zencore/logging.cpp14
-rw-r--r--zencore/testing.cpp2
-rw-r--r--zenserver/diag/logging.cpp51
-rw-r--r--zenserver/zenserver.cpp38
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`
diff --git a/xmake.lua b/xmake.lua
index cc9458bdd..db4ddb197 100644
--- a/xmake.lua
+++ b/xmake.lua
@@ -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;