forked from efficient/cicada-exp-sigmod2017-silo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
stats_client.cc
90 lines (80 loc) · 2.38 KB
/
stats_client.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/**
* stats_client.cc
*
* stand-alone client to poll a stats server
*
*/
#include <iostream>
#include <string>
#include <system_error>
#include <thread>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include "counter.h"
#include "stats_common.h"
#include "util.h"
using namespace std;
using namespace util;
int
main(int argc, char **argv)
{
if (argc != 3) {
cerr << "[usage] " << argv[0] << " sockfile counterspec" << endl;
return 1;
}
const string sockfile(argv[1]);
const vector<string> counter_names = split(argv[2], ':');
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd < 0)
throw system_error(errno, system_category(),
"creating UNIX domain socket");
struct sockaddr_un addr;
memset(&addr, 0, sizeof addr);
addr.sun_family = AF_UNIX;
if (sockfile.length() + 1 >= sizeof addr.sun_path)
throw range_error("UNIX domain socket path too long");
strcpy(addr.sun_path, sockfile.c_str());
size_t len = strlen(addr.sun_path) + sizeof(addr.sun_family);
if (connect(fd, (struct sockaddr *) &addr, len) < 0)
throw system_error(errno, system_category(),
"connecting to socket");
packet pkt;
int r;
timer loop_timer;
for (;;) {
for (auto &name : counter_names) {
uint8_t buf[1 + name.size()];
buf[0] = (uint8_t) stats_command::GET_COUNTER_VALUE;
memcpy(&buf[1], name.data(), name.size());
pkt.assign((const char *) &buf[0], sizeof(buf));
if ((r = pkt.sendpkt(fd))) {
perror("send - disconnecting");
return 1;
}
if ((r = pkt.recvpkt(fd))) {
if (r == EOF)
return 0;
perror("recv - disconnecting");
return 1;
}
const get_counter_value_t *resp = (const get_counter_value_t *) pkt.data();
cout << name << " "
<< resp->timestamp_us_ << " "
<< resp->d_.count_ << " "
<< resp->d_.sum_ << " "
<< resp->d_.max_ << endl;
}
const uint64_t last_loop_usec = loop_timer.lap();
//const uint64_t delay_time_usec = 1000000;
const uint64_t delay_time_usec = 1000000/1000;
if (last_loop_usec < delay_time_usec) {
const uint64_t sleep_ns = (delay_time_usec - last_loop_usec) * 1000;
struct timespec t;
t.tv_sec = sleep_ns / ONE_SECOND_NS;
t.tv_nsec = sleep_ns % ONE_SECOND_NS;
nanosleep(&t, nullptr);
}
}
return 0;
}