aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2024-08-14 09:23:19 +0200
committerGitHub Enterprise <[email protected]>2024-08-14 09:23:19 +0200
commit501d5e3b0be37ebceda96240af1e4d8df927d68f (patch)
tree1279228466433e992ec1dd2635c317d1ce78dcc3 /src
parentdon't try to memcache the empty buffer if invalid format (#110) (diff)
downloadzen-501d5e3b0be37ebceda96240af1e4d8df927d68f.tar.xz
zen-501d5e3b0be37ebceda96240af1e4d8df927d68f.zip
improve logging on main failure (#111)
* add support for indenting callstack output * Explicitly catch option-parse error and reduce log spam on bad parameters * add command line to sentry error reports * log command line at startup
Diffstat (limited to 'src')
-rw-r--r--src/zencore/callstack.cpp10
-rw-r--r--src/zencore/include/zencore/callstack.h4
-rw-r--r--src/zencore/zencore.cpp4
-rw-r--r--src/zenserver/config.cpp2
-rw-r--r--src/zenserver/config.h1
-rw-r--r--src/zenserver/main.cpp12
-rw-r--r--src/zenserver/sentryintegration.cpp36
-rw-r--r--src/zenserver/sentryintegration.h4
8 files changed, 39 insertions, 34 deletions
diff --git a/src/zencore/callstack.cpp b/src/zencore/callstack.cpp
index 905ab3d9e..d16605fb9 100644
--- a/src/zencore/callstack.cpp
+++ b/src/zencore/callstack.cpp
@@ -172,7 +172,7 @@ GetFrameSymbols(uint32_t FrameCount, void** Frames)
}
void
-FormatCallstack(const CallstackFrames* Callstack, StringBuilderBase& SB)
+FormatCallstack(const CallstackFrames* Callstack, StringBuilderBase& SB, std::string_view Prefix)
{
bool First = true;
for (const std::string& Symbol : GetFrameSymbols(Callstack))
@@ -185,15 +185,19 @@ FormatCallstack(const CallstackFrames* Callstack, StringBuilderBase& SB)
{
First = false;
}
+ if (!Prefix.empty())
+ {
+ SB.Append(Prefix);
+ }
SB.Append(Symbol);
}
}
std::string
-CallstackToString(const CallstackFrames* Callstack)
+CallstackToString(const CallstackFrames* Callstack, std::string_view Prefix)
{
StringBuilder<2048> SB;
- FormatCallstack(Callstack, SB);
+ FormatCallstack(Callstack, SB, Prefix);
return SB.ToString();
}
diff --git a/src/zencore/include/zencore/callstack.h b/src/zencore/include/zencore/callstack.h
index 02ba8b3c3..ef4ba0e91 100644
--- a/src/zencore/include/zencore/callstack.h
+++ b/src/zencore/include/zencore/callstack.h
@@ -29,8 +29,8 @@ GetFrameSymbols(const CallstackFrames* Callstack)
return GetFrameSymbols(Callstack ? Callstack->FrameCount : 0, Callstack ? Callstack->Frames : nullptr);
}
-void FormatCallstack(const CallstackFrames* Callstack, StringBuilderBase& SB);
-std::string CallstackToString(const CallstackFrames* Callstack);
+void FormatCallstack(const CallstackFrames* Callstack, StringBuilderBase& SB, std::string_view Prefix);
+std::string CallstackToString(const CallstackFrames* Callstack, std::string_view Prefix = {});
void callstack_forcelink(); // internal
diff --git a/src/zencore/zencore.cpp b/src/zencore/zencore.cpp
index 9c48b355b..6a963110b 100644
--- a/src/zencore/zencore.cpp
+++ b/src/zencore/zencore.cpp
@@ -82,7 +82,7 @@ AssertException::FullDescription() const noexcept
{
if (_Callstack)
{
- return fmt::format("'{}'\n{}", what(), CallstackToString(_Callstack));
+ return fmt::format("'{}'\n{}", what(), CallstackToString(_Callstack, " "));
}
return what();
}
@@ -131,7 +131,7 @@ AssertImpl::OnAssert(const char* Filename, int LineNumber, const char* FunctionN
fmt::basic_memory_buffer<char, 2048> Message;
auto Appender = fmt::appender(Message);
- fmt::format_to(Appender, "{}({}): ZEN_ASSERT({})\n{}", Filename, LineNumber, Msg, CallstackToString(Callstack));
+ fmt::format_to(Appender, "{}({}): ZEN_ASSERT({})\n{}", Filename, LineNumber, Msg, CallstackToString(Callstack, " "));
Message.push_back('\0');
// We use direct ZEN_LOG here instead of ZEN_ERROR as we don't care about *this* code location in the log
diff --git a/src/zenserver/config.cpp b/src/zenserver/config.cpp
index 55c90cbe1..867089ded 100644
--- a/src/zenserver/config.cpp
+++ b/src/zenserver/config.cpp
@@ -565,6 +565,8 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions)
}
#endif
+ ServerOptions.CommandLine = fmt::format("{}", fmt::join(std::span<const char*>((const char**)argv, size_t(argc)), " "));
+
// Note to those adding future options; std::filesystem::path-type options
// must be read into a std::string first. As of cxxopts-3.0.0 it uses a >>
// stream operator to convert argv value into the options type. std::fs::path
diff --git a/src/zenserver/config.h b/src/zenserver/config.h
index 41e05c7ea..46fdd6fdf 100644
--- a/src/zenserver/config.h
+++ b/src/zenserver/config.h
@@ -165,6 +165,7 @@ struct ZenServerOptions
std::string TraceHost; // Host name or IP address to send trace data to
std::string TraceFile; // Path of a file to write a trace
#endif
+ std::string CommandLine;
};
void ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions);
diff --git a/src/zenserver/main.cpp b/src/zenserver/main.cpp
index 023abc8a3..c27d4eb04 100644
--- a/src/zenserver/main.cpp
+++ b/src/zenserver/main.cpp
@@ -5,6 +5,7 @@
#include <zencore/compactbinarybuilder.h>
#include <zencore/compactbinaryvalidation.h>
#include <zencore/config.h>
+#include <zencore/except.h>
#include <zencore/filesystem.h>
#include <zencore/fmtutils.h>
#include <zencore/logging.h>
@@ -92,10 +93,9 @@ ZenEntryPoint::Run()
std::string SentryDatabasePath = (m_ServerOptions.DataDir / ".sentry-native").string();
std::string SentryAttachmentPath = m_ServerOptions.AbsLogFile.string();
- Sentry.Initialize(SentryDatabasePath, SentryAttachmentPath, m_ServerOptions.SentryAllowPII);
+ Sentry.Initialize(SentryDatabasePath, SentryAttachmentPath, m_ServerOptions.SentryAllowPII, m_ServerOptions.CommandLine);
}
#endif
-
try
{
// Mutual exclusion and synchronization
@@ -179,6 +179,8 @@ ZenEntryPoint::Run()
InitializeServerLogging(m_ServerOptions);
+ ZEN_INFO("Command line: {}", m_ServerOptions.CommandLine);
+
#if ZEN_USE_SENTRY
Sentry.LogStartupInformation();
#endif
@@ -437,6 +439,12 @@ main(int argc, char* argv[])
return App.Run();
#endif
}
+ catch (const OptionParseException& ParseEx)
+ {
+ // The parsing error already outputs all the details so no need to output the command line here
+ fprintf(stderr, "ERROR: %s\n", ParseEx.what());
+ return 1;
+ }
catch (const AssertException& AssertEx)
{
fprintf(stderr, "ERROR: Caught assert exception in main: '%s'", AssertEx.FullDescription().c_str());
diff --git a/src/zenserver/sentryintegration.cpp b/src/zenserver/sentryintegration.cpp
index 2f68a269b..5d2b851d1 100644
--- a/src/zenserver/sentryintegration.cpp
+++ b/src/zenserver/sentryintegration.cpp
@@ -190,7 +190,10 @@ SentryIntegration::~SentryIntegration()
}
void
-SentryIntegration::Initialize(std::string SentryDatabasePath, std::string SentryAttachmentPath, bool AllowPII)
+SentryIntegration::Initialize(std::string SentryDatabasePath,
+ std::string SentryAttachmentsPath,
+ bool AllowPII,
+ const std::string& CommandLine)
{
m_AllowPII = AllowPII;
@@ -202,11 +205,11 @@ SentryIntegration::Initialize(std::string SentryDatabasePath, std::string Sentry
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 (SentryAttachmentPath.starts_with("\\\\?\\"))
+ if (SentryAttachmentsPath.starts_with("\\\\?\\"))
{
- SentryAttachmentPath = SentryAttachmentPath.substr(4);
+ SentryAttachmentsPath = SentryAttachmentsPath.substr(4);
}
- sentry_options_add_attachment(SentryOptions, SentryAttachmentPath.c_str());
+ sentry_options_add_attachment(SentryOptions, SentryAttachmentsPath.c_str());
sentry_options_set_release(SentryOptions, ZEN_CFG_VERSION);
// sentry_options_set_debug(SentryOptions, 1);
@@ -215,6 +218,8 @@ SentryIntegration::Initialize(std::string SentryDatabasePath, std::string Sentry
if (m_SentryErrorCode == 0)
{
+ sentry_value_t SentryUserObject = sentry_value_new_object();
+
if (m_AllowPII)
{
# if ZEN_PLATFORM_WINDOWS
@@ -259,14 +264,15 @@ SentryIntegration::Initialize(std::string SentryDatabasePath, std::string Sentry
m_SentryHostName = "unknown";
}
# endif
- m_SentryId = fmt::format("{}@{}", m_SentryUserName, m_SentryHostName);
- sentry_value_t SentryUserObject = sentry_value_new_object();
+ 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_set_user(SentryUserObject);
}
+ sentry_value_set_by_key(SentryUserObject, "cmd", sentry_value_new_string(CommandLine.c_str()));
+ sentry_set_user(SentryUserObject);
+
m_SentryLogger = spdlog::create<sentry::sentry_sink>("sentry");
logging::SetErrorLog("sentry");
@@ -279,22 +285,6 @@ SentryIntegration::Initialize(std::string SentryDatabasePath, std::string Sentry
void
SentryIntegration::LogStartupInformation()
{
-# 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);
- }
- ZEN_INFO("Username: '{}'", m_SentryUserName);
-
- char HostNameBuffer[1023 + 1];
- int err = gethostname(HostNameBuffer, sizeof(HostNameBuffer));
- if (err == 0)
- {
- ZEN_INFO("Hostname: '{}'", HostNameBuffer);
- }
-# endif
if (m_IsInitialized)
{
if (m_SentryErrorCode == 0)
diff --git a/src/zenserver/sentryintegration.h b/src/zenserver/sentryintegration.h
index dd8b87ab7..29f526714 100644
--- a/src/zenserver/sentryintegration.h
+++ b/src/zenserver/sentryintegration.h
@@ -36,8 +36,8 @@ public:
SentryIntegration();
~SentryIntegration();
- void Initialize(std::string SentryDatabasePath, std::string SentryAttachmentsPath, bool AllowPII);
- void LogStartupInformation();
+ void Initialize(std::string SentryDatabasePath, std::string SentryAttachmentsPath, bool AllowPII, const std::string& CommandLine);
+ void LogStartupInformation();
static void ClearCaches();
private: