From cecccf7b74a3384266e96074846c301c42a402bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnter=20Obiltschnig?= Date: Thu, 21 Nov 2024 08:50:49 +0100 Subject: [PATCH] enh(Foundation): add Poco::Process::timesMicroseconds() --- Foundation/include/Poco/Process.h | 10 ++++++++++ Foundation/include/Poco/Process_UNIX.h | 1 + Foundation/include/Poco/Process_VX.h | 1 + Foundation/include/Poco/Process_WIN32U.h | 1 + Foundation/src/Process_UNIX.cpp | 9 +++++++++ Foundation/src/Process_VX.cpp | 7 +++++++ Foundation/src/Process_WIN32U.cpp | 24 ++++++++++++++++++++++++ Prometheus/src/ProcessCollector.cpp | 10 +++++----- 8 files changed, 58 insertions(+), 5 deletions(-) diff --git a/Foundation/include/Poco/Process.h b/Foundation/include/Poco/Process.h index 717040444..bb650c644 100644 --- a/Foundation/include/Poco/Process.h +++ b/Foundation/include/Poco/Process.h @@ -94,6 +94,10 @@ public: /// Returns the number of seconds spent by the /// current process in user and kernel mode. + static void timesMicroseconds(Poco::Int64& userTime, Poco::Int64& kernelTime); + /// Returns the number of microseconds spent by the + /// current process in user and kernel mode. + static ProcessHandle launch(const std::string& command, const Args& args, int options = 0); /// Creates a new process for the given command and returns /// a ProcessHandle of the new process. The given arguments are @@ -268,6 +272,12 @@ inline void Process::times(long& userTime, long& kernelTime) } +inline void Process::timesMicroseconds(Poco::Int64& userTime, Poco::Int64& kernelTime) +{ + ProcessImpl::timesMicrosecondsImpl(userTime, kernelTime); +} + + } // namespace Poco diff --git a/Foundation/include/Poco/Process_UNIX.h b/Foundation/include/Poco/Process_UNIX.h index 101243585..26666cb4b 100644 --- a/Foundation/include/Poco/Process_UNIX.h +++ b/Foundation/include/Poco/Process_UNIX.h @@ -56,6 +56,7 @@ public: static PIDImpl idImpl(); static void timesImpl(long& userTime, long& kernelTime); + static void timesMicrosecondsImpl(Poco::Int64& userTime, Poco::Int64& kernelTime); static ProcessHandleImpl* launchImpl( const std::string& command, const ArgsImpl& args, diff --git a/Foundation/include/Poco/Process_VX.h b/Foundation/include/Poco/Process_VX.h index 189828e3a..0fbda8c55 100644 --- a/Foundation/include/Poco/Process_VX.h +++ b/Foundation/include/Poco/Process_VX.h @@ -57,6 +57,7 @@ public: static PIDImpl idImpl(); static void timesImpl(long& userTime, long& kernelTime); + static void timesMicrosecondsImpl(Poco::Int64& userTime, Poco::Int64& kernelTime); static ProcessHandleImpl* launchImpl( const std::string& command, const ArgsImpl& args, diff --git a/Foundation/include/Poco/Process_WIN32U.h b/Foundation/include/Poco/Process_WIN32U.h index 6e789e984..d44b19c6b 100644 --- a/Foundation/include/Poco/Process_WIN32U.h +++ b/Foundation/include/Poco/Process_WIN32U.h @@ -61,6 +61,7 @@ public: static PIDImpl idImpl(); static void timesImpl(long& userTime, long& kernelTime); + static void timesMicrosecondsImpl(Poco::Int64& userTime, Poco::Int64& kernelTime); static ProcessHandleImpl* launchImpl( const std::string& command, const ArgsImpl& args, diff --git a/Foundation/src/Process_UNIX.cpp b/Foundation/src/Process_UNIX.cpp index f48448d26..68c491e7c 100644 --- a/Foundation/src/Process_UNIX.cpp +++ b/Foundation/src/Process_UNIX.cpp @@ -113,6 +113,15 @@ void ProcessImpl::timesImpl(long& userTime, long& kernelTime) } +void ProcessImpl::timesMicrosecondsImpl(Poco::Int64& userTime, Poco::Int64& kernelTime) +{ + struct rusage usage; + getrusage(RUSAGE_SELF, &usage); + userTime = static_cast(usage.ru_utime.tv_sec)*1000000 + usage.ru_utime.tv_usec; + kernelTime = static_cast(usage.ru_stime.tv_sec)*1000000 + usage.ru_stime.tv_usec; +} + + ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const ArgsImpl& args, const std::string& initialDirectory, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe, const EnvImpl& env, int options) { #if defined(__QNX__) diff --git a/Foundation/src/Process_VX.cpp b/Foundation/src/Process_VX.cpp index 7bb4dca94..3afa96189 100644 --- a/Foundation/src/Process_VX.cpp +++ b/Foundation/src/Process_VX.cpp @@ -67,6 +67,13 @@ void ProcessImpl::timesImpl(long& userTime, long& kernelTime) } +void ProcessImpl::timesMicrosecondsImpl(Poco::Int64& userTime, Poco::Int64& kernelTime) +{ + userTime = 0; + kernelTime = 0; +} + + ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const ArgsImpl& args, const std::string& initialDirectory,Pipe* inPipe, Pipe* outPipe, Pipe* errPipe, const EnvImpl& env) { throw Poco::NotImplementedException("Process::launch()"); diff --git a/Foundation/src/Process_WIN32U.cpp b/Foundation/src/Process_WIN32U.cpp index 57f1a8072..269fe1b3b 100644 --- a/Foundation/src/Process_WIN32U.cpp +++ b/Foundation/src/Process_WIN32U.cpp @@ -161,6 +161,30 @@ void ProcessImpl::timesImpl(long& userTime, long& kernelTime) } +void ProcessImpl::timesMicrosecondsImpl(Poco::Int64& userTime, Poco::Int64& kernelTime) +{ + FILETIME ftCreation; + FILETIME ftExit; + FILETIME ftKernel; + FILETIME ftUser; + + if (GetProcessTimes(GetCurrentProcess(), &ftCreation, &ftExit, &ftKernel, &ftUser) != 0) + { + ULARGE_INTEGER time; + time.LowPart = ftKernel.dwLowDateTime; + time.HighPart = ftKernel.dwHighDateTime; + kernelTime = Poco::Int64(time.QuadPart/10); + time.LowPart = ftUser.dwLowDateTime; + time.HighPart = ftUser.dwHighDateTime; + userTime = Poco::Int64(time.QuadPart/10); + } + else + { + userTime = kernelTime = -1; + } +} + + bool ProcessImpl::mustEscapeArg(const std::string& arg) { bool result = false; diff --git a/Prometheus/src/ProcessCollector.cpp b/Prometheus/src/ProcessCollector.cpp index 5c45a11db..8694abdc1 100644 --- a/Prometheus/src/ProcessCollector.cpp +++ b/Prometheus/src/ProcessCollector.cpp @@ -56,16 +56,16 @@ void ProcessCollector::exportTo(Exporter& exporter) const void ProcessCollector::buildMetrics() { - _metrics.push_back(std::make_unique( + _metrics.push_back(std::make_unique( name() + "_cpu_seconds_total"s, "Total user and system CPU time spent in seconds"s, nullptr, []() { - long user; - long system; - Poco::Process::times(user, system); - return static_cast(user) + static_cast(system); + Poco::Int64 user; + Poco::Int64 system; + Poco::Process::timesMicroseconds(user, system); + return static_cast(user/1000 + system/1000)/1000.0; })); #ifdef POCO_OS_FAMILY_UNIX