File: accesslog.cpp

package info (click to toggle)
cubemap 1.3.2-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 428 kB
  • sloc: cpp: 4,431; sh: 114; perl: 102; makefile: 60
file content (95 lines) | stat: -rw-r--r-- 2,323 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <stddef.h>
#include <stdio.h>
#include <time.h>
#include <string>
#include <vector>

#include "accesslog.h"
#include "client.h"
#include "log.h"
#include "mutexlock.h"
#include "timespec.h"

using namespace std;

AccessLogThread::AccessLogThread()
{
	pthread_mutex_init(&mutex, NULL);
}

AccessLogThread::AccessLogThread(const string &filename)
	: filename(filename) {
	pthread_mutex_init(&mutex, NULL);
}

void AccessLogThread::write(const ClientStats& client)
{
	{
		MutexLock lock(&mutex);
		pending_writes.push_back(client);
	}
	wakeup();
}

void AccessLogThread::do_work()
{
	// Open the file.
	if (filename.empty()) {
		logfp = NULL;
	} else {
		logfp = fopen(filename.c_str(), "a+");
		if (logfp == NULL) {
			log_perror(filename.c_str());
			// Continue as before.
		}
	}

	while (!should_stop()) {
		// Empty the queue.
		vector<ClientStats> writes;
		{
			MutexLock lock(&mutex);
			swap(pending_writes, writes);
		}

		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);
			}
		}

		// Wait until we are being woken up, either to quit or because
		// there is material in pending_writes.
		wait_for_wakeup(NULL);
	}

	if (logfp != NULL) {	
		if (fclose(logfp) == EOF) {
			log_perror("fclose");
		}
	}

	logfp = NULL;
}