Run include-what-you-use.
[cubemap] / accesslog.cpp
1 #include <stddef.h>
2 #include <stdio.h>
3 #include <time.h>
4 #include <string>
5 #include <vector>
6
7 #include "accesslog.h"
8 #include "client.h"
9 #include "log.h"
10 #include "mutexlock.h"
11
12 using namespace std;
13
14 AccessLogThread::AccessLogThread()
15 {
16         pthread_mutex_init(&mutex, NULL);
17 }
18
19 AccessLogThread::AccessLogThread(const string &filename)
20         : filename(filename) {
21         pthread_mutex_init(&mutex, NULL);
22 }
23
24 void AccessLogThread::write(const ClientStats& client)
25 {
26         MutexLock lock(&mutex);
27         pending_writes.push_back(client);
28 }
29
30 void AccessLogThread::do_work()
31 {
32         // Open the file.
33         if (filename.empty()) {
34                 logfp = NULL;
35         } else {
36                 logfp = fopen(filename.c_str(), "a+");
37                 if (logfp == NULL) {
38                         log_perror(filename.c_str());
39                         // Continue as before.
40                 }
41         }
42
43         while (!should_stop()) {
44                 // Empty the queue.
45                 vector<ClientStats> writes;
46                 {
47                         MutexLock lock(&mutex);
48                         swap(pending_writes, writes);
49                 }
50
51                 if (logfp != NULL) {
52                         // Do the actual writes.
53                         time_t now = time(NULL);
54                         for (size_t i = 0; i < writes.size(); ++i) {
55                                 fprintf(logfp, "%llu %s %s %d %llu %llu %llu\n",
56                                         (long long unsigned)(writes[i].connect_time),
57                                         writes[i].remote_addr.c_str(),
58                                         writes[i].url.c_str(),
59                                         int(now - writes[i].connect_time),
60                                         (long long unsigned)(writes[i].bytes_sent),
61                                         (long long unsigned)(writes[i].bytes_lost),
62                                         (long long unsigned)(writes[i].num_loss_events));
63                         }
64                         fflush(logfp);
65                 }
66
67                 // Wait until we are being woken up, either to quit or because
68                 // there is material in pending_writes.
69                 wait_for_wakeup(NULL);
70         }
71
72         if (logfp != NULL) {    
73                 if (fclose(logfp) == EOF) {
74                         log_perror("fclose");
75                 }
76         }
77
78         logfp = NULL;
79 }