state(Client::READING_REQUEST),
stream(NULL),
header_or_error_bytes_sent(0),
- stream_pos(0)
+ stream_pos(0),
+ bytes_sent(0),
+ bytes_lost(0),
+ num_loss_events(0)
{
request.reserve(1024);
stream(stream),
header_or_error(serialized.header_or_error()),
header_or_error_bytes_sent(serialized.header_or_error_bytes_sent()),
- stream_pos(serialized.stream_pos())
+ stream_pos(serialized.stream_pos()),
+ bytes_sent(serialized.bytes_sent()),
+ bytes_lost(serialized.bytes_lost()),
+ num_loss_events(serialized.num_loss_events())
{
if (stream != NULL && stream->mark_pool != NULL) {
fwmark = stream->mark_pool->get_mark();
serialized.set_header_or_error(header_or_error);
serialized.set_header_or_error_bytes_sent(serialized.header_or_error_bytes_sent());
serialized.set_stream_pos(stream_pos);
+ serialized.set_bytes_sent(bytes_sent);
+ serialized.set_bytes_lost(bytes_lost);
+ serialized.set_num_loss_events(num_loss_events);
return serialized;
}
stats.stream_id = stream_id;
stats.remote_addr = remote_addr;
stats.connect_time = connect_time;
- stats.bytes_sent = stream_pos;
+ stats.bytes_sent = bytes_sent;
+ stats.bytes_lost = bytes_lost;
+ stats.num_loss_events = num_loss_events;
return stats;
}
std::string remote_addr;
time_t connect_time;
size_t bytes_sent;
+ size_t bytes_lost;
+ size_t num_loss_events;
};
struct Client {
// Number of bytes we are into the stream (ie., the end of last send).
// Only relevant for SENDING_DATA.
size_t stream_pos;
+
+ // Number of bytes we've sent of data. Only relevant for SENDING_DATA.
+ size_t bytes_sent;
+
+ // Number of times we've skipped forward due to the backlog being too big,
+ // and how many bytes we've skipped over in all. Only relevant for SENDING_DATA.
+ size_t bytes_lost, num_loss_events;
};
#endif // !defined(_CLIENT_H)
client->sock,
(long long int)(bytes_to_send - stream->backlog_size));
client->stream_pos = stream->bytes_received - stream->backlog_size;
+ client->bytes_lost += bytes_to_send - stream->backlog_size;
+ ++client->num_loss_events;
bytes_to_send = stream->backlog_size;
}
return;
}
client->stream_pos += ret;
+ client->bytes_sent += ret;
if (client->stream_pos == stream->bytes_received) {
// We don't have any more data for this client, so put it to sleep.
optional bytes header_or_error = 5;
optional int64 header_or_error_bytes_sent = 6;
optional int64 stream_pos = 7;
+ optional int64 bytes_sent = 10;
+ optional int64 bytes_lost = 11;
+ optional int64 num_loss_events = 12;
};
// Corresponds to struct Stream.
now = time(NULL);
client_stats = servers->get_client_stats();
for (size_t i = 0; i < client_stats.size(); ++i) {
- fprintf(fp, "%s %s %d %llu\n",
+ fprintf(fp, "%s %s %d %llu %llu %llu\n",
client_stats[i].remote_addr.c_str(),
client_stats[i].stream_id.c_str(),
int(now - client_stats[i].connect_time),
- (long long unsigned)(client_stats[i].bytes_sent));
+ (long long unsigned)(client_stats[i].bytes_sent),
+ (long long unsigned)(client_stats[i].bytes_lost),
+ (long long unsigned)(client_stats[i].num_loss_events));
}
if (fclose(fp) == EOF) {
perror("fclose");