From bb1b9f42e8dc55e1cdb45ac04459f805ec6807fb Mon Sep 17 00:00:00 2001 From: Ivan Baidakou Date: Tue, 13 Sep 2016 13:56:54 +0300 Subject: [PATCH 01/12] Make it win32 and cmake friendly --- CMakeLists.txt | 40 +++++++++++++++++++ Makefile | 11 ------ src/CMakeLists.txt | 4 ++ src/Makefile | 21 ---------- src/StatsdClientConfig.h.in | 11 ++++++ src/statsd_client.cpp | 77 ++++++++++++++++++++++++------------- src/statsd_client.h | 5 +-- 7 files changed, 107 insertions(+), 62 deletions(-) create mode 100644 CMakeLists.txt delete mode 100644 Makefile create mode 100644 src/CMakeLists.txt delete mode 100644 src/Makefile create mode 100644 src/StatsdClientConfig.h.in diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..7890309 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,40 @@ +cmake_minimum_required (VERSION 2.6) +project (StatsdClient) + +set (StatsdClient_VERSION_MAJOR 1) +set (StatsdClient_VERSION_MINOR 0) + +# check for headers +# unix specific headers +include (${CMAKE_ROOT}/Modules/CheckIncludeFile.cmake) +if(UNIX) + CHECK_INCLUDE_FILE("sys/socket.h" HAVE_SYS_SOCKET_H) + CHECK_INCLUDE_FILE("arpa/inet.h" HAVE_APRA_INET_H) + CHECK_INCLUDE_FILE("netdb.h" HAVE_NETDB_H) + CHECK_INCLUDE_FILE("unistd.h" HAVE_UNISTD_H) +endif(UNIX) + +# windows-specific headers +if(NOT UNIX) + CHECK_INCLUDE_FILE("winsock2.h" HAVE_WINSOCK2_H) + CHECK_INCLUDE_FILE("ws2tcpip.h" HAVE_WS2TCPIP_H) +endif(NOT UNIX) + +# check for functions +include (${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake) +check_function_exists (closesocket HAVE_CLOSE_SOCKET) + + +include_directories ("${PROJECT_SOURCE_DIR}/src") +add_subdirectory (src) + +configure_file ( + "${PROJECT_SOURCE_DIR}/src/StatsdClient2Config.h.in" + "${PROJECT_BINARY_DIR}/StatsdClient2Config.h" + ) + +include_directories("${PROJECT_BINARY_DIR}") + +install (FILES "${PROJECT_BINARY_DIR}/StatsdClientConfig.h" + DESTINATION include) + diff --git a/Makefile b/Makefile deleted file mode 100644 index 4a3700d..0000000 --- a/Makefile +++ /dev/null @@ -1,11 +0,0 @@ - -all: - make -C src/; - make -C demo/; - @for f in demo/*; do test -x $$f && cp -v $$f ./; done; echo - -clean: - make -C src/ clean; - make -C demo/ clean; - @rm -f ./system_monitor ./test_client - diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..6d9e4ca --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,4 @@ +add_library(StatsdClient2 statsd_client.cpp) + +install (TARGETS StatsdClient2 DESTINATION bin) +install (FILES MathFunctions.h DESTINATION include) diff --git a/src/Makefile b/src/Makefile deleted file mode 100644 index bfeb08f..0000000 --- a/src/Makefile +++ /dev/null @@ -1,21 +0,0 @@ - -CXX=g++ -CPPFLAGS += -Wall -g - -TARGET = statsd_client -TARGET_LIB = lib$(TARGET).a -TARGET_HEADER = $(TARGET).h -TARGET_SOURCE = $(TARGET).cpp -TARGET_OBJ = $(TARGET).o - -all: $(TARGET_LIB) - -$(TARGET_LIB): $(TARGET_OBJ) - ar crus $@ $< - -$(TARGET_OBJ): $(TARGET_SOURCE) $(TARGET_HEADER) - $(CXX) -c -o $@ $< $(CPPFLAGS) - -clean: - rm -f $(TARGET_OBJ) $(TARGET_LIB) - diff --git a/src/StatsdClientConfig.h.in b/src/StatsdClientConfig.h.in new file mode 100644 index 0000000..81cc3fc --- /dev/null +++ b/src/StatsdClientConfig.h.in @@ -0,0 +1,11 @@ +#define StatsdClient_VERSION_MAJOR @StatsdClient_VERSION_MAJOR@ +#define StatsdClient_VERSION_MINOR @StatsdClient_VERSION_MINOR@ + +#cmakedefine HAVE_SYS_SOCKET_H +#cmakedefine HAVE_APRA_INET_H +#cmakedefine HAVE_NETDB_H +#cmakedefine HAVE_UNISTD_H + +#cmakedefine HAVE_WINSOCK2_H +#cmakedefine HAVE_WS2TCPIP_H +#cmakedefine HAVE_CLOSE_SOCKET diff --git a/src/statsd_client.cpp b/src/statsd_client.cpp index 1fbadfa..00d5de1 100644 --- a/src/statsd_client.cpp +++ b/src/statsd_client.cpp @@ -1,15 +1,42 @@ - #include -#include #include -#include #include #include #include #include -#include #include "statsd_client.h" -#include + +/* platform-specific headers */ +#ifdef HAVE_WINSOCK2_H + #include +#endif +#ifdef HAVE_WS2TCPIP_H + #include +#endif + +#ifdef HAVE_SYS_SOCKET_H + #include +#endif + +#ifdef HAVE_APRA_INET_H + #include +#endif + +#ifdef HAVE_NETDB_H + #include /* Needed for getaddrinfo() and freeaddrinfo() */ +#endif + +#ifdef HAVE_UNISTD_H + #include /* Needed for close() */ +#endif + +#ifdef _WIN32 + // Win32-specific close socket function + #define CLOSE_SOCKET(s) closesocket(s) +#else + // Generic Unix close socket function + #define CLOSE_SOCKET(s) close(s) +#endif using namespace std; namespace statsd { @@ -27,7 +54,7 @@ inline bool should_send(float sample_rate) return true; } - float p = ((float)random() / RAND_MAX); + float p = ((float)rand() / RAND_MAX); return sample_rate > p; } @@ -48,14 +75,14 @@ StatsdClient::StatsdClient(const string& host, int port, const string& ns) d = new _StatsdClientData; d->sock = -1; config(host, port, ns); - srandom(time(NULL)); + srand(time(NULL)); } StatsdClient::~StatsdClient() { // close socket if (d->sock >= 0) { - close(d->sock); + CLOSE_SOCKET(d->sock); d->sock = -1; delete d; d = NULL; @@ -69,7 +96,7 @@ void StatsdClient::config(const string& host, int port, const string& ns) d->port = port; d->init = false; if ( d->sock >= 0 ) { - close(d->sock); + CLOSE_SOCKET(d->sock); } d->sock = -1; } @@ -88,25 +115,21 @@ int StatsdClient::init() d->server.sin_family = AF_INET; d->server.sin_port = htons(d->port); - int ret = inet_aton(d->host.c_str(), &d->server.sin_addr); - if ( ret == 0 ) - { - // host must be a domain, get it from internet - struct addrinfo hints, *result = NULL; - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_DGRAM; - - ret = getaddrinfo(d->host.c_str(), NULL, &hints, &result); - if ( ret ) { - snprintf(d->errmsg, sizeof(d->errmsg), - "getaddrinfo fail, error=%d, msg=%s", ret, gai_strerror(ret) ); - return -2; - } - struct sockaddr_in* host_addr = (struct sockaddr_in*)result->ai_addr; - memcpy(&d->server.sin_addr, &host_addr->sin_addr, sizeof(struct in_addr)); - freeaddrinfo(result); + // host must be a domain, get it from internet + struct addrinfo hints, *result = NULL; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_DGRAM; + + int ret = getaddrinfo(d->host.c_str(), NULL, &hints, &result); + if ( ret ) { + snprintf(d->errmsg, sizeof(d->errmsg), + "getaddrinfo fail, error=%d, msg=%s", ret, gai_strerror(ret) ); + return -2; } + struct sockaddr_in* host_addr = (struct sockaddr_in*)result->ai_addr; + memcpy(&d->server.sin_addr, &host_addr->sin_addr, sizeof(struct in_addr)); + freeaddrinfo(result); d->init = true; return 0; diff --git a/src/statsd_client.h b/src/statsd_client.h index 9e97e83..1fec589 100644 --- a/src/statsd_client.h +++ b/src/statsd_client.h @@ -2,9 +2,8 @@ #ifndef STATSD_CLIENT_H #define STATSD_CLIENT_H -#include -#include -#include +#include "../StatsdClient2Config.h" + #include namespace statsd { From 59850c325efad74bded15731016980db425c093f Mon Sep 17 00:00:00 2001 From: Ivan Baidakou Date: Fri, 16 Sep 2016 11:08:48 +0300 Subject: [PATCH 02/12] Feedback: up min version for cmake --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7890309..751c96f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 3.2) project (StatsdClient) set (StatsdClient_VERSION_MAJOR 1) From 6da5edbaf885b2f00fa54cd4c7550568896a9347 Mon Sep 17 00:00:00 2001 From: Ivan Baidakou Date: Fri, 16 Sep 2016 11:11:53 +0300 Subject: [PATCH 03/12] Remove unused check for socket existance --- CMakeLists.txt | 4 ---- src/StatsdClientConfig.h.in | 1 - 2 files changed, 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 751c96f..10aa207 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,10 +20,6 @@ if(NOT UNIX) CHECK_INCLUDE_FILE("ws2tcpip.h" HAVE_WS2TCPIP_H) endif(NOT UNIX) -# check for functions -include (${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake) -check_function_exists (closesocket HAVE_CLOSE_SOCKET) - include_directories ("${PROJECT_SOURCE_DIR}/src") add_subdirectory (src) diff --git a/src/StatsdClientConfig.h.in b/src/StatsdClientConfig.h.in index 81cc3fc..95466c4 100644 --- a/src/StatsdClientConfig.h.in +++ b/src/StatsdClientConfig.h.in @@ -8,4 +8,3 @@ #cmakedefine HAVE_WINSOCK2_H #cmakedefine HAVE_WS2TCPIP_H -#cmakedefine HAVE_CLOSE_SOCKET From 63e06d78399b883e2ee03e748174b741998c51ec Mon Sep 17 00:00:00 2001 From: Ivan Baidakou Date: Fri, 16 Sep 2016 11:13:50 +0300 Subject: [PATCH 04/12] Fix filenames in CMakeList.txt --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 10aa207..fbb8115 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,8 +25,8 @@ include_directories ("${PROJECT_SOURCE_DIR}/src") add_subdirectory (src) configure_file ( - "${PROJECT_SOURCE_DIR}/src/StatsdClient2Config.h.in" - "${PROJECT_BINARY_DIR}/StatsdClient2Config.h" + "${PROJECT_SOURCE_DIR}/src/StatsdClientConfig.h.in" + "${PROJECT_BINARY_DIR}/StatsdClientConfig.h" ) include_directories("${PROJECT_BINARY_DIR}") From 581181064d195e9d250e9102463a11f4fc9c34e0 Mon Sep 17 00:00:00 2001 From: Ivan Baidakou Date: Fri, 16 Sep 2016 11:15:32 +0300 Subject: [PATCH 05/12] Let's keep the original Makefile --- Makefile | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4a3700d --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ + +all: + make -C src/; + make -C demo/; + @for f in demo/*; do test -x $$f && cp -v $$f ./; done; echo + +clean: + make -C src/ clean; + make -C demo/ clean; + @rm -f ./system_monitor ./test_client + From 50161a7c633a78af0000298d40015bb3427a181b Mon Sep 17 00:00:00 2001 From: Ivan Baidakou Date: Fri, 16 Sep 2016 11:49:20 +0300 Subject: [PATCH 06/12] Simplify checks --- CMakeLists.txt | 17 ----------------- src/StatsdClientConfig.h.in | 8 -------- src/statsd_client.cpp | 29 ++++++----------------------- src/statsd_client.h | 2 +- 4 files changed, 7 insertions(+), 49 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fbb8115..d782dfa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,23 +4,6 @@ project (StatsdClient) set (StatsdClient_VERSION_MAJOR 1) set (StatsdClient_VERSION_MINOR 0) -# check for headers -# unix specific headers -include (${CMAKE_ROOT}/Modules/CheckIncludeFile.cmake) -if(UNIX) - CHECK_INCLUDE_FILE("sys/socket.h" HAVE_SYS_SOCKET_H) - CHECK_INCLUDE_FILE("arpa/inet.h" HAVE_APRA_INET_H) - CHECK_INCLUDE_FILE("netdb.h" HAVE_NETDB_H) - CHECK_INCLUDE_FILE("unistd.h" HAVE_UNISTD_H) -endif(UNIX) - -# windows-specific headers -if(NOT UNIX) - CHECK_INCLUDE_FILE("winsock2.h" HAVE_WINSOCK2_H) - CHECK_INCLUDE_FILE("ws2tcpip.h" HAVE_WS2TCPIP_H) -endif(NOT UNIX) - - include_directories ("${PROJECT_SOURCE_DIR}/src") add_subdirectory (src) diff --git a/src/StatsdClientConfig.h.in b/src/StatsdClientConfig.h.in index 95466c4..37dc48d 100644 --- a/src/StatsdClientConfig.h.in +++ b/src/StatsdClientConfig.h.in @@ -1,10 +1,2 @@ #define StatsdClient_VERSION_MAJOR @StatsdClient_VERSION_MAJOR@ #define StatsdClient_VERSION_MINOR @StatsdClient_VERSION_MINOR@ - -#cmakedefine HAVE_SYS_SOCKET_H -#cmakedefine HAVE_APRA_INET_H -#cmakedefine HAVE_NETDB_H -#cmakedefine HAVE_UNISTD_H - -#cmakedefine HAVE_WINSOCK2_H -#cmakedefine HAVE_WS2TCPIP_H diff --git a/src/statsd_client.cpp b/src/statsd_client.cpp index 00d5de1..fdf2971 100644 --- a/src/statsd_client.cpp +++ b/src/statsd_client.cpp @@ -6,35 +6,18 @@ #include #include "statsd_client.h" + /* platform-specific headers */ -#ifdef HAVE_WINSOCK2_H +#ifdef _WIN32 #include -#endif -#ifdef HAVE_WS2TCPIP_H #include -#endif - -#ifdef HAVE_SYS_SOCKET_H + #define CLOSE_SOCKET(s) closesocket(s) +#else #include -#endif - -#ifdef HAVE_APRA_INET_H - #include -#endif - -#ifdef HAVE_NETDB_H - #include /* Needed for getaddrinfo() and freeaddrinfo() */ -#endif - -#ifdef HAVE_UNISTD_H + #include + #include /* Needed for getaddrinfo() and freeaddrinfo() */ #include /* Needed for close() */ -#endif -#ifdef _WIN32 - // Win32-specific close socket function - #define CLOSE_SOCKET(s) closesocket(s) -#else - // Generic Unix close socket function #define CLOSE_SOCKET(s) close(s) #endif diff --git a/src/statsd_client.h b/src/statsd_client.h index 1fec589..949d7b4 100644 --- a/src/statsd_client.h +++ b/src/statsd_client.h @@ -2,7 +2,7 @@ #ifndef STATSD_CLIENT_H #define STATSD_CLIENT_H -#include "../StatsdClient2Config.h" +#include "../StatsdClientConfig.h" #include From 726fa0a65a6472c1f0ff1e8b43139817a4c811ab Mon Sep 17 00:00:00 2001 From: Ivan Baidakou Date: Fri, 16 Sep 2016 11:50:55 +0300 Subject: [PATCH 07/12] use std::nullptr --- src/statsd_client.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/statsd_client.cpp b/src/statsd_client.cpp index fdf2971..69f40d0 100644 --- a/src/statsd_client.cpp +++ b/src/statsd_client.cpp @@ -68,7 +68,7 @@ StatsdClient::~StatsdClient() CLOSE_SOCKET(d->sock); d->sock = -1; delete d; - d = NULL; + d = std::nullptr; } } From 3db82fbafd4aacd61954b0c041c8fa01f035fe54 Mon Sep 17 00:00:00 2001 From: Ivan Baidakou Date: Fri, 16 Sep 2016 14:13:15 +0300 Subject: [PATCH 08/12] Minor fixes --- src/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6d9e4ca..8c67f93 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,4 @@ -add_library(StatsdClient2 statsd_client.cpp) +add_library(StatsdClient statsd_client.cpp) -install (TARGETS StatsdClient2 DESTINATION bin) -install (FILES MathFunctions.h DESTINATION include) +install (TARGETS StatsdClient DESTINATION lib) +install (FILES statsd_client.h DESTINATION include) From 7e0b06c63e50702209d36a09cd51d4c753094d57 Mon Sep 17 00:00:00 2001 From: Ivan Baidakou Date: Fri, 16 Sep 2016 14:21:12 +0300 Subject: [PATCH 09/12] Use nullptr, activate that feature from std=c++11 --- CMakeLists.txt | 2 ++ src/statsd_client.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d782dfa..6636d39 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,8 @@ configure_file ( "${PROJECT_BINARY_DIR}/StatsdClientConfig.h" ) +target_compile_features(StatsdClient PRIVATE cxx_nullptr) + include_directories("${PROJECT_BINARY_DIR}") install (FILES "${PROJECT_BINARY_DIR}/StatsdClientConfig.h" diff --git a/src/statsd_client.cpp b/src/statsd_client.cpp index 69f40d0..3b69f98 100644 --- a/src/statsd_client.cpp +++ b/src/statsd_client.cpp @@ -68,7 +68,7 @@ StatsdClient::~StatsdClient() CLOSE_SOCKET(d->sock); d->sock = -1; delete d; - d = std::nullptr; + d = nullptr; } } From c010cf495a5f4d9b2075da86bea2100bc3209b54 Mon Sep 17 00:00:00 2001 From: Ivan Baidakou Date: Fri, 16 Sep 2016 14:56:09 +0300 Subject: [PATCH 10/12] Use instead of C's rand() --- src/statsd_client.cpp | 34 ++++++++++++++++++++++------------ src/statsd_client.h | 1 + 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/statsd_client.cpp b/src/statsd_client.cpp index 3b69f98..3d7526e 100644 --- a/src/statsd_client.cpp +++ b/src/statsd_client.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "statsd_client.h" @@ -30,17 +31,6 @@ inline bool fequal(float a, float b) return ( fabs(a - b) < epsilon ); } -inline bool should_send(float sample_rate) -{ - if ( fequal(sample_rate, 1.0) ) - { - return true; - } - - float p = ((float)rand() / RAND_MAX); - return sample_rate > p; -} - struct _StatsdClientData { int sock; struct sockaddr_in server; @@ -50,13 +40,33 @@ struct _StatsdClientData { short port; bool init; + std::default_random_engine rng_engine; + std::uniform_real_distribution<> rng_dist; + + char errmsg[1024]; }; +inline bool should_send(_StatsdClientData* d, float sample_rate) +{ + if ( fequal(sample_rate, 1.0) ) + { + return true; + } + + float p = d->rng_dist(d->rng_engine); + return sample_rate > p; +} + StatsdClient::StatsdClient(const string& host, int port, const string& ns) { d = new _StatsdClientData; + d->sock = -1; + std::random_device rd; + d->rng_engine = std::default_random_engine(rd () ); + d->rng_dist = std::uniform_real_distribution<>(0.0f, 1.0f); + config(host, port, ns); srand(time(NULL)); } @@ -156,7 +166,7 @@ int StatsdClient::timing(const string& key, size_t ms, float sample_rate) int StatsdClient::send(string key, size_t value, const string &type, float sample_rate) { - if (!should_send(sample_rate)) { + if (!should_send(this->d, sample_rate)) { return 0; } diff --git a/src/statsd_client.h b/src/statsd_client.h index 949d7b4..874b023 100644 --- a/src/statsd_client.h +++ b/src/statsd_client.h @@ -6,6 +6,7 @@ #include + namespace statsd { struct _StatsdClientData; From 2d0314dfe603e84c10cc6b8b136f541ed58de2ad Mon Sep 17 00:00:00 2001 From: Ivan Baidakou Date: Fri, 16 Sep 2016 15:17:25 +0300 Subject: [PATCH 11/12] Add comment for possible upsteam PR --- src/statsd_client.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/statsd_client.cpp b/src/statsd_client.cpp index 3d7526e..136da26 100644 --- a/src/statsd_client.cpp +++ b/src/statsd_client.cpp @@ -114,6 +114,7 @@ int StatsdClient::init() hints.ai_family = AF_INET; hints.ai_socktype = SOCK_DGRAM; + // looks up IPv4/IPv6 address by host name or stringized IP address int ret = getaddrinfo(d->host.c_str(), NULL, &hints, &result); if ( ret ) { snprintf(d->errmsg, sizeof(d->errmsg), From be07266bc9e8d0e87abe67233ba3e735e1d298c5 Mon Sep 17 00:00:00 2001 From: Ivan Baidakou Date: Fri, 16 Sep 2016 15:19:19 +0300 Subject: [PATCH 12/12] remove srand --- src/statsd_client.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/statsd_client.cpp b/src/statsd_client.cpp index 136da26..8eb3d87 100644 --- a/src/statsd_client.cpp +++ b/src/statsd_client.cpp @@ -68,7 +68,6 @@ StatsdClient::StatsdClient(const string& host, int port, const string& ns) d->rng_dist = std::uniform_real_distribution<>(0.0f, 1.0f); config(host, port, ns); - srand(time(NULL)); } StatsdClient::~StatsdClient()