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