14 #include "serverpool.h"
19 extern ServerPool *servers;
21 StatsThread::StatsThread(const std::string &stats_file, int stats_interval)
22 : stats_file(stats_file),
23 stats_interval(stats_interval)
27 void StatsThread::do_work()
29 while (!should_stop) {
33 vector<ClientStats> client_stats;
35 // Open a new, temporary file.
36 char *filename = strdup((stats_file + ".new.XXXXXX").c_str());
37 fd = mkostemp(filename, O_WRONLY);
47 if (close(fd) == -1) {
50 if (unlink(filename) == -1) {
58 client_stats = servers->get_client_stats();
59 for (size_t i = 0; i < client_stats.size(); ++i) {
60 fprintf(fp, "%s %d %d %s %d %llu %llu %llu\n",
61 client_stats[i].remote_addr.c_str(),
63 client_stats[i].fwmark,
64 client_stats[i].stream_id.c_str(),
65 int(now - client_stats[i].connect_time),
66 (long long unsigned)(client_stats[i].bytes_sent),
67 (long long unsigned)(client_stats[i].bytes_lost),
68 (long long unsigned)(client_stats[i].num_loss_events));
70 if (fclose(fp) == EOF) {
72 if (unlink(filename) == -1) {
79 if (rename(filename, stats_file.c_str()) == -1) {
80 if (unlink(filename) == -1) {
88 // Wait until the stop_fd pipe is closed, stats_interval timeout,
89 // or a spurious signal. (The latter will cause us to write stats
90 // too often, but that's okay.)
92 pfd.fd = stop_fd_read;
93 pfd.events = POLLIN | POLLRDHUP;
95 int nfds = poll(&pfd, 1, stats_interval * 1000);
96 if (nfds == 0 || (nfds == -1 && errno == EINTR)) {