Skip to content
This repository was archived by the owner on Dec 10, 2022. It is now read-only.

Add counters to motd #35

Merged
merged 2 commits into from
Dec 4, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 14 additions & 15 deletions .appveyor.yml
Original file line number Diff line number Diff line change
@@ -12,25 +12,24 @@ branches:

environment:
matrix:
- channel: stable
target: x86_64-pc-windows-gnu
# stable x86_64 with static libsodium from sources
- TARGET: x86_64-pc-windows-msvc
RUST_CHANNEL: stable

# stable x86 with static libsodium from sources
- TARGET: i686-pc-windows-msvc
RUST_CHANNEL: stable
# env variables for debugging
RUST_BACKTRACE: "1"

install:
# install libsodium
- mkdir deps && cd deps
- appveyor-retry appveyor DownloadFile https://download.libsodium.org/libsodium/releases/libsodium-1.0.16-mingw.tar.gz -FileName libsodium.tar.gz
- 7z x libsodium.tar.gz -so | 7z x -si -ttar > nul
- set SODIUM_STATIC=1
- set SODIUM_LIB_DIR=C:\projects\tox-node\deps\libsodium-win64\lib
- cd C:\projects\tox-node
# install rustc & cargo
- appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
- rustup-init -yv --default-toolchain %channel% --default-host %target%
- set PATH=%PATH%;%USERPROFILE%\.cargo\bin
- rustc -vV
- cargo -vV
- ps: |
# Install Rust
appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
cmd.exe /c .\rustup-init.exe -y --default-host "$env:TARGET" --default-toolchain "$env:RUST_CHANNEL" 2`>`&1
$env:PATH += ";$env:USERPROFILE\.cargo\bin"
rustc -V
cargo -V
build: false

2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
language: rust
rust:
- 1.26.0
- 1.30.1
- stable
- beta
- nightly
776 changes: 621 additions & 155 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@ log = "0.4"
regex = "1"
tokio = "0.1.7"
tokio-codec = "0.1"
tox = "0.0.7"
tox = { git = "https://github.com/tox-rs/tox/" }

[target.'cfg(unix)'.dependencies]
syslog = "4.0"
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -37,6 +37,10 @@ via `--motd` key. It's possible to use the following variables surrounded by
`{{ }}`:
- `start_date`: time when the node was started
- `uptime`: uptime in the format 'XX days XX hours XX minutes'
- `tcp_packets_in`: counter of tcp incoming packets
- `tcp_packets_out`: counter of tcp outgoing packets
- `udp_packets_in`: counter of udp incoming packets
- `udp_packets_out`: counter of udp outgoing packets

## Keys generation

21 changes: 13 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -39,11 +39,12 @@ use tox::toxcore::dht::lan_discovery::LanDiscoverySender;
use tox::toxcore::onion::packet::InnerOnionResponse;
use tox::toxcore::tcp::packet::OnionRequest;
use tox::toxcore::tcp::server::{Server as TcpServer, ServerExt};
use tox::toxcore::stats::Stats;
#[cfg(unix)]
use syslog::Facility;

use cli_config::*;
use motd::Motd;
use motd::{Motd, Counters};

/// Get version in format 3AAABBBCCC, where A B and C are major, minor and patch
/// versions of node. `tox-bootstrapd` uses similar scheme but with leading 1.
@@ -163,7 +164,7 @@ fn create_onion_streams() -> (TcpOnion, UdpOnion) {
(tcp_onion, udp_onion)
}

fn run_tcp(cli_config: &CliConfig, dht_sk: SecretKey, tcp_onion: TcpOnion) -> impl Future<Item = (), Error = Error> {
fn run_tcp(cli_config: &CliConfig, dht_sk: SecretKey, tcp_onion: TcpOnion, stats: Stats) -> impl Future<Item = (), Error = Error> {
if cli_config.tcp_addrs.is_empty() {
// If TCP address is not specified don't start TCP server and only drop
// all onion packets from DHT server
@@ -181,7 +182,7 @@ fn run_tcp(cli_config: &CliConfig, dht_sk: SecretKey, tcp_onion: TcpOnion) -> im
let tcp_server_c = tcp_server_c.clone();
let dht_sk = dht_sk.clone();
let listener = TcpListener::bind(&addr).expect("Failed to bind TCP listener");
tcp_server_c.run(listener, dht_sk)
tcp_server_c.run(listener, dht_sk, stats.clone())
.map_err(Error::from)
});

@@ -205,7 +206,7 @@ fn run_tcp(cli_config: &CliConfig, dht_sk: SecretKey, tcp_onion: TcpOnion) -> im
.map(|_| ()))
}

