mirror of https://github.com/dswd/vpncloud.git
Fixed statsd support
This commit is contained in:
parent
1f94d0deff
commit
cac5af890b
68
src/cloud.rs
68
src/cloud.rs
|
@ -28,7 +28,7 @@ use super::{
|
|||
traffic::TrafficStats,
|
||||
types::{Error, HeaderMagic, NodeId, Protocol, Range, Table},
|
||||
udpmessage::{decode, encode, Message},
|
||||
util::{addr_nice, resolve, CtrlC, Duration, Time, TimeSource}
|
||||
util::{addr_nice, resolve, CtrlC, Duration, StatsdMsg, Time, TimeSource}
|
||||
};
|
||||
|
||||
pub type Hash = BuildHasherDefault<FnvHasher>;
|
||||
|
@ -600,35 +600,43 @@ impl<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSource> GenericCloud<D
|
|||
let peer_traffic = self.traffic.total_peer_traffic();
|
||||
let payload_traffic = self.traffic.total_payload_traffic();
|
||||
let dropped = &self.traffic.dropped;
|
||||
let msg = format!(
|
||||
"peer_count:{}|g\ntable_entries:{}|g\n\
|
||||
traffic.protocol.inbound.bytes:{}\n\
|
||||
traffic.protocol.inbound.packets:{}\n\
|
||||
traffic.protocol.outbound.bytes:{}\n\
|
||||
traffic.protocol.outbound.packets:{}\n\
|
||||
traffic.payload.inbound.bytes:{}\n\
|
||||
traffic.payload.inbound.packets:{}\n\
|
||||
traffic.payload.outbound.bytes:{}\n\
|
||||
traffic.payload.outbound.packets:{}\n\
|
||||
invalid_protocol_traffic.bytes:{}\n\
|
||||
invalid_protocol_traffic.packets:{}\n\
|
||||
dropped_payload.bytes:{}\n\
|
||||
dropped_payload.packets:{}",
|
||||
self.peers.len(),
|
||||
self.table.len(),
|
||||
peer_traffic.in_bytes,
|
||||
peer_traffic.in_packets,
|
||||
peer_traffic.out_bytes,
|
||||
peer_traffic.out_packets,
|
||||
payload_traffic.in_bytes,
|
||||
payload_traffic.in_packets,
|
||||
payload_traffic.out_bytes,
|
||||
payload_traffic.out_packets,
|
||||
dropped.in_bytes,
|
||||
dropped.in_packets,
|
||||
dropped.out_bytes,
|
||||
dropped.out_packets
|
||||
);
|
||||
let prefix = self.config.statsd_prefix.as_ref().map(|s| s as &str).unwrap_or("vpncloud");
|
||||
let msg = StatsdMsg::new()
|
||||
.with_ns(prefix, |msg| {
|
||||
msg.add("peer_count", self.peers.len(), "g");
|
||||
msg.add("table_entries", self.table.len(), "g");
|
||||
msg.with_ns("traffic", |msg| {
|
||||
msg.with_ns("protocol", |msg| {
|
||||
msg.with_ns("inbound", |msg| {
|
||||
msg.add("bytes", peer_traffic.in_bytes, "c");
|
||||
msg.add("packets", peer_traffic.in_packets, "c");
|
||||
});
|
||||
msg.with_ns("outbound", |msg| {
|
||||
msg.add("bytes", peer_traffic.out_bytes, "c");
|
||||
msg.add("packets", peer_traffic.out_packets, "c");
|
||||
});
|
||||
});
|
||||
msg.with_ns("payload", |msg| {
|
||||
msg.with_ns("inbound", |msg| {
|
||||
msg.add("bytes", payload_traffic.in_bytes, "c");
|
||||
msg.add("packets", payload_traffic.in_packets, "c");
|
||||
});
|
||||
msg.with_ns("outbound", |msg| {
|
||||
msg.add("bytes", payload_traffic.out_bytes, "c");
|
||||
msg.add("packets", payload_traffic.out_packets, "c");
|
||||
});
|
||||
});
|
||||
});
|
||||
msg.with_ns("invalid_protocol_traffic", |msg| {
|
||||
msg.add("bytes", dropped.in_bytes, "c");
|
||||
msg.add("packets", dropped.in_packets, "c");
|
||||
});
|
||||
msg.with_ns("dropped_payload", |msg| {
|
||||
msg.add("bytes", dropped.out_bytes, "c");
|
||||
msg.add("packets", dropped.out_packets, "c");
|
||||
});
|
||||
})
|
||||
.build();
|
||||
let msg_data = msg.as_bytes();
|
||||
let addrs = resolve(endpoint)?;
|
||||
if let Some(addr) = addrs.first() {
|
||||
|
|
|
@ -59,6 +59,7 @@ pub struct Config {
|
|||
pub pid_file: Option<String>,
|
||||
pub stats_file: Option<String>,
|
||||
pub statsd_server: Option<String>,
|
||||
pub statsd_prefix: Option<String>,
|
||||
pub user: Option<String>,
|
||||
pub group: Option<String>
|
||||
}
|
||||
|
@ -89,6 +90,7 @@ impl Default for Config {
|
|||
pid_file: None,
|
||||
stats_file: None,
|
||||
statsd_server: None,
|
||||
statsd_prefix: None,
|
||||
user: None,
|
||||
group: None
|
||||
}
|
||||
|
@ -168,6 +170,9 @@ impl Config {
|
|||
if let Some(val) = file.statsd_server {
|
||||
self.statsd_server = Some(val);
|
||||
}
|
||||
if let Some(val) = file.statsd_prefix {
|
||||
self.statsd_prefix = Some(val);
|
||||
}
|
||||
if let Some(val) = file.user {
|
||||
self.user = Some(val);
|
||||
}
|
||||
|
@ -246,6 +251,9 @@ impl Config {
|
|||
if let Some(val) = args.statsd_server {
|
||||
self.statsd_server = Some(val);
|
||||
}
|
||||
if let Some(val) = args.statsd_prefix {
|
||||
self.statsd_prefix = Some(val);
|
||||
}
|
||||
if let Some(val) = args.user {
|
||||
self.user = Some(val);
|
||||
}
|
||||
|
@ -307,6 +315,7 @@ pub struct ConfigFile {
|
|||
pub pid_file: Option<String>,
|
||||
pub stats_file: Option<String>,
|
||||
pub statsd_server: Option<String>,
|
||||
pub statsd_prefix: Option<String>,
|
||||
pub user: Option<String>,
|
||||
pub group: Option<String>
|
||||
}
|
||||
|
@ -342,6 +351,7 @@ group: nogroup
|
|||
pid_file: /run/vpncloud.run
|
||||
stats_file: /var/log/vpncloud.stats
|
||||
statsd_server: example.com:1234
|
||||
statsd_prefix: prefix
|
||||
";
|
||||
assert_eq!(serde_yaml::from_str::<ConfigFile>(config_file).unwrap(), ConfigFile {
|
||||
device_type: Some(Type::Tun),
|
||||
|
@ -368,7 +378,8 @@ statsd_server: example.com:1234
|
|||
group: Some("nogroup".to_string()),
|
||||
pid_file: Some("/run/vpncloud.run".to_string()),
|
||||
stats_file: Some("/var/log/vpncloud.stats".to_string()),
|
||||
statsd_server: Some("example.com:1234".to_string())
|
||||
statsd_server: Some("example.com:1234".to_string()),
|
||||
statsd_prefix: Some("prefix".to_string())
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -400,7 +411,8 @@ fn config_merge() {
|
|||
group: Some("nogroup".to_string()),
|
||||
pid_file: Some("/run/vpncloud.run".to_string()),
|
||||
stats_file: Some("/var/log/vpncloud.stats".to_string()),
|
||||
statsd_server: Some("example.com:1234".to_string())
|
||||
statsd_server: Some("example.com:1234".to_string()),
|
||||
statsd_prefix: Some("prefix".to_string())
|
||||
});
|
||||
assert_eq!(config, Config {
|
||||
device_type: Type::Tun,
|
||||
|
@ -427,6 +439,7 @@ fn config_merge() {
|
|||
pid_file: Some("/run/vpncloud.run".to_string()),
|
||||
stats_file: Some("/var/log/vpncloud.stats".to_string()),
|
||||
statsd_server: Some("example.com:1234".to_string()),
|
||||
statsd_prefix: Some("prefix".to_string()),
|
||||
..Default::default()
|
||||
});
|
||||
config.merge_args(Args {
|
||||
|
@ -453,6 +466,7 @@ fn config_merge() {
|
|||
pid_file: Some("/run/vpncloud-mynet.run".to_string()),
|
||||
stats_file: Some("/var/log/vpncloud-mynet.stats".to_string()),
|
||||
statsd_server: Some("example.com:2345".to_string()),
|
||||
statsd_prefix: Some("prefix2".to_string()),
|
||||
user: Some("root".to_string()),
|
||||
group: Some("root".to_string()),
|
||||
..Default::default()
|
||||
|
@ -486,6 +500,7 @@ fn config_merge() {
|
|||
pid_file: Some("/run/vpncloud-mynet.run".to_string()),
|
||||
stats_file: Some("/var/log/vpncloud-mynet.stats".to_string()),
|
||||
statsd_server: Some("example.com:2345".to_string()),
|
||||
statsd_prefix: Some("prefix2".to_string()),
|
||||
daemonize: true
|
||||
});
|
||||
}
|
||||
|
|
|
@ -173,6 +173,10 @@ pub struct Args {
|
|||
#[structopt(long)]
|
||||
statsd_server: Option<String>,
|
||||
|
||||
/// Use the given prefix for statsd records
|
||||
#[structopt(long)]
|
||||
statsd_prefix: Option<String>,
|
||||
|
||||
/// Run as other user
|
||||
#[structopt(long)]
|
||||
user: Option<String>,
|
||||
|
|
|
@ -10,7 +10,7 @@ use std::{
|
|||
};
|
||||
|
||||
use super::{
|
||||
cloud::Hash,
|
||||
cloud::{Hash, STATS_INTERVAL},
|
||||
types::Address,
|
||||
util::{addr_nice, Bytes}
|
||||
};
|
||||
|
@ -157,10 +157,10 @@ impl TrafficStats {
|
|||
out,
|
||||
" - peer: \"{}\"\n in: {{ display: \"{}/s\", bytes: {}, packets: {} }}\n out: {{ display: \"{}/s\", bytes: {}, packets: {} }}",
|
||||
addr_nice(**addr),
|
||||
Bytes(data.in_bytes / 60),
|
||||
Bytes(data.in_bytes / STATS_INTERVAL as u64),
|
||||
data.in_bytes,
|
||||
data.in_packets,
|
||||
Bytes(data.out_bytes / 60),
|
||||
Bytes(data.out_bytes / STATS_INTERVAL as u64),
|
||||
data.out_bytes,
|
||||
data.out_packets
|
||||
)?;
|
||||
|
@ -175,10 +175,10 @@ impl TrafficStats {
|
|||
" - addrs: [\"{}\", \"{}\"]\n in: {{ display: \"{}/s\", bytes: {}, packets: {} }}\n out: {{ display: \"{}/s\", bytes: {}, packets: {} }}",
|
||||
remote,
|
||||
local,
|
||||
Bytes(data.in_bytes / 60),
|
||||
Bytes(data.in_bytes / STATS_INTERVAL as u64),
|
||||
data.in_bytes,
|
||||
data.in_packets,
|
||||
Bytes(data.out_bytes / 60),
|
||||
Bytes(data.out_bytes / STATS_INTERVAL as u64),
|
||||
data.out_bytes,
|
||||
data.out_packets
|
||||
)?;
|
||||
|
@ -187,14 +187,14 @@ impl TrafficStats {
|
|||
writeln!(
|
||||
out,
|
||||
"invalid_protocol_traffic: {{ display: \"{}/s\", bytes: {}, packets: {} }}",
|
||||
Bytes(self.dropped.in_bytes / 60),
|
||||
Bytes(self.dropped.in_bytes / STATS_INTERVAL as u64),
|
||||
self.dropped.in_bytes,
|
||||
self.dropped.in_packets
|
||||
)?;
|
||||
writeln!(
|
||||
out,
|
||||
"dropped_payload_traffic: {{ display: \"{}/s\", bytes: {}, packets: {} }}",
|
||||
Bytes(self.dropped.out_bytes / 60),
|
||||
Bytes(self.dropped.out_bytes / STATS_INTERVAL as u64),
|
||||
self.dropped.out_bytes,
|
||||
self.dropped.out_packets
|
||||
)?;
|
||||
|
|
|
@ -228,6 +228,9 @@ pub trait Table {
|
|||
fn remove(&mut self, _: &Address) -> bool;
|
||||
fn remove_all(&mut self, _: &SocketAddr);
|
||||
fn len(&self) -> usize;
|
||||
fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Protocol: Sized {
|
||||
|
|
29
src/util.rs
29
src/util.rs
|
@ -319,6 +319,35 @@ pub fn from_base62(data: &str) -> Result<Vec<u8>, char> {
|
|||
}
|
||||
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct StatsdMsg {
|
||||
entries: Vec<String>,
|
||||
key: Vec<String>
|
||||
}
|
||||
|
||||
impl StatsdMsg {
|
||||
pub fn new() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
pub fn add<T: fmt::Display>(&mut self, key: &str, val: T, type_: &str) -> &mut Self {
|
||||
self.entries.push(format!("{}.{}:{}|{}", self.key.join("."), key, val, type_));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_ns<F: FnOnce(&mut Self)>(&mut self, ns: &str, f: F) -> &mut Self {
|
||||
self.key.push(ns.to_string());
|
||||
f(self);
|
||||
self.key.pop();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(&self) -> String {
|
||||
self.entries.join("\n")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn base62() {
|
||||
assert_eq!("", to_base62(&[0]));
|
||||
|
|
Loading…
Reference in New Issue