diff options
| author | Stefan Boberg <[email protected]> | 2026-03-23 19:22:08 +0100 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2026-03-23 19:22:08 +0100 |
| commit | 440ef03df8d8bba4432126f36168c1f7631c18dc (patch) | |
| tree | 07d4bd4446a11589c9a842255bf37c25aaded74b /src/zenutil/include | |
| parent | Merge branch 'de/v5.7.25-hotpatch' (#880) (diff) | |
| download | zen-440ef03df8d8bba4432126f36168c1f7631c18dc.tar.xz zen-440ef03df8d8bba4432126f36168c1f7631c18dc.zip | |
Cross-platform process metrics support (#887)
- **Cross-platform `GetProcessMetrics`**: Implement Linux (`/proc/{pid}/stat`, `/proc/{pid}/statm`, `/proc/{pid}/status`) and macOS (`proc_pidinfo(PROC_PIDTASKINFO)`) support for CPU times and memory metrics. Fix Windows to populate the `MemoryBytes` field (was always 0). All platforms now set `MemoryBytes = WorkingSetSize`.
- **`ProcessMetricsTracker`**: Experimental utility class (`zenutil`) that periodically samples resource usage for a set of tracked child processes. Supports both a dedicated background thread and an ASIO steady_timer mode. Computes delta-based CPU usage percentage across samples, with batched sampling (8 processes per tick) to limit per-cycle overhead.
- **`ProcessHandle` documentation**: Add Doxygen comments to all public methods describing platform-specific behavior.
- **Cleanup**: Remove unused `ZEN_RUN_TESTS` macro (inlined at its single call site in `zenserver/main.cpp`), remove dead `#if 0` thread-shutdown workaround block.
- **Minor fixes**: Use `HttpClientAccessToken` constructor in hordeclient instead of setting private members directly. Log ASIO version at startup and include it in the server settings list.
Diffstat (limited to 'src/zenutil/include')
| -rw-r--r-- | src/zenutil/include/zenutil/processmetricstracker.h | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/src/zenutil/include/zenutil/processmetricstracker.h b/src/zenutil/include/zenutil/processmetricstracker.h new file mode 100644 index 000000000..fdeae2bfa --- /dev/null +++ b/src/zenutil/include/zenutil/processmetricstracker.h @@ -0,0 +1,105 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include <zencore/process.h> +#include <zencore/zencore.h> + +#include <memory> +#include <vector> + +namespace asio { +class io_context; +} + +namespace zen { + +/** Tracked process entry with latest metrics snapshot. + */ +struct TrackedProcessEntry +{ + int Pid = 0; + ProcessMetrics Metrics; + + // Derived CPU usage percentage (delta-based, requires two samples). + // -1.0 means not yet sampled. + float CpuUsagePercent = -1.0f; +}; + +/** Aggregate metrics across all tracked processes. + */ +struct AggregateProcessMetrics +{ + uint64_t TotalWorkingSetSize = 0; + uint64_t TotalPeakWorkingSetSize = 0; + uint64_t TotalUserTimeMs = 0; + uint64_t TotalKernelTimeMs = 0; + uint32_t ProcessCount = 0; +}; + +/** Background process metrics tracker. + * + * Maintains a set of child processes keyed by pid and periodically samples + * their resource usage (CPU times, memory) in a background thread or via + * an ASIO timer on an external io_context. + * + * The tracker does not take ownership of process handles. On Windows it + * duplicates the handle internally; on other platforms it uses the pid + * directly. + * + * Usage (dedicated thread): + * ProcessMetricsTracker Tracker; + * Tracker.Start(); + * Tracker.Add(ChildHandle); + * + * Usage (ASIO timer): + * ProcessMetricsTracker Tracker(IoContext); + * Tracker.Start(); + * Tracker.Add(ChildHandle); + */ +class ProcessMetricsTracker +{ +public: + /// Construct with a dedicated background thread for sampling. + explicit ProcessMetricsTracker(uint64_t SampleIntervalMs = 5000); + + /// Construct with an external io_context — uses an asio::steady_timer + /// instead of a dedicated thread. The caller must ensure the io_context + /// outlives this tracker and that its run loop is active. + ProcessMetricsTracker(asio::io_context& IoContext, uint64_t SampleIntervalMs = 5000); + + ~ProcessMetricsTracker(); + + ProcessMetricsTracker(const ProcessMetricsTracker&) = delete; + ProcessMetricsTracker& operator=(const ProcessMetricsTracker&) = delete; + + /// Start sampling. Spawns the background thread or enqueues the first timer. + void Start(); + + /// Stop sampling. Safe to call multiple times. + void Stop(); + + /// Add a process to track. Internally clones the handle (Windows) or + /// copies the pid (Linux/macOS). If the pid is already tracked, replaces it. + void Add(const ProcessHandle& Handle); + + /// Remove a tracked process by pid. + void Remove(int Pid); + + /// Remove all tracked processes. + void Clear(); + + /// Returns a snapshot of metrics for all tracked processes. + std::vector<TrackedProcessEntry> GetSnapshot() const; + + /// Returns aggregate metrics across all tracked processes. + AggregateProcessMetrics GetAggregate() const; + +private: + struct Impl; + std::unique_ptr<Impl> m_Impl; +}; + +void processmetricstracker_forcelink(); // internal + +} // namespace zen |