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,
|
traffic::TrafficStats,
|
||||||
types::{Error, HeaderMagic, NodeId, Protocol, Range, Table},
|
types::{Error, HeaderMagic, NodeId, Protocol, Range, Table},
|
||||||
udpmessage::{decode, encode, Message},
|
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>;
|
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 peer_traffic = self.traffic.total_peer_traffic();
|
||||||
let payload_traffic = self.traffic.total_payload_traffic();
|
let payload_traffic = self.traffic.total_payload_traffic();
|
||||||
let dropped = &self.traffic.dropped;
|
let dropped = &self.traffic.dropped;
|
||||||
let msg = format!(
|
let prefix = self.config.statsd_prefix.as_ref().map(|s| s as &str).unwrap_or("vpncloud");
|
||||||
"peer_count:{}|g\ntable_entries:{}|g\n\
|
let msg = StatsdMsg::new()
|
||||||
traffic.protocol.inbound.bytes:{}\n\
|
.with_ns(prefix, |msg| {
|
||||||
traffic.protocol.inbound.packets:{}\n\
|
msg.add("peer_count", self.peers.len(), "g");
|
||||||
traffic.protocol.outbound.bytes:{}\n\
|
msg.add("table_entries", self.table.len(), "g");
|
||||||
traffic.protocol.outbound.packets:{}\n\
|
msg.with_ns("traffic", |msg| {
|
||||||
traffic.payload.inbound.bytes:{}\n\
|
msg.with_ns("protocol", |msg| {
|
||||||
traffic.payload.inbound.packets:{}\n\
|
msg.with_ns("inbound", |msg| {
|
||||||
traffic.payload.outbound.bytes:{}\n\
|
msg.add("bytes", peer_traffic.in_bytes, "c");
|
||||||
traffic.payload.outbound.packets:{}\n\
|
msg.add("packets", peer_traffic.in_packets, "c");
|
||||||
invalid_protocol_traffic.bytes:{}\n\
|
});
|
||||||
invalid_protocol_traffic.packets:{}\n\
|
msg.with_ns("outbound", |msg| {
|
||||||
dropped_payload.bytes:{}\n\
|
msg.add("bytes", peer_traffic.out_bytes, "c");
|
||||||
dropped_payload.packets:{}",
|
msg.add("packets", peer_traffic.out_packets, "c");
|
||||||
self.peers.len(),
|
});
|
||||||
self.table.len(),
|
});
|
||||||
peer_traffic.in_bytes,
|
msg.with_ns("payload", |msg| {
|
||||||
peer_traffic.in_packets,
|
msg.with_ns("inbound", |msg| {
|
||||||
peer_traffic.out_bytes,
|
msg.add("bytes", payload_traffic.in_bytes, "c");
|
||||||
peer_traffic.out_packets,
|
msg.add("packets", payload_traffic.in_packets, "c");
|
||||||
payload_traffic.in_bytes,
|
});
|
||||||
payload_traffic.in_packets,
|
msg.with_ns("outbound", |msg| {
|
||||||
payload_traffic.out_bytes,
|
msg.add("bytes", payload_traffic.out_bytes, "c");
|
||||||
payload_traffic.out_packets,
|
msg.add("packets", payload_traffic.out_packets, "c");
|
||||||
dropped.in_bytes,
|
});
|
||||||
dropped.in_packets,
|
});
|
||||||
dropped.out_bytes,
|
});
|
||||||
dropped.out_packets
|
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 msg_data = msg.as_bytes();
|
||||||
let addrs = resolve(endpoint)?;
|
let addrs = resolve(endpoint)?;
|
||||||
if let Some(addr) = addrs.first() {
|
if let Some(addr) = addrs.first() {
|
||||||
|
|
|
@ -59,6 +59,7 @@ pub struct Config {
|
||||||
pub pid_file: Option<String>,
|
pub pid_file: Option<String>,
|
||||||
pub stats_file: Option<String>,
|
pub stats_file: Option<String>,
|
||||||
pub statsd_server: Option<String>,
|
pub statsd_server: Option<String>,
|
||||||
|
pub statsd_prefix: Option<String>,
|
||||||
pub user: Option<String>,
|
pub user: Option<String>,
|
||||||
pub group: Option<String>
|
pub group: Option<String>
|
||||||
}
|
}
|
||||||
|
@ -89,6 +90,7 @@ impl Default for Config {
|
||||||
pid_file: None,
|
pid_file: None,
|
||||||
stats_file: None,
|
stats_file: None,
|
||||||
statsd_server: None,
|
statsd_server: None,
|
||||||
|
statsd_prefix: None,
|
||||||
user: None,
|
user: None,
|
||||||
group: None
|
group: None
|
||||||
}
|
}
|
||||||
|
@ -168,6 +170,9 @@ impl Config {
|
||||||
if let Some(val) = file.statsd_server {
|
if let Some(val) = file.statsd_server {
|
||||||
self.statsd_server = Some(val);
|
self.statsd_server = Some(val);
|
||||||
}
|
}
|
||||||
|
if let Some(val) = file.statsd_prefix {
|
||||||
|
self.statsd_prefix = Some(val);
|
||||||
|
}
|
||||||
if let Some(val) = file.user {
|
if let Some(val) = file.user {
|
||||||
self.user = Some(val);
|
self.user = Some(val);
|
||||||
}
|
}
|
||||||
|
@ -246,6 +251,9 @@ impl Config {
|
||||||
if let Some(val) = args.statsd_server {
|
if let Some(val) = args.statsd_server {
|
||||||
self.statsd_server = Some(val);
|
self.statsd_server = Some(val);
|
||||||
}
|
}
|
||||||
|
if let Some(val) = args.statsd_prefix {
|
||||||
|
self.statsd_prefix = Some(val);
|
||||||
|
}
|
||||||
if let Some(val) = args.user {
|
if let Some(val) = args.user {
|
||||||
self.user = Some(val);
|
self.user = Some(val);
|
||||||
}
|
}
|
||||||
|
@ -307,6 +315,7 @@ pub struct ConfigFile {
|
||||||
pub pid_file: Option<String>,
|
pub pid_file: Option<String>,
|
||||||
pub stats_file: Option<String>,
|
pub stats_file: Option<String>,
|
||||||
pub statsd_server: Option<String>,
|
pub statsd_server: Option<String>,
|
||||||
|
pub statsd_prefix: Option<String>,
|
||||||
pub user: Option<String>,
|
pub user: Option<String>,
|
||||||
pub group: Option<String>
|
pub group: Option<String>
|
||||||
}
|
}
|
||||||
|
@ -342,6 +351,7 @@ group: nogroup
|
||||||
pid_file: /run/vpncloud.run
|
pid_file: /run/vpncloud.run
|
||||||
stats_file: /var/log/vpncloud.stats
|
stats_file: /var/log/vpncloud.stats
|
||||||
statsd_server: example.com:1234
|
statsd_server: example.com:1234
|
||||||
|
statsd_prefix: prefix
|
||||||
";
|
";
|
||||||
assert_eq!(serde_yaml::from_str::<ConfigFile>(config_file).unwrap(), ConfigFile {
|
assert_eq!(serde_yaml::from_str::<ConfigFile>(config_file).unwrap(), ConfigFile {
|
||||||
device_type: Some(Type::Tun),
|
device_type: Some(Type::Tun),
|
||||||
|
@ -368,7 +378,8 @@ statsd_server: example.com:1234
|
||||||
group: Some("nogroup".to_string()),
|
group: Some("nogroup".to_string()),
|
||||||
pid_file: Some("/run/vpncloud.run".to_string()),
|
pid_file: Some("/run/vpncloud.run".to_string()),
|
||||||
stats_file: Some("/var/log/vpncloud.stats".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()),
|
group: Some("nogroup".to_string()),
|
||||||
pid_file: Some("/run/vpncloud.run".to_string()),
|
pid_file: Some("/run/vpncloud.run".to_string()),
|
||||||
stats_file: Some("/var/log/vpncloud.stats".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 {
|
assert_eq!(config, Config {
|
||||||
device_type: Type::Tun,
|
device_type: Type::Tun,
|
||||||
|
@ -427,6 +439,7 @@ fn config_merge() {
|
||||||
pid_file: Some("/run/vpncloud.run".to_string()),
|
pid_file: Some("/run/vpncloud.run".to_string()),
|
||||||
stats_file: Some("/var/log/vpncloud.stats".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()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
config.merge_args(Args {
|
config.merge_args(Args {
|
||||||
|
@ -453,6 +466,7 @@ fn config_merge() {
|
||||||
pid_file: Some("/run/vpncloud-mynet.run".to_string()),
|
pid_file: Some("/run/vpncloud-mynet.run".to_string()),
|
||||||
stats_file: Some("/var/log/vpncloud-mynet.stats".to_string()),
|
stats_file: Some("/var/log/vpncloud-mynet.stats".to_string()),
|
||||||
statsd_server: Some("example.com:2345".to_string()),
|
statsd_server: Some("example.com:2345".to_string()),
|
||||||
|
statsd_prefix: Some("prefix2".to_string()),
|
||||||
user: Some("root".to_string()),
|
user: Some("root".to_string()),
|
||||||
group: Some("root".to_string()),
|
group: Some("root".to_string()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
@ -486,6 +500,7 @@ fn config_merge() {
|
||||||
pid_file: Some("/run/vpncloud-mynet.run".to_string()),
|
pid_file: Some("/run/vpncloud-mynet.run".to_string()),
|
||||||
stats_file: Some("/var/log/vpncloud-mynet.stats".to_string()),
|
stats_file: Some("/var/log/vpncloud-mynet.stats".to_string()),
|
||||||
statsd_server: Some("example.com:2345".to_string()),
|
statsd_server: Some("example.com:2345".to_string()),
|
||||||
|
statsd_prefix: Some("prefix2".to_string()),
|
||||||
daemonize: true
|
daemonize: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,6 +173,10 @@ pub struct Args {
|
||||||
#[structopt(long)]
|
#[structopt(long)]
|
||||||
statsd_server: Option<String>,
|
statsd_server: Option<String>,
|
||||||
|
|
||||||
|
/// Use the given prefix for statsd records
|
||||||
|
#[structopt(long)]
|
||||||
|
statsd_prefix: Option<String>,
|
||||||
|
|
||||||
/// Run as other user
|
/// Run as other user
|
||||||
#[structopt(long)]
|
#[structopt(long)]
|
||||||
user: Option<String>,
|
user: Option<String>,
|
||||||
|
|
|
@ -10,7 +10,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
cloud::Hash,
|
cloud::{Hash, STATS_INTERVAL},
|
||||||
types::Address,
|
types::Address,
|
||||||
util::{addr_nice, Bytes}
|
util::{addr_nice, Bytes}
|
||||||
};
|
};
|
||||||
|
@ -157,10 +157,10 @@ impl TrafficStats {
|
||||||
out,
|
out,
|
||||||
" - peer: \"{}\"\n in: {{ display: \"{}/s\", bytes: {}, packets: {} }}\n out: {{ display: \"{}/s\", bytes: {}, packets: {} }}",
|
" - peer: \"{}\"\n in: {{ display: \"{}/s\", bytes: {}, packets: {} }}\n out: {{ display: \"{}/s\", bytes: {}, packets: {} }}",
|
||||||
addr_nice(**addr),
|
addr_nice(**addr),
|
||||||
Bytes(data.in_bytes / 60),
|
Bytes(data.in_bytes / STATS_INTERVAL as u64),
|
||||||
data.in_bytes,
|
data.in_bytes,
|
||||||
data.in_packets,
|
data.in_packets,
|
||||||
Bytes(data.out_bytes / 60),
|
Bytes(data.out_bytes / STATS_INTERVAL as u64),
|
||||||
data.out_bytes,
|
data.out_bytes,
|
||||||
data.out_packets
|
data.out_packets
|
||||||
)?;
|
)?;
|
||||||
|
@ -175,10 +175,10 @@ impl TrafficStats {
|
||||||
" - addrs: [\"{}\", \"{}\"]\n in: {{ display: \"{}/s\", bytes: {}, packets: {} }}\n out: {{ display: \"{}/s\", bytes: {}, packets: {} }}",
|
" - addrs: [\"{}\", \"{}\"]\n in: {{ display: \"{}/s\", bytes: {}, packets: {} }}\n out: {{ display: \"{}/s\", bytes: {}, packets: {} }}",
|
||||||
remote,
|
remote,
|
||||||
local,
|
local,
|
||||||
Bytes(data.in_bytes / 60),
|
Bytes(data.in_bytes / STATS_INTERVAL as u64),
|
||||||
data.in_bytes,
|
data.in_bytes,
|
||||||
data.in_packets,
|
data.in_packets,
|
||||||
Bytes(data.out_bytes / 60),
|
Bytes(data.out_bytes / STATS_INTERVAL as u64),
|
||||||
data.out_bytes,
|
data.out_bytes,
|
||||||
data.out_packets
|
data.out_packets
|
||||||
)?;
|
)?;
|
||||||
|
@ -187,14 +187,14 @@ impl TrafficStats {
|
||||||
writeln!(
|
writeln!(
|
||||||
out,
|
out,
|
||||||
"invalid_protocol_traffic: {{ display: \"{}/s\", bytes: {}, packets: {} }}",
|
"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_bytes,
|
||||||
self.dropped.in_packets
|
self.dropped.in_packets
|
||||||
)?;
|
)?;
|
||||||
writeln!(
|
writeln!(
|
||||||
out,
|
out,
|
||||||
"dropped_payload_traffic: {{ display: \"{}/s\", bytes: {}, packets: {} }}",
|
"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_bytes,
|
||||||
self.dropped.out_packets
|
self.dropped.out_packets
|
||||||
)?;
|
)?;
|
||||||
|
|
|
@ -228,6 +228,9 @@ pub trait Table {
|
||||||
fn remove(&mut self, _: &Address) -> bool;
|
fn remove(&mut self, _: &Address) -> bool;
|
||||||
fn remove_all(&mut self, _: &SocketAddr);
|
fn remove_all(&mut self, _: &SocketAddr);
|
||||||
fn len(&self) -> usize;
|
fn len(&self) -> usize;
|
||||||
|
fn is_empty(&self) -> bool {
|
||||||
|
self.len() == 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Protocol: Sized {
|
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]
|
#[test]
|
||||||
fn base62() {
|
fn base62() {
|
||||||
assert_eq!("", to_base62(&[0]));
|
assert_eq!("", to_base62(&[0]));
|
||||||
|
|
Loading…
Reference in New Issue