From e6eebd495996c1b71840e8293fc58b6a5f9cc4c7 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Mon, 22 Jul 2024 15:03:00 +0800 Subject: [PATCH 1/2] default port --- include/cinatra/coro_http_client.hpp | 21 +++++++++++---------- include/cinatra/uri.hpp | 4 ++-- lang/coro_http_client_introduction.md | 2 +- tests/test_cinatra.cpp | 2 +- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/include/cinatra/coro_http_client.hpp b/include/cinatra/coro_http_client.hpp index 063ccb68..239e1217 100644 --- a/include/cinatra/coro_http_client.hpp +++ b/include/cinatra/coro_http_client.hpp @@ -1546,20 +1546,21 @@ class coro_http_client : public std::enable_shared_from_this { if (!proxy_host_.empty() && !proxy_port_.empty()) { if (!proxy_request_uri_.empty()) proxy_request_uri_.clear(); - if (u.get_port() == "http") { - proxy_request_uri_ += "http://" + u.get_host() + ":"; - proxy_request_uri_ += "80"; + if (u.get_port() == "80") { + proxy_request_uri_.append("http://").append(u.get_host()).append(":80"); } - else if (u.get_port() == "https") { - proxy_request_uri_ += "https://" + u.get_host() + ":"; - proxy_request_uri_ += "443"; + else if (u.get_port() == "443") { + proxy_request_uri_.append("https://") + .append(u.get_host()) + .append(":443"); } else { // all be http - proxy_request_uri_ += "http://" + u.get_host() + ":"; - proxy_request_uri_ += u.get_port(); + proxy_request_uri_.append("http://") + .append(u.get_host()) + .append(u.get_port()); } - proxy_request_uri_ += u.get_path(); + proxy_request_uri_.append(u.get_path()); u.path = std::string_view(proxy_request_uri_); } } @@ -2424,7 +2425,7 @@ class coro_http_client : public std::enable_shared_from_this { bool enable_follow_redirect_ = false; bool enable_timeout_ = false; std::chrono::steady_clock::duration conn_timeout_duration_ = - std::chrono::seconds(30); + std::chrono::seconds(8); std::chrono::steady_clock::duration req_timeout_duration_ = std::chrono::seconds(60); bool enable_tcp_no_delay_ = true; diff --git a/include/cinatra/uri.hpp b/include/cinatra/uri.hpp index 4c1aedaa..089ce4b3 100644 --- a/include/cinatra/uri.hpp +++ b/include/cinatra/uri.hpp @@ -232,7 +232,7 @@ class uri_t { std::string port_str; if (is_ssl) { if (port.empty()) { - port_str = "https"; + port_str = "443"; } else { port_str = std::string(port); @@ -240,7 +240,7 @@ class uri_t { } else { if (port.empty()) { - port_str = "http"; + port_str = "80"; } else { port_str = std::string(port); diff --git a/lang/coro_http_client_introduction.md b/lang/coro_http_client_introduction.md index 9bcdebc6..8e74f3b2 100644 --- a/lang/coro_http_client_introduction.md +++ b/lang/coro_http_client_introduction.md @@ -252,7 +252,7 @@ async_simple::coro::Lazy test_async_client() { // 通过重连复用client1 r = async_simple::coro::syncAwait(client1.connect("http://cn.bing.com")); CHECK(client1.get_host() == "cn.bing.com"); - CHECK(client1.get_port() == "http"); + CHECK(client1.get_port() == "80"); CHECK(r.status == 200); ``` diff --git a/tests/test_cinatra.cpp b/tests/test_cinatra.cpp index 08c3de7c..d066acfa 100644 --- a/tests/test_cinatra.cpp +++ b/tests/test_cinatra.cpp @@ -753,7 +753,7 @@ TEST_CASE("test coro_http_client async_http_connect") { r = async_simple::coro::syncAwait(client1.connect("http://cn.bing.com")); CHECK(client1.get_host() == "cn.bing.com"); - CHECK(client1.get_port() == "http"); + CHECK(client1.get_port() == "80"); CHECK(r.status >= 200); r = async_simple::coro::syncAwait(client1.connect("http://www.baidu.com")); From 867cfcd65fe6ce74c86b74f9b1e7841870177dc5 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Thu, 17 Oct 2024 11:29:05 +0800 Subject: [PATCH 2/2] metric for windows --- include/cinatra/ylt/metric/system_metric.hpp | 252 ++++++++++++++++++- 1 file changed, 245 insertions(+), 7 deletions(-) diff --git a/include/cinatra/ylt/metric/system_metric.hpp b/include/cinatra/ylt/metric/system_metric.hpp index 97e1c26d..50c36f31 100644 --- a/include/cinatra/ylt/metric/system_metric.hpp +++ b/include/cinatra/ylt/metric/system_metric.hpp @@ -2,6 +2,16 @@ #if defined(__GNUC__) #include #include +#endif + +#if defined(WIN32) +#include +#include +#include + +// Link with Psapi.lib +#pragma comment(lib, "Psapi.lib") +#endif #include #include @@ -73,6 +83,175 @@ inline int read_command_output_through_popen(std::ostream& os, } #endif +#if defined(WIN32) +typedef struct timeval { + long tv_sec; + long tv_usec; +} timeval; + +inline int gettimeofday(struct timeval* tp, struct timezone* tzp) { + // Note: some broken versions only have 8 trailing zero's, the correct epoch + // has 9 trailing zero's This magic number is the number of 100 nanosecond + // intervals since January 1, 1601 (UTC) until 00:00:00 January 1, 1970 + static const uint64_t epoch = ((uint64_t)116444736000000000ULL); + + SYSTEMTIME system_time; + FILETIME file_time; + uint64_t time; + + GetSystemTime(&system_time); + SystemTimeToFileTime(&system_time, &file_time); + time = ((uint64_t)file_time.dwLowDateTime); + time += ((uint64_t)file_time.dwHighDateTime) << 32; + + tp->tv_sec = (long)((time - epoch) / 10000000L); + tp->tv_usec = (long)(system_time.wMilliseconds * 1000); + return 0; +} + +#define RUSAGE_SELF 0 +#define RUSAGE_CHILDREN (-1) + +struct rusage { + struct timeval ru_utime; /* user time used */ + struct timeval ru_stime; /* system time used */ +}; + +inline int getrusage(int who, struct rusage* rusage) { + FILETIME starttime; + FILETIME exittime; + FILETIME kerneltime; + FILETIME usertime; + ULARGE_INTEGER li; + + if (who != RUSAGE_SELF) { + /* Only RUSAGE_SELF is supported in this implementation for now */ + errno = EINVAL; + return -1; + } + + if (rusage == (struct rusage*)NULL) { + errno = EFAULT; + return -1; + } + memset(rusage, 0, sizeof(struct rusage)); + if (GetProcessTimes(GetCurrentProcess(), &starttime, &exittime, &kerneltime, + &usertime) == 0) { + return -1; + } + + /* Convert FILETIMEs (0.1 us) to struct timeval */ + memcpy(&li, &kerneltime, sizeof(FILETIME)); + li.QuadPart /= 10L; /* Convert to microseconds */ + rusage->ru_stime.tv_sec = li.QuadPart / 1000000L; + rusage->ru_stime.tv_usec = li.QuadPart % 1000000L; + + memcpy(&li, &usertime, sizeof(FILETIME)); + li.QuadPart /= 10L; /* Convert to microseconds */ + rusage->ru_utime.tv_sec = li.QuadPart / 1000000L; + rusage->ru_utime.tv_usec = li.QuadPart % 1000000L; + + return 0; +} + +inline SIZE_T get_shared_memory_size(HANDLE h_process) { + MEMORY_BASIC_INFORMATION mbi; + SIZE_T base_address = 0; + SIZE_T shared_memory_size = 0; + + while (VirtualQueryEx(h_process, (LPCVOID)base_address, &mbi, sizeof(mbi))) { + if (mbi.State == MEM_COMMIT) { + if (mbi.Type == MEM_MAPPED || mbi.Type == MEM_IMAGE) { + shared_memory_size += mbi.RegionSize; + } + } + base_address = (SIZE_T)mbi.BaseAddress + mbi.RegionSize; + } + + return shared_memory_size; +} + +inline DWORD getppid() { + HANDLE h_snapshot; + PROCESSENTRY32 pe32; + DWORD ppid = 0, pid = GetCurrentProcessId(); + + h_snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + try { + if (h_snapshot == INVALID_HANDLE_VALUE) + return ppid; + + ZeroMemory(&pe32, sizeof(pe32)); + pe32.dwSize = sizeof(pe32); + if (!Process32First(h_snapshot, &pe32)) + return ppid; + + do { + if (pe32.th32ProcessID == pid) { + ppid = pe32.th32ParentProcessID; + break; + } + } while (Process32Next(h_snapshot, &pe32)); + + } catch (...) { + if (h_snapshot != INVALID_HANDLE_VALUE) + CloseHandle(h_snapshot); + } + + if (h_snapshot != INVALID_HANDLE_VALUE) + CloseHandle(h_snapshot); + + return ppid; +} + +inline DWORD get_thread_number(DWORD processId) { + DWORD thread_count = 0; + HANDLE snapshot_handle = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); + + if (snapshot_handle == INVALID_HANDLE_VALUE) { + std::cerr << "Failed to create snapshot. Error code: " << GetLastError() + << std::endl; + return 0; + } + + THREADENTRY32 threadEntry; + threadEntry.dwSize = sizeof(THREADENTRY32); + + if (Thread32First(snapshot_handle, &threadEntry)) { + do { + if (threadEntry.th32OwnerProcessID == processId) { + ++thread_count; + } + } while (Thread32Next(snapshot_handle, &threadEntry)); + } + else { + std::cerr << "Failed to retrieve thread information. Error code: " + << GetLastError() << std::endl; + } + + CloseHandle(snapshot_handle); + return thread_count; +} + +inline DWORD get_process_group(HANDLE process_handle) { + DWORD_PTR process_affinity_mask; + DWORD_PTR system_affinity_mask; + + if (GetProcessAffinityMask(process_handle, &process_affinity_mask, + &system_affinity_mask)) { + // Output the processor group information + // Process Affinity Mask + DWORD grop_id = process_affinity_mask; + return grop_id; + } + else { + std::cerr << "Failed to get process affinity mask. Error code: " + << GetLastError() << std::endl; + return 0; + } +} +#endif + inline int64_t last_time_us = 0; inline int64_t last_sys_time_us = 0; inline int64_t last_user_time_us = 0; @@ -145,7 +324,9 @@ inline void stat_memory() { long virtual_size = 0; long resident = 0; long share = 0; +#if defined(__GNUC__) static long page_size = sysconf(_SC_PAGE_SIZE); +#endif #if defined(__APPLE__) static pid_t pid = getpid(); @@ -169,9 +350,33 @@ inline void stat_memory() { file >> virtual_size >> resident >> share; #endif +#if defined(WIN32) + DWORD current_process = GetCurrentProcessId(); + // open process + HANDLE h_process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, + FALSE, current_process); + if (h_process == NULL) { + virtual_size = 0; + resident = 0; + share = 0; + } + PROCESS_MEMORY_COUNTERS pmc; + if (GetProcessMemoryInfo(h_process, &pmc, sizeof(pmc))) { + virtual_size = pmc.PagefileUsage; + resident = pmc.WorkingSetSize; + } + share = get_shared_memory_size(h_process); + + CloseHandle(h_process); + + process_memory_virtual->update(virtual_size); + process_memory_resident->update(resident); + process_memory_shared->update(share); +#else process_memory_virtual->update(virtual_size * page_size); process_memory_resident->update(resident * page_size); process_memory_shared->update(share * page_size); +#endif } struct ProcIO { @@ -199,10 +404,9 @@ inline void stat_io() { "ylt_process_io_write_second"); ProcIO s{}; -#if defined(__APPLE__) -#else +#if defined(__GUNC__) auto stream_file = - std::shared_ptr(fopen("/proc/self/io", "r"), [](FILE *ptr) { + std::shared_ptr(fopen("/proc/self/io", "r"), [](FILE* ptr) { fclose(ptr); }); if (stream_file == nullptr) { @@ -217,6 +421,30 @@ inline void stat_io() { } #endif +#if defined(WIN32) + DWORD current_process_id = GetCurrentProcessId(); + // open process + HANDLE h_process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, + FALSE, current_process_id); + if (h_process == NULL) { + s.rchar = 0; + s.wchar = 0; + s.syscr = 0; + s.syscw = 0; + } + else { + IO_COUNTERS io_counters = {0}; + if (GetProcessIoCounters(h_process, &io_counters)) { + s.rchar = io_counters.ReadOperationCount; + s.wchar = io_counters.WriteOperationCount; + s.syscr = io_counters.ReadOperationCount; + s.syscw = io_counters.WriteOperationCount; + } + } + + CloseHandle(h_process); +#endif + process_io_read_bytes_second->update(s.rchar); process_io_write_bytes_second->update(s.wchar); process_io_read_second->update(s.syscr); @@ -336,7 +564,7 @@ inline void process_status() { if (read_command_output_through_popen(oss, cmdbuf) != 0) { return; } - const std::string &result = oss.str(); + const std::string& result = oss.str(); if (sscanf(result.c_str(), "%d %d %d %d" "%d %u %ld %ld", @@ -344,6 +572,16 @@ inline void process_status() { &stat.flags, &stat.priority, &stat.nice) != 8) { return; } +#elif defined(WIN32) + stat.pid = GetCurrentProcessId(); + stat.ppid = getppid(); + + HANDLE h_process = + OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, stat.pid); + stat.priority = GetPriorityClass(h_process); + stat.num_threads = get_thread_number(stat.pid); + stat.pgrp = get_process_group(h_process); + CloseHandle(h_process); #endif process_uptime->inc(); process_priority->update(stat.priority); @@ -362,7 +600,8 @@ inline void stat_metric() { static auto user_metric_label_count = system_metric_manager::instance().get_metric_static( "ylt_user_metric_labels"); - user_metric_label_count->update(metric_t::g_user_metric_label_count->value()); + user_metric_label_count->update( + metric::metric_t::g_user_metric_label_count->value()); } inline void ylt_stat() { @@ -450,5 +689,4 @@ inline bool start_system_metric() { return true; } -} // namespace ylt::metric -#endif \ No newline at end of file +} // namespace ylt::metric \ No newline at end of file