]> git.sesse.net Git - cubemap/blob - stats.cpp
49106eed04fbcf7fffc0e2a8f5c8b6de79e1c081
[cubemap] / stats.cpp
1 #include <fcntl.h>
2 #include <stddef.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <time.h>
7 #include <unistd.h>
8 #include <vector>
9
10 #include "client.h"
11 #include "serverpool.h"
12 #include "stats.h"
13
14 using namespace std;
15
16 extern ServerPool *servers;
17
18 StatsThread::StatsThread(const std::string &stats_file, int stats_interval)
19         : stats_file(stats_file),
20           stats_interval(stats_interval)
21 {
22 }
23
24 void StatsThread::do_work()
25 {
26         while (!should_stop) {
27                 int fd;
28                 FILE *fp;
29                 time_t now;
30                 vector<ClientStats> client_stats;
31
32                 // Open a new, temporary file.
33                 char *filename = strdup((stats_file + ".new.XXXXXX").c_str());
34                 fd = mkostemp(filename, O_WRONLY);
35                 if (fd == -1) {
36                         perror(filename);
37                         free(filename);
38                         goto sleep;
39                 }
40
41                 fp = fdopen(fd, "w");
42                 if (fp == NULL) {
43                         perror("fdopen");
44                         close(fd);
45                         unlink(filename);
46                         free(filename);
47                         goto sleep;
48                 }
49
50                 now = time(NULL);
51                 client_stats = servers->get_client_stats();
52                 for (size_t i = 0; i < client_stats.size(); ++i) {
53                         fprintf(fp, "%s %s %d %llu\n",
54                                 client_stats[i].remote_addr.c_str(),
55                                 client_stats[i].stream_id.c_str(),
56                                 int(now - client_stats[i].connect_time),
57                                 (long long unsigned)(client_stats[i].bytes_sent));
58                 }
59                 if (fclose(fp) == EOF) {
60                         perror("fclose");
61                         unlink(filename);
62                         free(filename);
63                         goto sleep;
64                 }
65                 
66                 if (rename(filename, stats_file.c_str()) == -1) {
67                         perror("rename");
68                         unlink(filename);
69                 }
70
71 sleep:
72                 int left_to_sleep = stats_interval;
73                 do {
74                         left_to_sleep = sleep(left_to_sleep);
75                 } while (left_to_sleep > 0 && !should_stop);
76         }
77 }