]> git.sesse.net Git - cubemap/blobdiff - accesslog.cpp
Add suppor for raw (non-Metacube) inputs over HTTP. Only really useful for TS.
[cubemap] / accesslog.cpp
index b666f27cf3018fdd47e5fd76c51a2a6483cb4802..af53872e6ec03c0d68f83b86e4b9c9f83320eb6d 100644 (file)
@@ -1,9 +1,6 @@
+#include <stddef.h>
 #include <stdio.h>
-#include <unistd.h>
-#include <sys/poll.h>
-#include <errno.h>
-
-#include <algorithm>
+#include <time.h>
 #include <string>
 #include <vector>
 
 #include "client.h"
 #include "log.h"
 #include "mutexlock.h"
+#include "timespec.h"
 
 using namespace std;
 
-AccessLogThread::AccessLogThread() {}
+AccessLogThread::AccessLogThread()
+{
+       pthread_mutex_init(&mutex, NULL);
+}
 
 AccessLogThread::AccessLogThread(const string &filename)
-       : filename(filename) {}
+       : filename(filename) {
+       pthread_mutex_init(&mutex, NULL);
+}
 
 void AccessLogThread::write(const ClientStats& client)
 {
-       MutexLock lock(&mutex);
-       pending_writes.push_back(client);
+       {
+               MutexLock lock(&mutex);
+               pending_writes.push_back(client);
+       }
+       wakeup();
 }
 
 void AccessLogThread::do_work()
@@ -38,7 +44,7 @@ void AccessLogThread::do_work()
                }
        }
 
-       while (!should_stop) {
+       while (!should_stop()) {
                // Empty the queue.
                vector<ClientStats> writes;
                {
@@ -46,47 +52,43 @@ void AccessLogThread::do_work()
                        swap(pending_writes, writes);
                }
 
-               if (logfp == NULL) {
-                       continue;
+               if (logfp != NULL) {
+                       // Do the actual writes.
+                       timespec now_monotonic;
+                       timespec now_realtime;
+                       if (clock_gettime(CLOCK_MONOTONIC_COARSE, &now_monotonic) == -1) {
+                               log_perror("clock_gettime(CLOCK_MONOTONIC_COARSE)");
+                       } else if (clock_gettime(CLOCK_REALTIME, &now_realtime) == -1) {
+                               log_perror("clock_gettime(CLOCK_REALTIME)");
+                       } else {
+                               timespec realtime_offset = clock_diff(now_monotonic, now_realtime);
+                               for (size_t i = 0; i < writes.size(); ++i) {
+                                       timespec connect_time_realtime = clock_add(writes[i].connect_time, realtime_offset);
+                                       timespec time_since_connect = clock_diff(writes[i].connect_time, now_monotonic);
+                                       fprintf(logfp, "%llu %s %s %d %llu %llu %llu \"%s\" \"%s\"\n",
+                                               (long long unsigned)(connect_time_realtime.tv_sec),
+                                               writes[i].remote_addr.c_str(),
+                                               writes[i].url.c_str(),
+                                               int(time_since_connect.tv_sec),
+                                               (long long unsigned)(writes[i].bytes_sent),
+                                               (long long unsigned)(writes[i].bytes_lost),
+                                               (long long unsigned)(writes[i].num_loss_events),
+                                               writes[i].referer.c_str(),
+                                               writes[i].user_agent.c_str());
+                               }
+                               fflush(logfp);
+                       }
                }
 
-               // Do the actual writes.
-               time_t now = time(NULL);
-               for (size_t i = 0; i < writes.size(); ++i) {
-                       fprintf(logfp, "%llu %s %s %d %llu %llu %llu\n",
-                               (long long unsigned)(writes[i].connect_time),
-                               writes[i].remote_addr.c_str(),
-                               writes[i].stream_id.c_str(),
-                               int(now - writes[i].connect_time),
-                               (long long unsigned)(writes[i].bytes_sent),
-                               (long long unsigned)(writes[i].bytes_lost),
-                               (long long unsigned)(writes[i].num_loss_events));
-               }
-               fflush(logfp);
-               
-               // Wait until the stop_fd pipe is closed, one second has passed.
-               // or a spurious signal arrives.
-               pollfd pfd;
-               pfd.fd = stop_fd_read;
-               pfd.events = POLLIN | POLLRDHUP;
+               // Wait until we are being woken up, either to quit or because
+               // there is material in pending_writes.
+               wait_for_wakeup(NULL);
+       }
 
-               int nfds = poll(&pfd, 1, 1000);
-               if (nfds == 0 || (nfds == -1 && errno == EINTR)) {
-                       continue;
-               }
-               if (nfds == 1) {
-                       // Should stop.
-                       break;
+       if (logfp != NULL) {    
+               if (fclose(logfp) == EOF) {
+                       log_perror("fclose");
                }
-               if (nfds == -1) {
-                       log_perror("poll");
-                       usleep(100000);
-                       continue;
-               }
-       }
-       
-       if (fclose(logfp) == EOF) {
-               log_perror("fclose");
        }
 
        logfp = NULL;