diff options
| author | Stefan Boberg <[email protected]> | 2026-03-21 21:43:22 +0100 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2026-03-21 21:43:22 +0100 |
| commit | 14ca5b35d0fc477ba30f10b80f937b523fd7e930 (patch) | |
| tree | 8aab2acfec8be1af4bf0dffdb4badc3b64bf8385 /src/zenserver | |
| parent | fix null stats provider crash when build store is not configured (#875) (diff) | |
| download | zen-14ca5b35d0fc477ba30f10b80f937b523fd7e930.tar.xz zen-14ca5b35d0fc477ba30f10b80f937b523fd7e930.zip | |
Interprocess pipe support (for stdout/stderr capture) (#866)
- **RAII pipe handles for child process stdout/stderr capture**: `StdoutPipeHandles` is now a proper RAII type with automatic cleanup, move semantics, and partial close support. This makes it safe to use pipes for capturing child process output without risking handle/fd leaks.
- **Optional separate stderr pipe**: `CreateProcOptions` now accepts a `StderrPipe` field so callers can capture stdout and stderr independently. When null (default), stderr shares the stdout pipe as before.
- **LogStreamListener with pluggable handler**: The TCP log stream listener accepts connections from remote processes and delivers parsed log lines through a `LogStreamHandler` interface, set dynamically via `SetHandler()`. This allows any client to receive log messages without depending on a specific console implementation.
- **TcpLogStreamSink for zen::logging**: A logging sink that forwards log messages to a `LogStreamListener` over TCP, using the native `zen::logging::Sink` infrastructure with proper thread-safe synchronization.
- **Reliable child process exit codes on Linux**: `waitpid` result handling is fixed so `ProcessHandle::GetExitCode()` returns the real exit code. `ProcessHandle::Reset()` reaps zombies directly, replacing the global `IgnoreChildSignals()` which prevented exit code collection entirely. Also fixes a TOCTOU race in `ProcessHandle::Wait()` on Linux/Mac.
- **Pipe capture test suite**: Tests covering stdout/stderr capture via pipes (both shared and separate modes), RAII cleanup, move semantics, and exit code propagation using `zentest-appstub` as the child process.
- **Service command integration tests**: Shell-based integration tests for `zen service` covering the full lifecycle (install, status, start, stop, uninstall) on all three platforms — Linux (systemd), macOS (launchd), and Windows (SCM via PowerShell).
- **Test script reorganization**: Platform-specific test scripts moved from `scripts/test_scripts/` into `scripts/test_linux/`, `test_mac/`, and `test_windows/`.
Diffstat (limited to 'src/zenserver')
| -rw-r--r-- | src/zenserver/diag/logging.cpp | 23 | ||||
| -rw-r--r-- | src/zenserver/main.cpp | 4 |
2 files changed, 23 insertions, 4 deletions
diff --git a/src/zenserver/diag/logging.cpp b/src/zenserver/diag/logging.cpp index 178c3d3b5..38b15480a 100644 --- a/src/zenserver/diag/logging.cpp +++ b/src/zenserver/diag/logging.cpp @@ -13,6 +13,7 @@ #include <zencore/string.h> #include <zenutil/logging.h> #include <zenutil/logging/rotatingfilesink.h> +#include <zenutil/splitconsole/tcplogstreamsink.h> #include "otlphttp.h" @@ -28,6 +29,7 @@ InitializeServerLogging(const ZenServerConfig& InOptions, bool WithCacheService) .IsTest = InOptions.IsTest, .NoConsoleOutput = InOptions.LoggingConfig.NoConsoleOutput, .QuietConsole = InOptions.LoggingConfig.QuietConsole, + .ForceColor = InOptions.LoggingConfig.ForceColor, .AbsLogFile = InOptions.LoggingConfig.AbsLogFile, .LogId = InOptions.LoggingConfig.LogId}; @@ -81,6 +83,27 @@ InitializeServerLogging(const ZenServerConfig& InOptions, bool WithCacheService) } #endif + if (!InOptions.LoggingConfig.LogStreamEndpoint.empty()) + { + std::string Endpoint = InOptions.LoggingConfig.LogStreamEndpoint; + std::string Host = "localhost"; + uint16_t Port = 0; + + auto ColonPos = Endpoint.rfind(':'); + if (ColonPos != std::string::npos) + { + Host = Endpoint.substr(0, ColonPos); + std::optional<uint16_t> P = ParseInt<uint16_t>(std::string_view(Endpoint).substr(ColonPos + 1)); + Port = P.value_or(0); + } + + if (Port > 0) + { + logging::SinkPtr StreamSink(new TcpLogStreamSink(Host, Port, "zenserver")); + zen::logging::Default()->AddSink(std::move(StreamSink)); + } + } + FinishInitializeLogging(LogOptions); const zen::Oid ServerSessionId = zen::GetSessionId(); diff --git a/src/zenserver/main.cpp b/src/zenserver/main.cpp index bf328c499..dff162b1c 100644 --- a/src/zenserver/main.cpp +++ b/src/zenserver/main.cpp @@ -123,10 +123,6 @@ AppMain(int argc, char* argv[]) signal(SIGINT, utils::SignalCallbackHandler); signal(SIGTERM, utils::SignalCallbackHandler); -#if ZEN_PLATFORM_LINUX - IgnoreChildSignals(); -#endif - try { typename Main::Config ServerOptions; |