1
// libTorrent - BitTorrent library
2
// Copyright (C) 2005-2011, Jari Sundell
4
// This program is free software; you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation; either version 2 of the License, or
7
// (at your option) any later version.
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
// GNU General Public License for more details.
14
// You should have received a copy of the GNU General Public License
15
// along with this program; if not, write to the Free Software
16
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
// In addition, as a special exception, the copyright holders give
19
// permission to link the code of portions of this program with the
20
// OpenSSL library under certain conditions as described in each
21
// individual source file, and distribute linked combinations
24
// You must obey the GNU General Public License in all respects for
25
// all of the code used other than OpenSSL. If you modify file(s)
26
// with this exception, you may extend this exception to your version
27
// of the file(s), but you are not obligated to do so. If you do not
28
// wish to do so, delete this exception statement from your version.
29
// If you delete this exception statement from all source files in the
30
// program, then also delete it here.
32
// Contact: Jari Sundell <jaris@ifi.uio.no>
35
// 3185 Skoppum, NORWAY
46
#include "rak/timer.h"
47
#include "log_files.h"
49
#include "torrent/download/group_entry.h"
50
#include "protocol/peer_connection_base.h"
54
log_file log_files[LOG_MAX_SIZE] = {
55
log_file("mincore_stats"),
56
log_file("choke_changes")
60
log_file::open_file(const char* filename) {
64
m_last_update = rak::timer::current().seconds();
66
return (m_fd = open(filename, O_APPEND | O_RDWR | O_CREAT, 0666)) != -1;
79
find_log_file(const char* name) {
80
for (log_file* first = log_files, *last = log_files + LOG_MAX_SIZE; first != last; first++)
81
if (std::strcmp(name, first->name()) == 0)
88
// Specific log handling:
91
struct log_mincore_stats {
93
int counter_not_incore;
94
int counter_incore_new;
95
int counter_not_incore_new;
96
int counter_incore_break;
98
int counter_sync_success;
99
int counter_sync_failed;
100
int counter_sync_not_synced;
101
int counter_sync_not_deallocated;
102
int counter_alloc_failed;
104
uint64_t velocity_allocate;
105
uint64_t velocity_deallocate;
108
log_mincore_stats log_mincore_stats_instance = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
110
void log_mincore_stats_func_sync_success(int count) { log_mincore_stats_instance.counter_sync_success += count; }
111
void log_mincore_stats_func_sync_failed(int count) { log_mincore_stats_instance.counter_sync_failed += count; }
112
void log_mincore_stats_func_sync_not_synced(int count) { log_mincore_stats_instance.counter_sync_not_synced += count; }
113
void log_mincore_stats_func_sync_not_deallocated(int count) { log_mincore_stats_instance.counter_sync_not_deallocated += count; }
114
void log_mincore_stats_func_alloc_failed(int count) { log_mincore_stats_instance.counter_alloc_failed += count; }
115
void log_mincore_stats_func_alloc(int velocity) { log_mincore_stats_instance.velocity_allocate += velocity; }
116
void log_mincore_stats_func_dealloc(int velocity) { log_mincore_stats_instance.velocity_deallocate += velocity; }
119
log_mincore_stats_func(bool is_incore, bool new_index, bool& continous) {
120
log_file* lf = &log_files[LOG_MINCORE_STATS];
122
if (rak::timer::current().seconds() >= lf->last_update() + 10) {
125
// Log the result of mincore for every piece uploaded to a file.
126
unsigned int buf_length = snprintf(buffer, 256, "%i %u %u %u %u %u %u %u %u %u %u %llu %llu\n",
128
log_mincore_stats_instance.counter_incore,
129
log_mincore_stats_instance.counter_incore_new,
130
log_mincore_stats_instance.counter_not_incore,
131
log_mincore_stats_instance.counter_not_incore_new,
132
log_mincore_stats_instance.counter_incore_break,
133
log_mincore_stats_instance.counter_sync_success,
134
log_mincore_stats_instance.counter_sync_failed,
135
log_mincore_stats_instance.counter_sync_not_synced,
136
log_mincore_stats_instance.counter_sync_not_deallocated,
137
log_mincore_stats_instance.counter_alloc_failed,
138
(long long unsigned int)log_mincore_stats_instance.velocity_allocate,
139
(long long unsigned int)log_mincore_stats_instance.velocity_deallocate);
141
// Add a zero'ed log entry so that graphs will look right after a
142
// long period with no activity.
143
if (rak::timer::current().seconds() >= lf->last_update() + 20)
144
buf_length += snprintf(buffer + buf_length, 256 - buf_length,
145
"%i 0 0 0 0 0 0 0 0 0 0 0 0\n", lf->last_update() + 10);
147
if (rak::timer::current().seconds() >= lf->last_update() + 30)
148
buf_length += snprintf(buffer + buf_length, 256 - buf_length,
149
"%i 0 0 0 0 0 0 0 0 0 0 0 0\n", rak::timer::current().seconds() / 10 * 10 - 10);
151
int __UNUSED result = write(lf->file_descriptor(), buffer, buf_length);
153
lf->set_last_update(rak::timer::current().seconds() / 10 * 10);
154
std::memset(&log_mincore_stats_instance, 0, sizeof(log_mincore_stats));
157
log_mincore_stats_instance.counter_incore += !new_index && is_incore;
158
log_mincore_stats_instance.counter_incore_new += new_index && is_incore;
159
log_mincore_stats_instance.counter_not_incore += !new_index && !is_incore;
160
log_mincore_stats_instance.counter_not_incore_new += new_index && !is_incore;
162
log_mincore_stats_instance.counter_incore_break += continous && !is_incore;
163
continous = is_incore;
167
log_choke_changes_func_new(void* address, const char* title, int quota, int adjust) {
168
log_file* lf = &log_files[LOG_CHOKE_CHANGES];
169
lf->set_last_update(rak::timer::current().seconds());
172
unsigned int buf_length = snprintf(buffer, 256, "%p %i %s %i %i\n",
173
address, lf->last_update(), title, quota, adjust);
175
int __UNUSED result = write(lf->file_descriptor(), buffer, buf_length);
179
log_choke_changes_func_peer(void* address, const char* title, weighted_connection* data) {
180
log_file* lf = &log_files[LOG_CHOKE_CHANGES];
183
unsigned int buf_length = snprintf(buffer, 256, "%p %i %s %p %X %llu %llu\n",
184
address, lf->last_update(), title, data->connection, data->weight,
185
(long long unsigned int)data->connection->up_rate()->rate(),
186
(long long unsigned int)data->connection->down_rate()->rate());
188
int __UNUSED result = write(lf->file_descriptor(), buffer, buf_length);
192
log_choke_changes_func_allocate(void* address, const char* title, unsigned int index, uint32_t count, int dist) {
193
log_file* lf = &log_files[LOG_CHOKE_CHANGES];
196
unsigned int buf_length = snprintf(buffer, 256, "%p %i %s %u %u %i\n",
197
address, lf->last_update(), title, index, count, dist);
199
int __UNUSED result = write(lf->file_descriptor(), buffer, buf_length);