fn run_udp(cli_config: &CliConfig, dht_pk: PublicKey, dht_sk: &SecretKey, udp_onion: UdpOnion) -> impl Future<Item = (), Error = Error> {
fn run_udp(cli_config: &CliConfig, dht_pk: PublicKey, dht_sk: &SecretKey, udp_onion: UdpOnion, tcp_stats: Stats) -> impl Future<Item = (), Error = Error> {
let udp_addr = if let Some(udp_addr) = cli_config.udp_addr {
udp_addr
} else {
@@ -218,7 +219,9 @@ fn run_udp(cli_config: &CliConfig, dht_pk: PublicKey, dht_sk: &SecretKey, udp_on
};

let socket = bind_socket(udp_addr);
let (sink, stream) = UdpFramed::new(socket, DhtCodec).split();
let udp_stats = Stats::new();
let codec = DhtCodec::new(udp_stats.clone());
let (sink, stream) = UdpFramed::new(socket, codec).split();

// Create a channel for server to communicate with network
let (tx, rx) = mpsc::unbounded();
@@ -232,7 +235,8 @@ fn run_udp(cli_config: &CliConfig, dht_pk: PublicKey, dht_sk: &SecretKey, udp_on
};

let mut server = UdpServer::new(tx, dht_pk, dht_sk.clone());
let motd = Motd::new(cli_config.motd.clone());
let counters = Counters::new(tcp_stats, udp_stats);
let motd = Motd::new(cli_config.motd.clone(), counters);
server.set_bootstrap_info(version(), Box::new(move |_| motd.format().as_bytes().to_owned()));
server.enable_lan_discovery(cli_config.lan_discovery_enabled);
server.set_tcp_onion_sink(udp_onion.tx);
@@ -346,8 +350,9 @@ fn main() {

let (tcp_onion, udp_onion) = create_onion_streams();

let udp_server_future = run_udp(&cli_config, dht_pk, &dht_sk, udp_onion);
let tcp_server_future = run_tcp(&cli_config, dht_sk, tcp_onion);
let tcp_stats = Stats::new();
let udp_server_future = run_udp(&cli_config, dht_pk, &dht_sk, udp_onion, tcp_stats.clone());
let tcp_server_future = run_tcp(&cli_config, dht_sk, tcp_onion, tcp_stats);

let future = udp_server_future.select(tcp_server_future).map(|_| ()).map_err(|(e, _)| e);

65 changes: 64 additions & 1 deletion src/motd.rs
Original file line number Diff line number Diff line change
@@ -2,6 +2,9 @@ use std::borrow::Cow;
use chrono::DateTime;
use chrono::offset::Local;
use regex::Regex;
use std::u64;

use tox::toxcore::stats::Stats;

struct RegexMatches {
regex: Regex,
@@ -25,27 +28,71 @@ impl RegexMatches {
}
}

/// Packet counters for both tcp and udp.
pub struct Counters {
tcp: Stats,
udp: Stats,
}

impl Counters {
pub fn new(tcp: Stats, udp: Stats) -> Self {
Counters {
tcp,
udp,
}
}
}

pub struct Motd {
start_date_regex: RegexMatches,
uptime_regex: RegexMatches,
tcp_packets_in_regex: RegexMatches,
tcp_packets_out_regex: RegexMatches,
udp_packets_in_regex: RegexMatches,
udp_packets_out_regex: RegexMatches,
start_date: DateTime<Local>,
counters: Counters,
template: String,
}

impl Motd {
pub fn new(template: String) -> Motd {
pub fn new(template: String, counters: Counters) -> Motd {
let start_date_regex = Regex::new(r"(?i)\{\{\s*start_date\s*\}\}")
.expect("Failed to compile start_date regex");
let uptime_regex = Regex::new(r"(?i)\{\{\s*uptime\s*\}\}")
.expect("Failed to compile uptime regex");
let tcp_packets_in_regex = Regex::new(r"(?i)\{\{\s*tcp_packets_in\s*\}\}")
.expect("Failed to compile tcp_in regex");
let tcp_packets_out_regex = Regex::new(r"(?i)\{\{\s*tcp_packets_out\s*\}\}")
.expect("Failed to compile tcp_out regex");
let udp_packets_in_regex = Regex::new(r"(?i)\{\{\s*udp_packets_in\s*\}\}")
.expect("Failed to compile udp_in regex");
let udp_packets_out_regex = Regex::new(r"(?i)\{\{\s*udp_packets_out\s*\}\}")
.expect("Failed to compile udp_out regex");
Motd {
start_date_regex: RegexMatches::new(&template, start_date_regex),
uptime_regex: RegexMatches::new(&template, uptime_regex),
tcp_packets_in_regex: RegexMatches::new(&template, tcp_packets_in_regex),
tcp_packets_out_regex: RegexMatches::new(&template, tcp_packets_out_regex),
udp_packets_in_regex: RegexMatches::new(&template, udp_packets_in_regex),
udp_packets_out_regex: RegexMatches::new(&template, udp_packets_out_regex),
start_date: Local::now(),
counters,
template,
}
}

fn summary(source: u64) -> String {
match source {
0..=999 => format!("{}",source),
1000..=999999 => format!("{0:.1}K", source as f32 / 1000.0),
1000000..=999999999 => format!("{0:.1}M", source as f32 / 1000000.0),
1000000000..=999999999999 => format!("{0:.1}G", source as f32 / 1000000000.0),
1000000000000..=u64::MAX => format!("{0:.1}T", source as f32 / 1000000000000.0),
_ => unreachable!("Packets counter has an impossible value")
}
}

pub fn format(&self) -> String {
let result = self.start_date_regex.replace(&self.template, ||
self.start_date.format("%c").to_string()
@@ -62,6 +109,22 @@ impl Motd {
minutes
)
});
let result = self.tcp_packets_in_regex.replace(&result, || {
let packets = self.counters.tcp.counters.incoming();
Self::summary(packets)
});
let result = self.tcp_packets_out_regex.replace(&result, || {
let packets = self.counters.tcp.counters.outgoing();
Self::summary(packets)
});
let result = self.udp_packets_in_regex.replace(&result, || {
let packets = self.counters.udp.counters.incoming();
Self::summary(packets)
});
let result = self.udp_packets_out_regex.replace(&result, || {
let packets = self.counters.udp.counters.outgoing();
Self::summary(packets)
});
result.into_owned()
}
}