From 3d59b5d7036c35fe484d052ff32dbdc9d0a75cf7 Mon Sep 17 00:00:00 2001 From: Dan Engelbrecht Date: Mon, 13 Apr 2026 19:17:09 +0200 Subject: fix utf characters in source code (#953) --- src/zenserver/zenserver.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/zenserver/zenserver.cpp') diff --git a/src/zenserver/zenserver.cpp b/src/zenserver/zenserver.cpp index 087b40d6a..e9e7a2c33 100644 --- a/src/zenserver/zenserver.cpp +++ b/src/zenserver/zenserver.cpp @@ -699,7 +699,7 @@ ZenServerMain::Run() // The entry's process failed to pick up our sponsor request after // multiple attempts. Before reclaiming the entry, verify that the // PID does not still belong to a zenserver process. If it does, the - // server is alive but unresponsive – fall back to the original error + // server is alive but unresponsive - fall back to the original error // path. If the PID is gone or belongs to a different executable the // entry is genuinely stale and safe to reclaim. const int StalePid = Entry->Pid.load(); @@ -717,7 +717,7 @@ ZenServerMain::Run() } ZEN_CONSOLE_WARN( "Failed to add sponsor to process on port {} (pid {}); " - "pid belongs to '{}' – assuming stale entry and reclaiming", + "pid belongs to '{}' - assuming stale entry and reclaiming", m_ServerOptions.BasePort, StalePid, ExeEc ? "" : PidExePath.filename().string()); -- cgit v1.2.3 From 5a48e941b6f7e41ff6f0e86e6999f8b0a15d5c5b Mon Sep 17 00:00:00 2001 From: Dan Engelbrecht Date: Wed, 15 Apr 2026 19:12:44 +0200 Subject: add sessions to hub and proxy (#960) * move session service to zenserver base class and make it available in all zenserver modes * fix deadlock in sessionsclient shutdown --- src/zenserver/zenserver.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) (limited to 'src/zenserver/zenserver.cpp') diff --git a/src/zenserver/zenserver.cpp b/src/zenserver/zenserver.cpp index e9e7a2c33..e68e46bd6 100644 --- a/src/zenserver/zenserver.cpp +++ b/src/zenserver/zenserver.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -28,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -64,6 +66,9 @@ ZEN_THIRD_PARTY_INCLUDES_END #include "config/config.h" #include "diag/logging.h" +#include "sessions/httpsessions.h" +#include "sessions/inprocsessionlogsink.h" +#include "sessions/sessions.h" #include @@ -225,6 +230,8 @@ ZenServerBase::Initialize(const ZenServerConfig& ServerOptions, ZenServerState:: LogSettingsSummary(ServerOptions); + InitializeSessions(); + return EffectiveBasePort; } @@ -233,6 +240,11 @@ ZenServerBase::Finalize() { m_StatsService.RegisterHandler("http", *m_Http); + if (m_HttpSessionsService) + { + m_Http->RegisterService(*m_HttpSessionsService); + } + m_Http->SetDefaultRedirect("/dashboard/"); // Register health service last so if we return "OK" for health it means all services have been properly initialized @@ -243,10 +255,48 @@ ZenServerBase::Finalize() void ZenServerBase::ShutdownServices() { - m_StatsService.UnregisterHandler("http", *m_Http); + if (m_InProcSessionLogSink) + { + GetDefaultBroadcastSink()->RemoveSink(m_InProcSessionLogSink); + m_InProcSessionLogSink = {}; + } + + if (m_SessionsService) + { + m_SessionsService->RemoveSession(GetSessionId()); + } + + m_HttpSessionsService.reset(); + m_SessionsService.reset(); + + if (m_Http) + { + m_StatsService.UnregisterHandler("http", *m_Http); + } m_StatsService.Shutdown(); } +void +ZenServerBase::InitializeSessions() +{ + m_SessionsService = std::make_unique(); + m_HttpSessionsService = std::make_unique(m_StatusService, m_StatsService, *m_SessionsService, m_IoContext); + m_HttpSessionsService->SetSelfSessionId(GetSessionId()); + + m_InProcSessionLogSink = logging::SinkPtr(new InProcSessionLogSink(*m_SessionsService)); + m_InProcSessionLogSink->SetLevel(logging::Info); + GetDefaultBroadcastSink()->AddSink(m_InProcSessionLogSink); +} + +void +ZenServerBase::StartSelfSession(std::string_view AppName) +{ + if (m_SessionsService) + { + m_SessionsService->RegisterSession(GetSessionId(), std::string(AppName), GetServerMode(), Oid::Zero, {}); + } +} + void ZenServerBase::GetBuildOptions(StringBuilderBase& OutOptions, char Separator) const { -- cgit v1.2.3 From 28a61b12d302e9e0d37d52bf1aa5d19069f3411b Mon Sep 17 00:00:00 2001 From: Dan Engelbrecht Date: Mon, 20 Apr 2026 15:53:22 +0200 Subject: zen history command (#987) - Feature: Per-user invocation history for `zen` and `zenserver`; each startup appends a record to a JSONL file capped at the most recent 100 entries. Location: `%LOCALAPPDATA%\Epic\Zen\History\invocations.jsonl` on Windows, `~/.zen/History/invocations.jsonl` on POSIX - `zen history` opens an interactive picker; selecting a zen row re-runs it inline and forwards the exit code, selecting a zenserver row spawns it detached - `zen history --list` (`-l`) prints the table to stdout instead of showing the picker - `zen history --filter zen|zenserver` restricts the listing to one executable - `zen history --print` prints the reconstructed command line of the selected row instead of launching it - `--enable-execution-history` global option on both binaries (default `true`) to opt out per invocation - The history file is attached to Sentry crash reports (alongside the existing zenserver log) --- src/zenserver/zenserver.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'src/zenserver/zenserver.cpp') diff --git a/src/zenserver/zenserver.cpp b/src/zenserver/zenserver.cpp index e68e46bd6..59bb79973 100644 --- a/src/zenserver/zenserver.cpp +++ b/src/zenserver/zenserver.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -671,11 +672,20 @@ ZenServerMain::Run() { ZEN_OTEL_SPAN("SentryInit"); - std::string SentryDatabasePath = (m_ServerOptions.DataDir / ".sentry-native").string(); - std::string SentryAttachmentPath = m_ServerOptions.LoggingConfig.AbsLogFile.string(); + std::string SentryDatabasePath = (m_ServerOptions.DataDir / ".sentry-native").string(); + + std::vector AttachmentPaths; + if (!m_ServerOptions.LoggingConfig.AbsLogFile.empty()) + { + AttachmentPaths.push_back(m_ServerOptions.LoggingConfig.AbsLogFile); + } + if (std::filesystem::path HistoryPath = GetInvocationHistoryPath(); !HistoryPath.empty()) + { + AttachmentPaths.push_back(std::move(HistoryPath)); + } Sentry.Initialize({.DatabasePath = SentryDatabasePath, - .AttachmentsPath = SentryAttachmentPath, + .AttachmentPaths = std::move(AttachmentPaths), .Dsn = m_ServerOptions.SentryConfig.Dsn, .Environment = m_ServerOptions.SentryConfig.Environment, .AllowPII = m_ServerOptions.SentryConfig.AllowPII, -- cgit v1.2.3 From 6aa4efa21a09990998a4054e805e595ef38ae785 Mon Sep 17 00:00:00 2001 From: Dan Engelbrecht Date: Mon, 20 Apr 2026 22:13:10 +0200 Subject: hide secrets from log and sentry (#989) * scrub sensitive command line options from log and sentry --- src/zenserver/zenserver.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/zenserver/zenserver.cpp') diff --git a/src/zenserver/zenserver.cpp b/src/zenserver/zenserver.cpp index 59bb79973..6bf22eef8 100644 --- a/src/zenserver/zenserver.cpp +++ b/src/zenserver/zenserver.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -665,6 +666,9 @@ ZenServerMain::Run() zen::SetCurrentThreadName("main"); #endif + std::string ScrubbedCmdLine = m_ServerOptions.CommandLine; + ScrubSensitiveValues(ScrubbedCmdLine); + #if ZEN_USE_SENTRY SentryIntegration Sentry; @@ -690,7 +694,7 @@ ZenServerMain::Run() .Environment = m_ServerOptions.SentryConfig.Environment, .AllowPII = m_ServerOptions.SentryConfig.AllowPII, .Debug = m_ServerOptions.SentryConfig.Debug}, - m_ServerOptions.CommandLine); + ScrubbedCmdLine); } #endif @@ -822,7 +826,7 @@ ZenServerMain::Run() InitializeLogging(); - ZEN_INFO("Command line: {}", m_ServerOptions.CommandLine); + ZEN_INFO("Command line: {}", ScrubbedCmdLine); #if ZEN_USE_SENTRY Sentry.LogStartupInformation(); -- cgit v1.2.3