1
-
2
1
#include < math.h>
3
- #include < netdb.h>
4
2
#include < time.h>
5
- #include < unistd.h>
6
3
#include < stdlib.h>
7
4
#include < string.h>
8
5
#include < stdio.h>
9
6
#include < sys/types.h>
10
- #include < netinet/in.h >
7
+ #include < random >
11
8
#include " statsd_client.h"
12
- #include < fcntl.h>
9
+
10
+
11
+ /* platform-specific headers */
12
+ #ifdef _WIN32
13
+ #include < winsock2.h>
14
+ #include < ws2tcpip.h>
15
+ #define CLOSE_SOCKET (s ) closesocket(s)
16
+ #else
17
+ #include < sys/socket.h>
18
+ #include < arpa/inet.h>
19
+ #include < netdb.h> /* Needed for getaddrinfo() and freeaddrinfo() */
20
+ #include < unistd.h> /* Needed for close() */
21
+
22
+ #define CLOSE_SOCKET (s ) close(s)
23
+ #endif
13
24
14
25
using namespace std ;
15
26
namespace statsd {
@@ -20,17 +31,6 @@ inline bool fequal(float a, float b)
20
31
return ( fabs (a - b) < epsilon );
21
32
}
22
33
23
- inline bool should_send (float sample_rate)
24
- {
25
- if ( fequal (sample_rate, 1.0 ) )
26
- {
27
- return true ;
28
- }
29
-
30
- float p = ((float )random () / RAND_MAX);
31
- return sample_rate > p;
32
- }
33
-
34
34
struct _StatsdClientData {
35
35
int sock;
36
36
struct sockaddr_in server;
@@ -40,25 +40,44 @@ struct _StatsdClientData {
40
40
short port;
41
41
bool init;
42
42
43
+ std::default_random_engine rng_engine;
44
+ std::uniform_real_distribution<> rng_dist;
45
+
46
+
43
47
char errmsg[1024 ];
44
48
};
45
49
50
+ inline bool should_send (_StatsdClientData* d, float sample_rate)
51
+ {
52
+ if ( fequal (sample_rate, 1.0 ) )
53
+ {
54
+ return true ;
55
+ }
56
+
57
+ float p = d->rng_dist (d->rng_engine );
58
+ return sample_rate > p;
59
+ }
60
+
46
61
StatsdClient::StatsdClient (const string& host, int port, const string& ns)
47
62
{
48
63
d = new _StatsdClientData;
64
+
49
65
d->sock = -1 ;
66
+ std::random_device rd;
67
+ d->rng_engine = std::default_random_engine (rd () );
68
+ d->rng_dist = std::uniform_real_distribution<>(0 .0f , 1 .0f );
69
+
50
70
config (host, port, ns);
51
- srandom (time (NULL ));
52
71
}
53
72
54
73
StatsdClient::~StatsdClient ()
55
74
{
56
75
// close socket
57
76
if (d->sock >= 0 ) {
58
- close (d->sock );
77
+ CLOSE_SOCKET (d->sock );
59
78
d->sock = -1 ;
60
79
delete d;
61
- d = NULL ;
80
+ d = nullptr ;
62
81
}
63
82
}
64
83
@@ -69,7 +88,7 @@ void StatsdClient::config(const string& host, int port, const string& ns)
69
88
d->port = port;
70
89
d->init = false ;
71
90
if ( d->sock >= 0 ) {
72
- close (d->sock );
91
+ CLOSE_SOCKET (d->sock );
73
92
}
74
93
d->sock = -1 ;
75
94
}
@@ -88,25 +107,22 @@ int StatsdClient::init()
88
107
d->server .sin_family = AF_INET;
89
108
d->server .sin_port = htons (d->port );
90
109
91
- int ret = inet_aton (d->host .c_str (), &d->server .sin_addr );
92
- if ( ret == 0 )
93
- {
94
- // host must be a domain, get it from internet
95
- struct addrinfo hints, *result = NULL ;
96
- memset (&hints, 0 , sizeof (hints));
97
- hints.ai_family = AF_INET;
98
- hints.ai_socktype = SOCK_DGRAM;
99
-
100
- ret = getaddrinfo (d->host .c_str (), NULL , &hints, &result);
101
- if ( ret ) {
102
- snprintf (d->errmsg , sizeof (d->errmsg ),
103
- " getaddrinfo fail, error=%d, msg=%s" , ret, gai_strerror (ret) );
104
- return -2 ;
105
- }
106
- struct sockaddr_in * host_addr = (struct sockaddr_in *)result->ai_addr ;
107
- memcpy (&d->server .sin_addr , &host_addr->sin_addr , sizeof (struct in_addr ));
108
- freeaddrinfo (result);
110
+ // host must be a domain, get it from internet
111
+ struct addrinfo hints, *result = NULL ;
112
+ memset (&hints, 0 , sizeof (hints));
113
+ hints.ai_family = AF_INET;
114
+ hints.ai_socktype = SOCK_DGRAM;
115
+
116
+ // looks up IPv4/IPv6 address by host name or stringized IP address
117
+ int ret = getaddrinfo (d->host .c_str (), NULL , &hints, &result);
118
+ if ( ret ) {
119
+ snprintf (d->errmsg , sizeof (d->errmsg ),
120
+ " getaddrinfo fail, error=%d, msg=%s" , ret, gai_strerror (ret) );
121
+ return -2 ;
109
122
}
123
+ struct sockaddr_in * host_addr = (struct sockaddr_in *)result->ai_addr ;
124
+ memcpy (&d->server .sin_addr , &host_addr->sin_addr , sizeof (struct in_addr ));
125
+ freeaddrinfo (result);
110
126
111
127
d->init = true ;
112
128
return 0 ;
@@ -150,7 +166,7 @@ int StatsdClient::timing(const string& key, size_t ms, float sample_rate)
150
166
151
167
int StatsdClient::send (string key, size_t value, const string &type, float sample_rate)
152
168
{
153
- if (!should_send (sample_rate)) {
169
+ if (!should_send (this -> d , sample_rate)) {
154
170
return 0 ;
155
171
}
156
172
0 commit comments