[tor-commits] [metrics-web/master] Allow multiple transports to be displayed at once.
karsten at torproject.org
karsten at torproject.org
Sat Sep 13 06:03:52 UTC 2014
commit 2e474bd7e77d67708c91fce9257ee39cff828082
Author: Karsten Loesing <karsten.loesing at gmx.net>
Date: Tue Sep 9 10:23:48 2014 +0200
Allow multiple transports to be displayed at once.
Implements a feature requested by asn in #12432.
---
website/rserve/graphs.R | 91 +++++++++++++++-----
.../metrics/web/graphs/GraphParameterChecker.java | 8 +-
website/web/WEB-INF/users.jsp | 21 +++--
3 files changed, 87 insertions(+), 33 deletions(-)
diff --git a/website/rserve/graphs.R b/website/rserve/graphs.R
index 68a8b7d..d546127 100644
--- a/website/rserve/graphs.R
+++ b/website/rserve/graphs.R
@@ -795,19 +795,56 @@ plot_userstats <- function(start, end, node, variable, value, events,
u$node == 'relay', ]
title <- "Directly connecting users\n"
}
+ u <- aggregate(list(lower = u$lower, upper = u$upper,
+ users = u$clients),
+ by = list(date = as.Date(u$date, "%Y-%m-%d"),
+ value = u$country),
+ FUN = sum)
} else if (variable == 'transport') {
- if (value != '!<*>') {
- u <- u[u$transport == value & u$node == 'bridge', ]
- title <- paste("Bridge users using transport ", value, "\n",
- sep = "")
+ if ('!<OR>' %in% value) {
+ n <- u[u$transport != '' & u$transport != '<OR>' &
+ u$node == 'bridge', ]
+ n <- aggregate(list(lower = n$lower, upper = n$upper,
+ clients = n$clients),
+ by = list(date = n$date),
+ FUN = sum)
+ u <- rbind(u, data.frame(date = n$date, node = 'bridge',
+ country = '', transport = '!<OR>',
+ version = '', lower = n$lower,
+ upper = n$upper, clients = n$clients,
+ frac = NA))
+ }
+ if (length(value) > 1) {
+ u <- u[u$transport %in% value & u$node == 'bridge', ]
+ u <- aggregate(list(lower = u$lower, upper = u$upper,
+ users = u$clients),
+ by = list(date = as.Date(u$date, "%Y-%m-%d"),
+ value = u$transport),
+ FUN = sum)
+ title <- paste("Bridge users by transport\n")
} else {
- u <- u[u$transport != '' & u$transport != '<OR>' &
- u$node == 'bridge', ]
- title <- paste("Bridge users using any pluggable transport\n")
+ u <- u[u$transport == value & u$node == 'bridge', ]
+ u <- aggregate(list(lower = u$lower, upper = u$upper,
+ users = u$clients),
+ by = list(date = as.Date(u$date, "%Y-%m-%d"),
+ value = u$transport),
+ FUN = sum)
+ title <- paste("Bridge users using ",
+ ifelse(value == '<??>', 'unknown pluggable transport(s)',
+ ifelse(value == '<OR>', 'default OR protocol',
+ ifelse(value == '!<OR>', 'any pluggable transport',
+ ifelse(value == 'fte', 'FTE',
+ ifelse(value == 'websocket', 'Flash proxy/websocket',
+ paste('transport', value)))))), "\n", sep = "")
}
} else if (variable == 'version') {
- u <- u[u$version== value & u$node == 'bridge', ]
+ u <- u[u$version == value & u$node == 'bridge', ]
title <- paste("Bridge users using IP", value, "\n", sep = "")
+ u <- aggregate(list(lower = u$lower, upper = u$upper,
+ users = u$clients),
+ by = list(date = as.Date(u$date, "%Y-%m-%d"),
+ value = u$version),
+ FUN = sum)
} else {
if (value != 'all') {
u <- u[u$country == value & u$node == 'bridge', ]
@@ -818,26 +855,28 @@ plot_userstats <- function(start, end, node, variable, value, events,
u$node == 'bridge', ]
title <- "Bridge users\n"
}
+ u <- aggregate(list(lower = u$lower, upper = u$upper,
+ users = u$clients),
+ by = list(date = as.Date(u$date, "%Y-%m-%d"),
+ value = u$country),
+ FUN = sum)
}
- u <- aggregate(list(lower = u$lower, upper = u$upper,
- users = u$clients),
- by = list(date = as.Date(u$date, "%Y-%m-%d")), FUN = sum)
- dates <- seq(from = as.Date(start, "%Y-%m-%d"),
- to = as.Date(end, "%Y-%m-%d"), by="1 day")
- missing <- setdiff(dates, u$date)
- if (length(missing) > 0) {
- u <- rbind(u,
- data.frame(date = as.Date(missing, origin = "1970-01-01"),
- users = NA, lower = NA, upper = NA))
- }
+ u <- merge(x = u, all.y = TRUE, y = data.frame(expand.grid(
+ date = seq(from = as.Date(start, "%Y-%m-%d"),
+ to = as.Date(end, "%Y-%m-%d"), by="1 day"),
+ value = ifelse(value == 'all', '', value))))
formatter <- function(x, ...) { format(x, scientific = FALSE, ...) }
date_breaks <- date_breaks(
as.numeric(max(u$date) - min(u$date)))
max_y <- ifelse(length(na.omit(u$users)) == 0, 0,
max(u$users, na.rm = TRUE))
- plot <- ggplot(u, aes(x = date, y = users))
+ if (length(value) > 1) {
+ plot <- ggplot(u, aes(x = date, y = users, colour = value))
+ } else {
+ plot <- ggplot(u, aes(x = date, y = users))
+ }
if (length(na.omit(u$users)) > 0 & events != "off" &
- variable == 'country' & value != "all") {
+ variable == 'country' & length(value) == 1 && value != "all") {
upturns <- u[u$users > u$upper, c("date", "users")]
downturns <- u[u$users <= u$lower, c("date", "users")]
if (events == "on") {
@@ -865,6 +904,16 @@ plot_userstats <- function(start, end, node, variable, value, events,
scale_y_continuous(name = "", limits = c(0, max_y),
formatter = formatter) +
opts(title = title)
+ if (length(value) > 1) {
+ plot <- plot +
+ scale_colour_hue(name = "", breaks = value,
+ labels = ifelse(value == '<??>', 'Unknown PT',
+ ifelse(value == '<OR>', 'Default OR protocol',
+ ifelse(value == '!<OR>', 'Any PT',
+ ifelse(value == 'fte', 'FTE',
+ ifelse(value == 'websocket', 'Flash proxy/websocket',
+ value))))))
+ }
ggsave(filename = path, width = 8, height = 5, dpi = 72)
}
diff --git a/website/src/org/torproject/metrics/web/graphs/GraphParameterChecker.java b/website/src/org/torproject/metrics/web/graphs/GraphParameterChecker.java
index ab77943..223a289 100644
--- a/website/src/org/torproject/metrics/web/graphs/GraphParameterChecker.java
+++ b/website/src/org/torproject/metrics/web/graphs/GraphParameterChecker.java
@@ -59,7 +59,7 @@ public class GraphParameterChecker {
this.knownParameterValues.put("source", "all,siv,moria,torperf");
this.knownParameterValues.put("filesize", "50kb,1mb,5mb");
this.knownParameterValues.put("transport",
- "obfs2,obfs3,websocket,fte,meek,scramblesuit,<OR>,<??>,!<*>");
+ "obfs2,obfs3,websocket,fte,meek,scramblesuit,<OR>,<??>,!<OR>");
this.knownParameterValues.put("version", "v4,v6");
this.knownParameterValues.put("p", "100,99,98,97,95,91,90,80,75,70,"
+ "60,50,40,30,25,20,10,9,5,3,2,1,0");
@@ -161,6 +161,9 @@ public class GraphParameterChecker {
List<String> knownCountries = Arrays.asList(
this.knownParameterValues.get("country").split(","));
if (countryParameters != null) {
+ if (countryParameters.length != 1) {
+ return null;
+ }
for (String country : countryParameters) {
if (country == null || country.length() == 0 ||
!knownCountries.contains(country)) {
@@ -265,6 +268,9 @@ public class GraphParameterChecker {
List<String> knownVersions = Arrays.asList(
this.knownParameterValues.get("version").split(","));
if (versionParameters != null) {
+ if (versionParameters.length != 1) {
+ return null;
+ }
for (String version : versionParameters) {
if (version == null || version.length() == 0 ||
!knownVersions.contains(version)) {
diff --git a/website/web/WEB-INF/users.jsp b/website/web/WEB-INF/users.jsp
index 400fd31..04eeaf9 100644
--- a/website/web/WEB-INF/users.jsp
+++ b/website/web/WEB-INF/users.jsp
@@ -232,17 +232,16 @@ Bridge users by transport:
<input type="text" name="end" size="10"
value="<c:choose><c:when test="${fn:length(userstats_bridge_transport_end) == 0}">${default_end_date}</c:when><c:otherwise>${userstats_bridge_transport_end[0]}</c:otherwise></c:choose>">
</p><p>
- Source: <select name="transport">
- <option value="<OR>"<c:if test="${userstats_bridge_transport_transport[0] eq '<OR>'}"> selected</c:if>>Default OR protocol</option>
- <option value="obfs2"<c:if test="${userstats_bridge_transport_transport[0] eq 'obfs2'}"> selected</c:if>>obfs2</option>
- <option value="obfs3"<c:if test="${userstats_bridge_transport_transport[0] eq 'obfs3'}"> selected</c:if>>obfs3</option>
- <option value="websocket"<c:if test="${userstats_bridge_transport_transport[0] eq 'websocket'}"> selected</c:if>>Flash proxy/websocket</option>
- <option value="fte"<c:if test="${userstats_bridge_transport_transport[0] eq 'fte'}"> selected</c:if>>FTE</option>
- <option value="meek"<c:if test="${userstats_bridge_transport_transport[0] eq 'meek'}"> selected</c:if>>meek</option>
- <option value="scramblesuit"<c:if test="${userstats_bridge_transport_transport[0] eq 'scramblesuit'}"> selected</c:if>>scramblesuit</option>
- <option value="<??>"<c:if test="${userstats_bridge_transport_transport[0] eq '<??>'}"> selected</c:if>>Unknown transport</option>
- <option value="!<*>"<c:if test="${userstats_bridge_transport_transport[0] eq '!<*>'}"> selected</c:if>>Any non-OR transport</option>
- </select>
+ <label>Source: </label>
+ <input type="checkbox" name="transport" value="<OR>"<c:if test="${fn:length(userstats_bridge_transport_transport) == 0 or fn:contains(fn:join(userstats_bridge_transport_transport, ','), '<OR>')}"> checked</c:if>> Default OR protocol
+ <input type="checkbox" name="transport" value="obfs2"<c:if test="${fn:length(userstats_bridge_transport_transport) > 0 and fn:contains(fn:join(userstats_bridge_transport_transport, ','), 'obfs2')}"> checked</c:if>> obfs2
+ <input type="checkbox" name="transport" value="obfs3"<c:if test="${fn:length(userstats_bridge_transport_transport) > 0 and fn:contains(fn:join(userstats_bridge_transport_transport, ','), 'obfs3')}"> checked</c:if>> obfs3
+ <input type="checkbox" name="transport" value="websocket"<c:if test="${fn:length(userstats_bridge_transport_transport) > 0 and fn:contains(fn:join(userstats_bridge_transport_transport, ','), 'websocket')}"> checked</c:if>> Flash proxy/websocket
+ <input type="checkbox" name="transport" value="fte"<c:if test="${fn:length(userstats_bridge_transport_transport) > 0 and fn:contains(fn:join(userstats_bridge_transport_transport, ','), 'fte')}"> checked</c:if>> FTE
+ <input type="checkbox" name="transport" value="meek"<c:if test="${fn:length(userstats_bridge_transport_transport) > 0 and fn:contains(fn:join(userstats_bridge_transport_transport, ','), 'meek')}"> checked</c:if>> meek
+ <input type="checkbox" name="transport" value="scramblesuit"<c:if test="${fn:length(userstats_bridge_transport_transport) > 0 and fn:contains(fn:join(userstats_bridge_transport_transport, ','), 'scramblesuit')}"> checked</c:if>> scramblesuit
+ <input type="checkbox" name="transport" value="<??>"<c:if test="${fn:length(userstats_bridge_transport_transport) > 0 and fn:contains(fn:join(userstats_bridge_transport_transport, ','), '<??>')}"> checked</c:if>> Unknown pluggable transport(s)
+ <input type="checkbox" name="transport" value="!<OR>"<c:if test="${fn:length(userstats_bridge_transport_transport) > 0 and fn:contains(fn:join(userstats_bridge_transport_transport, ','), '!<OR>')}"> checked</c:if>> Any pluggable transport
</p><p>
<input class="submit" type="submit" value="Update graph">
</p>
More information about the tor-commits
mailing list