added stats_alert reporting raw transfer stats per torrent every second
This commit is contained in:
@@ -406,5 +406,24 @@ void bind_alert()
|
|||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
class_<stats_alert, bases<torrent_alert>, noncopyable>(
|
||||||
|
"stats_alert", no_init
|
||||||
|
)
|
||||||
|
.def_readonly("transferred", &stats_alert::transferred)
|
||||||
|
.def_readonly("interval", &stats_alert::interval)
|
||||||
|
;
|
||||||
|
|
||||||
|
enum_<stats_alert::stats_channel>("stats_channel")
|
||||||
|
.value("upload_payload", stats_alert::upload_payload)
|
||||||
|
.value("upload_protocol", stats_alert::upload_protocol)
|
||||||
|
.value("upload_ip_protocol", stats_alert::upload_ip_protocol)
|
||||||
|
.value("upload_dht_protocol", stats_alert::upload_dht_protocol)
|
||||||
|
.value("upload_tracker_protocol", stats_alert::upload_tracker_protocol)
|
||||||
|
.value("download_payload", stats_alert::download_payload)
|
||||||
|
.value("download_protocol", stats_alert::download_protocol)
|
||||||
|
.value("download_ip_protocol", stats_alert::download_ip_protocol)
|
||||||
|
.value("download_dht_protocol", stats_alert::download_dht_protocol)
|
||||||
|
.value("download_tracker_protocol", stats_alert::download_tracker_protocol)
|
||||||
|
;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -4748,6 +4748,11 @@ is a bitmask with the following bits:
|
|||||||
| ``performance_warning`` | Alerts when some limit is reached that might limit the download |
|
| ``performance_warning`` | Alerts when some limit is reached that might limit the download |
|
||||||
| | or upload rate. |
|
| | or upload rate. |
|
||||||
+--------------------------------+---------------------------------------------------------------------+
|
+--------------------------------+---------------------------------------------------------------------+
|
||||||
|
| ``stats_notification`` | If you enable these alerts, you will receive a ``stats_alert`` |
|
||||||
|
| | approximately once every second, for every active torrent. |
|
||||||
|
| | These alerts contain all statistics counters for the interval since |
|
||||||
|
| | the lasts stats alert. |
|
||||||
|
+--------------------------------+---------------------------------------------------------------------+
|
||||||
| ``all_categories`` | The full bitmask, representing all available categories. |
|
| ``all_categories`` | The full bitmask, representing all available categories. |
|
||||||
+--------------------------------+---------------------------------------------------------------------+
|
+--------------------------------+---------------------------------------------------------------------+
|
||||||
|
|
||||||
@@ -5646,6 +5651,45 @@ generating the resume data. ``error`` describes what went wrong.
|
|||||||
error_code error;
|
error_code error;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
stats_alert
|
||||||
|
-----------
|
||||||
|
|
||||||
|
This alert is posted approximately once every second, and it contains
|
||||||
|
byte counters of most statistics that's tracked for torrents. Each active
|
||||||
|
torrent posts these alerts regularly.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
struct stats_alert: torrent_alert
|
||||||
|
{
|
||||||
|
// ...
|
||||||
|
enum stats_channel
|
||||||
|
{
|
||||||
|
upload_payload,
|
||||||
|
upload_protocol,
|
||||||
|
upload_ip_protocol,
|
||||||
|
upload_dht_protocol,
|
||||||
|
upload_tracker_protocol,
|
||||||
|
download_payload,
|
||||||
|
download_protocol,
|
||||||
|
download_ip_protocol,
|
||||||
|
download_dht_protocol,
|
||||||
|
download_tracker_protocol,
|
||||||
|
num_channels
|
||||||
|
};
|
||||||
|
|
||||||
|
int transferred[num_channels];
|
||||||
|
int interval;
|
||||||
|
};
|
||||||
|
|
||||||
|
``transferred`` this is an array of samples. The enum describes what each
|
||||||
|
sample is a measurement of. All of these are raw, and not smoothing is performed.
|
||||||
|
|
||||||
|
``interval`` the number of milliseconds during which these stats
|
||||||
|
were collected. This is typically just above 1000, but if CPU is
|
||||||
|
limited, it may be higher than that.
|
||||||
|
|
||||||
|
|
||||||
dht_announce_alert
|
dht_announce_alert
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
@@ -86,6 +86,7 @@ namespace libtorrent {
|
|||||||
ip_block_notification = 0x100,
|
ip_block_notification = 0x100,
|
||||||
performance_warning = 0x200,
|
performance_warning = 0x200,
|
||||||
dht_notification = 0x400,
|
dht_notification = 0x400,
|
||||||
|
stats_notification = 0x800,
|
||||||
|
|
||||||
all_categories = 0xffffffff
|
all_categories = 0xffffffff
|
||||||
};
|
};
|
||||||
|
@@ -40,6 +40,16 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "libtorrent/assert.hpp"
|
#include "libtorrent/assert.hpp"
|
||||||
#include "libtorrent/identify_client.hpp"
|
#include "libtorrent/identify_client.hpp"
|
||||||
#include "libtorrent/address.hpp"
|
#include "libtorrent/address.hpp"
|
||||||
|
#include "libtorrent/stat.hpp"
|
||||||
|
|
||||||
|
// lines reserved for future includes
|
||||||
|
// the type-ids of the alert types
|
||||||
|
// are derived from the line on which
|
||||||
|
// they are declared
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
@@ -1078,6 +1088,36 @@ namespace libtorrent
|
|||||||
|
|
||||||
sha1_hash info_hash;
|
sha1_hash info_hash;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TORRENT_EXPORT stats_alert: torrent_alert
|
||||||
|
{
|
||||||
|
stats_alert(torrent_handle const& h, int interval
|
||||||
|
, stat const& s);
|
||||||
|
|
||||||
|
TORRENT_DEFINE_ALERT(stats_alert);
|
||||||
|
|
||||||
|
const static int static_category = alert::stats_notification;
|
||||||
|
virtual std::string message() const;
|
||||||
|
|
||||||
|
enum stats_channel
|
||||||
|
{
|
||||||
|
upload_payload,
|
||||||
|
upload_protocol,
|
||||||
|
upload_ip_protocol,
|
||||||
|
upload_dht_protocol,
|
||||||
|
upload_tracker_protocol,
|
||||||
|
download_payload,
|
||||||
|
download_protocol,
|
||||||
|
download_ip_protocol,
|
||||||
|
download_dht_protocol,
|
||||||
|
download_tracker_protocol,
|
||||||
|
num_channels
|
||||||
|
};
|
||||||
|
|
||||||
|
int transferred[num_channels];
|
||||||
|
int interval;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -52,13 +52,16 @@ namespace libtorrent
|
|||||||
enum { history = 10 };
|
enum { history = 10 };
|
||||||
|
|
||||||
stat_channel()
|
stat_channel()
|
||||||
: m_counter(0)
|
: m_window(3)
|
||||||
|
, m_counter(0)
|
||||||
, m_total_counter(0)
|
, m_total_counter(0)
|
||||||
, m_rate_sum(0)
|
, m_rate_sum(0)
|
||||||
{
|
{
|
||||||
std::memset(m_rate_history, 0, sizeof(m_rate_history));
|
std::memset(m_rate_history, 0, sizeof(m_rate_history));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_window(int w);
|
||||||
|
|
||||||
void operator+=(stat_channel const& s)
|
void operator+=(stat_channel const& s)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(m_counter >= 0);
|
TORRENT_ASSERT(m_counter >= 0);
|
||||||
@@ -82,7 +85,7 @@ namespace libtorrent
|
|||||||
|
|
||||||
// should be called once every second
|
// should be called once every second
|
||||||
void second_tick(int tick_interval_ms);
|
void second_tick(int tick_interval_ms);
|
||||||
int rate() const { return int(m_rate_sum / history); }
|
int rate() const { return int(m_rate_sum / m_window); }
|
||||||
size_type rate_sum() const { return m_rate_sum; }
|
size_type rate_sum() const { return m_rate_sum; }
|
||||||
size_type total() const { return m_total_counter; }
|
size_type total() const { return m_total_counter; }
|
||||||
|
|
||||||
@@ -104,13 +107,15 @@ namespace libtorrent
|
|||||||
m_rate_sum = 0;
|
m_rate_sum = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int window() const { return m_window; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
#ifdef TORRENT_DEBUG
|
#ifdef TORRENT_DEBUG
|
||||||
void check_invariant() const
|
void check_invariant() const
|
||||||
{
|
{
|
||||||
size_type sum = 0;
|
size_type sum = 0;
|
||||||
for (int i = 0; i < history; ++i) sum += m_rate_history[i];
|
for (int i = 0; i < m_window; ++i) sum += m_rate_history[i];
|
||||||
TORRENT_ASSERT(m_rate_sum == sum);
|
TORRENT_ASSERT(m_rate_sum == sum);
|
||||||
TORRENT_ASSERT(m_total_counter >= 0);
|
TORRENT_ASSERT(m_total_counter >= 0);
|
||||||
}
|
}
|
||||||
@@ -119,6 +124,9 @@ namespace libtorrent
|
|||||||
// history of rates a few seconds back
|
// history of rates a few seconds back
|
||||||
int m_rate_history[history];
|
int m_rate_history[history];
|
||||||
|
|
||||||
|
// averaging window (seconds). 'history' is the max size
|
||||||
|
int m_window;
|
||||||
|
|
||||||
// the accumulator for this second.
|
// the accumulator for this second.
|
||||||
int m_counter;
|
int m_counter;
|
||||||
|
|
||||||
@@ -216,6 +224,12 @@ namespace libtorrent
|
|||||||
int download_tracker() const { return m_stat[download_tracker_protocol].counter(); }
|
int download_tracker() const { return m_stat[download_tracker_protocol].counter(); }
|
||||||
int upload_tracker() const { return m_stat[upload_tracker_protocol].counter(); }
|
int upload_tracker() const { return m_stat[upload_tracker_protocol].counter(); }
|
||||||
|
|
||||||
|
void set_window(int w)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < num_channels; ++i)
|
||||||
|
m_stat[i].set_window(w);
|
||||||
|
}
|
||||||
|
|
||||||
// should be called once every second
|
// should be called once every second
|
||||||
void second_tick(int tick_interval_ms)
|
void second_tick(int tick_interval_ms)
|
||||||
{
|
{
|
||||||
@@ -229,7 +243,7 @@ namespace libtorrent
|
|||||||
+ m_stat[upload_protocol].rate_sum()
|
+ m_stat[upload_protocol].rate_sum()
|
||||||
+ m_stat[upload_ip_protocol].rate_sum()
|
+ m_stat[upload_ip_protocol].rate_sum()
|
||||||
+ m_stat[upload_dht_protocol].rate_sum())
|
+ m_stat[upload_dht_protocol].rate_sum())
|
||||||
/ stat_channel::history);
|
/ m_stat[0].window());
|
||||||
}
|
}
|
||||||
|
|
||||||
int download_rate() const
|
int download_rate() const
|
||||||
@@ -238,7 +252,7 @@ namespace libtorrent
|
|||||||
+ m_stat[download_protocol].rate_sum()
|
+ m_stat[download_protocol].rate_sum()
|
||||||
+ m_stat[download_ip_protocol].rate_sum()
|
+ m_stat[download_ip_protocol].rate_sum()
|
||||||
+ m_stat[download_dht_protocol].rate_sum())
|
+ m_stat[download_dht_protocol].rate_sum())
|
||||||
/ stat_channel::history);
|
/ m_stat[0].window());
|
||||||
}
|
}
|
||||||
|
|
||||||
size_type total_upload() const
|
size_type total_upload() const
|
||||||
@@ -319,6 +333,12 @@ namespace libtorrent
|
|||||||
m_stat[i].clear();
|
m_stat[i].clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stat_channel const& operator[](int i) const
|
||||||
|
{
|
||||||
|
TORRENT_ASSERT(i >= 0 && i < num_channels);
|
||||||
|
return m_stat[i];
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
stat_channel m_stat[num_channels];
|
stat_channel m_stat[num_channels];
|
||||||
|
@@ -433,5 +433,33 @@ namespace libtorrent {
|
|||||||
return queue_size_limit_;
|
return queue_size_limit_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stats_alert::stats_alert(torrent_handle const& h, int in
|
||||||
|
, stat const& s)
|
||||||
|
: torrent_alert(h)
|
||||||
|
, interval(in)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < num_channels; ++i)
|
||||||
|
transferred[i] = s[i].counter();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string stats_alert::message() const
|
||||||
|
{
|
||||||
|
char msg[200];
|
||||||
|
snprintf(msg, sizeof(msg), "%s: [%d] %d %d %d %d %d %d %d %d %d %d"
|
||||||
|
, torrent_alert::message().c_str()
|
||||||
|
, interval
|
||||||
|
, transferred[0]
|
||||||
|
, transferred[1]
|
||||||
|
, transferred[2]
|
||||||
|
, transferred[3]
|
||||||
|
, transferred[4]
|
||||||
|
, transferred[5]
|
||||||
|
, transferred[6]
|
||||||
|
, transferred[7]
|
||||||
|
, transferred[8]
|
||||||
|
, transferred[9]);
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace libtorrent
|
} // namespace libtorrent
|
||||||
|
|
||||||
|
20
src/stat.cpp
20
src/stat.cpp
@@ -30,11 +30,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// TODO: Use two algorithms to estimate transfer rate.
|
|
||||||
// one (simple) for transfer rates that are >= 1 packet
|
|
||||||
// per second and one (low pass-filter) for rates < 1
|
|
||||||
// packet per second.
|
|
||||||
|
|
||||||
#include "libtorrent/pch.hpp"
|
#include "libtorrent/pch.hpp"
|
||||||
|
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
@@ -43,14 +38,13 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "libtorrent/stat.hpp"
|
#include "libtorrent/stat.hpp"
|
||||||
#include "libtorrent/invariant_check.hpp"
|
#include "libtorrent/invariant_check.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent {
|
||||||
{
|
|
||||||
|
|
||||||
void stat_channel::second_tick(int tick_interval_ms)
|
void stat_channel::second_tick(int tick_interval_ms)
|
||||||
{
|
{
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
m_rate_sum -= m_rate_history[history-1];
|
m_rate_sum -= m_rate_history[m_window-1];
|
||||||
|
|
||||||
for (int i = history - 2; i >= 0; --i)
|
for (int i = history - 2; i >= 0; --i)
|
||||||
m_rate_history[i + 1] = m_rate_history[i];
|
m_rate_history[i + 1] = m_rate_history[i];
|
||||||
@@ -61,6 +55,16 @@ void stat_channel::second_tick(int tick_interval_ms)
|
|||||||
m_counter = 0;
|
m_counter = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void stat_channel::set_window(int w)
|
||||||
|
{
|
||||||
|
if (w < 1) w = 1;
|
||||||
|
else if (w > history) w = history;
|
||||||
|
m_window = w;
|
||||||
|
m_rate_sum = 0;
|
||||||
|
for (int i = 0; i < m_window; ++i)
|
||||||
|
m_rate_sum += m_rate_history[i];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -5456,6 +5456,9 @@ namespace libtorrent
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
if (m_ses.m_alerts.should_post<stats_alert>())
|
||||||
|
m_ses.m_alerts.post_alert(stats_alert(get_handle(), tick_interval_ms, m_stat));
|
||||||
|
|
||||||
accumulator += m_stat;
|
accumulator += m_stat;
|
||||||
m_total_uploaded += m_stat.last_payload_uploaded();
|
m_total_uploaded += m_stat.last_payload_uploaded();
|
||||||
m_total_downloaded += m_stat.last_payload_downloaded();
|
m_total_downloaded += m_stat.last_payload_downloaded();
|
||||||
|
Reference in New Issue
Block a user