14 #include "serverpool.h"
20 extern ServerPool *servers;
22 StatsThread::StatsThread(const std::string &stats_file, int stats_interval)
23 : stats_file(stats_file),
24 stats_interval(stats_interval)
28 void StatsThread::do_work()
30 while (!should_stop()) {
34 vector<ClientStats> client_stats;
36 // Open a new, temporary file.
37 char *filename = strdup((stats_file + ".new.XXXXXX").c_str());
38 fd = mkostemp(filename, O_WRONLY);
49 if (unlink(filename) == -1) {
57 client_stats = servers->get_client_stats();
58 for (size_t i = 0; i < client_stats.size(); ++i) {
59 fprintf(fp, "%s %d %d %s %d %llu %llu %llu\n",
60 client_stats[i].remote_addr.c_str(),
62 client_stats[i].fwmark,
63 client_stats[i].stream_id.c_str(),
64 int(now - client_stats[i].connect_time),
65 (long long unsigned)(client_stats[i].bytes_sent),
66 (long long unsigned)(client_stats[i].bytes_lost),
67 (long long unsigned)(client_stats[i].num_loss_events));
69 if (fclose(fp) == EOF) {
71 if (unlink(filename) == -1) {
78 if (rename(filename, stats_file.c_str()) == -1) {
80 if (unlink(filename) == -1) {
87 // Wait until we are asked to quit, stats_interval timeout,
88 // or a spurious signal. (The latter will cause us to write stats
89 // too often, but that's okay.)
91 timeout_ts.tv_sec = stats_interval;
92 timeout_ts.tv_nsec = 0;
93 wait_for_wakeup(&timeout_ts);