From 7a7499aeaa45a33aed4b3bfd339c950fa21e1a08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Mon, 12 Oct 2020 21:04:22 +0200 Subject: change to actual logging (#2) --- mumd/Cargo.toml | 3 +++ mumd/src/audio.rs | 19 ++++++++++--------- mumd/src/main.rs | 24 ++++++++++++++++++++++++ mumd/src/network.rs | 36 +++++++++++++++++------------------- mumd/src/state.rs | 5 +++-- 5 files changed, 57 insertions(+), 30 deletions(-) (limited to 'mumd') diff --git a/mumd/Cargo.toml b/mumd/Cargo.toml index 2f38df3..72f9167 100644 --- a/mumd/Cargo.toml +++ b/mumd/Cargo.toml @@ -11,9 +11,12 @@ edition = "2018" [dependencies] argparse = "0.2" bytes = "0.5" +colored = "2.0" cpal = { git = "https://github.com/RustAudio/cpal" } +fern = "0.5" futures = "0.3" futures-util = "0.3" +log = "0.4" mumble-protocol = "0.3" native-tls = "0.2" openssl = { version = "0.10", optional = true } diff --git a/mumd/src/audio.rs b/mumd/src/audio.rs index eeae4da..9b794a6 100644 --- a/mumd/src/audio.rs +++ b/mumd/src/audio.rs @@ -4,6 +4,7 @@ use cpal::traits::HostTrait; use cpal::{ InputCallbackInfo, OutputCallbackInfo, Sample, SampleFormat, SampleRate, Stream, StreamConfig, }; +use log::*; use mumble_protocol::voice::VoicePacketPayload; use opus::Channels; use std::collections::hash_map::Entry; @@ -62,7 +63,7 @@ impl Audio { let input_supported_sample_format = input_supported_config.sample_format(); let input_config: StreamConfig = input_supported_config.into(); - let err_fn = |err| eprintln!("an error occurred on the output audio stream: {}", err); + let err_fn = |err| error!("An error occurred on the output audio stream: {}", err); let client_streams = Arc::new(Mutex::new(HashMap::new())); let output_stream = match output_supported_sample_format { @@ -90,7 +91,7 @@ impl Audio { 1 => Channels::Mono, 2 => Channels::Stereo, _ => unimplemented!( - "only 1 or 2 channels supported, got {})", + "Only 1 or 2 channels supported, got {})", input_config.channels ), }, @@ -147,7 +148,7 @@ impl Audio { .decode_packet(payload, self.output_config.channels as usize); } Entry::Vacant(_) => { - eprintln!("cannot find session id {}", session_id); + warn!("Can't find session id {}", session_id); } } } @@ -155,7 +156,7 @@ impl Audio { pub fn add_client(&self, session_id: u32) { match self.client_streams.lock().unwrap().entry(session_id) { Entry::Occupied(_) => { - eprintln!("session id {} already exists", session_id); + warn!("Session id {} already exists", session_id); } Entry::Vacant(entry) => { entry.insert(ClientStream::new( @@ -172,8 +173,8 @@ impl Audio { entry.remove(); } Entry::Vacant(_) => { - eprintln!( - "tried to remove session id {} that doesn't exist", + warn!( + "Tried to remove session id {} that doesn't exist", session_id ); } @@ -194,7 +195,7 @@ impl ClientStream { match channels { 1 => Channels::Mono, 2 => Channels::Stereo, - _ => unimplemented!("only 1 or 2 channels supported, got {}", channels), + _ => unimplemented!("Only 1 or 2 channels supported, got {}", channels), }, ) .unwrap(), @@ -207,12 +208,12 @@ impl ClientStream { let mut out: Vec = vec![0.0; 720 * channels * 4]; //720 is because that is the max size of packet we can get that we want to decode let parsed = self.opus_decoder .decode_float(&bytes, &mut out, false) - .expect("error decoding"); + .expect("Error decoding"); out.truncate(parsed); self.buffer.extend(out); } _ => { - unimplemented!("payload type not supported"); + unimplemented!("Payload type not supported"); } } } diff --git a/mumd/src/main.rs b/mumd/src/main.rs index afc1b2e..fcffb87 100644 --- a/mumd/src/main.rs +++ b/mumd/src/main.rs @@ -8,9 +8,11 @@ use crate::state::Server; use argparse::ArgumentParser; use argparse::Store; use argparse::StoreTrue; +use colored::*; use cpal::traits::StreamTrait; use futures::channel::oneshot; use futures::join; +use log::*; use mumble_protocol::crypt::ClientCryptState; use std::net::ToSocketAddrs; use std::sync::Arc; @@ -18,6 +20,28 @@ use std::sync::Mutex; #[tokio::main] async fn main() { + // setup logger + fern::Dispatch::new() + .format(|out, message, record| { + out.finish(format_args!( + "{} {}:{} {}", + //TODO runtime flag that disables color + match record.level() { + Level::Error => "ERROR".red(), + Level::Warn => "WARN ".yellow(), + Level::Info => "INFO ".normal(), + Level::Debug => "DEBUG".green(), + Level::Trace => "TRACE".normal(), + }, + record.file().unwrap(), + record.line().unwrap(), + message + )) + }) + .level(log::LevelFilter::Debug) + .chain(std::io::stderr()) + .apply().unwrap(); + // Handle command line arguments let mut server_host = "".to_string(); let mut server_port = 64738u16; diff --git a/mumd/src/network.rs b/mumd/src/network.rs index 0602860..a90a0fc 100644 --- a/mumd/src/network.rs +++ b/mumd/src/network.rs @@ -5,6 +5,7 @@ use bytes::Bytes; use futures::channel::oneshot; use futures::{join, SinkExt, StreamExt}; use futures_util::stream::{SplitSink, SplitStream}; +use log::*; use mumble_protocol::control::{msgs, ClientControlCodec, ControlCodec, ControlPacket}; use mumble_protocol::crypt::ClientCryptState; use mumble_protocol::voice::{VoicePacket, VoicePacketPayload}; @@ -35,7 +36,7 @@ async fn connect_tcp( let stream = TcpStream::connect(&server_addr) .await .expect("failed to connect to server:"); - println!("TCP connected"); + debug!("TCP connected"); let mut builder = native_tls::TlsConnector::builder(); builder.danger_accept_invalid_certs(accept_invalid_cert); @@ -47,7 +48,7 @@ async fn connect_tcp( .connect(&server_host, stream) .await .expect("failed to connect TLS: {}"); - println!("TLS connected"); + debug!("TLS connected"); // Wrap the TLS stream with Mumble's client-side control-channel codec ClientControlCodec::new().framed(tls_stream).split() @@ -67,7 +68,7 @@ pub async fn connect_udp( // disconnected before we received the CryptSetup packet, oh well Err(_) => panic!("disconnect before crypt packet received"), //TODO exit gracefully }; - println!("UDP ready!"); + debug!("UDP connected"); // Wrap the raw UDP packets in Mumble's crypto and voice codec (CryptState does both) UdpFramed::new(udp_socket, crypt_state).split() @@ -77,7 +78,7 @@ async fn send_pings(sink: Arc>, delay_seconds: u64) { let mut interval = time::interval(Duration::from_secs(delay_seconds)); loop { interval.tick().await; - println!("Sending ping"); + trace!("Sending ping"); let msg = msgs::Ping::new(); sink.lock().unwrap().send(msg.into()).await.unwrap(); } @@ -104,7 +105,7 @@ async fn listen_tcp( //TODO handle types separately match packet.unwrap() { ControlPacket::TextMessage(mut msg) => { - println!( + info!( "Got message from user with session ID {}: {}", msg.get_actor(), msg.get_message() @@ -117,7 +118,7 @@ async fn listen_tcp( lock.send(response.into()).await.unwrap(); } ControlPacket::CryptSetup(msg) => { - println!("crypt setup"); + debug!("Crypt setup"); // Wait until we're fully connected before initiating UDP voice crypt_state = Some(ClientCryptState::new_from( msg.get_key() @@ -132,7 +133,7 @@ async fn listen_tcp( )); } ControlPacket::ServerSync(msg) => { - println!("Logged in!"); + info!("Logged in"); if let Some(sender) = crypt_state_sender.take() { sender.send( crypt_state @@ -143,16 +144,16 @@ async fn listen_tcp( let mut server = server.lock().unwrap(); server.parse_server_sync(msg); match &server.welcome_text { - Some(s) => println!("Welcome: {}", s), - None => println!("No welcome found"), + Some(s) => info!("Welcome: {}", s), + None => info!("No welcome received"), } for (_, channel) in server.channels() { - println!("Found channel {}", channel.name()); + info!("Found channel {}", channel.name()); } sink.lock().unwrap().send(msgs::UserList::new().into()).await.unwrap(); } ControlPacket::Reject(msg) => { - println!("Login rejected: {:?}", msg); + warn!("Login rejected: {:?}", msg); } ControlPacket::UserState(msg) => { audio.lock().unwrap().add_client(msg.get_session()); @@ -160,22 +161,19 @@ async fn listen_tcp( let session = msg.get_session(); server.parse_user_state(msg); let user = server.users().get(&session).unwrap(); - println!("User {} connected to {}", + info!("User {} connected to {}", user.name(), user.channel()); } ControlPacket::UserRemove(msg) => { - println!("User {} left", msg.get_session()); + info!("User {} left", msg.get_session()); audio.lock().unwrap().remove_client(msg.get_session()); } ControlPacket::ChannelState(msg) => { + debug!("Channel state received"); server.lock().unwrap().parse_channel_state(msg); } ControlPacket::ChannelRemove(msg) => {} - ControlPacket::UserList(msg) => { - println!("User list received"); - println!("{:?}", msg); - } _ => {} } } @@ -196,7 +194,7 @@ pub async fn handle_tcp( // Handshake (omitting `Version` message for brevity) authenticate(Arc::clone(&sink), username).await; - println!("Logging in.."); + info!("Logging in..."); join!( send_pings(Arc::clone(&sink), 10), @@ -213,7 +211,7 @@ async fn listen_udp( let (packet, _src_addr) = match packet { Ok(packet) => packet, Err(err) => { - eprintln!("Got an invalid UDP packet: {}", err); + warn!("Got an invalid UDP packet: {}", err); // To be expected, considering this is the internet, just ignore it continue; } diff --git a/mumd/src/state.rs b/mumd/src/state.rs index 791d26c..6e0d908 100644 --- a/mumd/src/state.rs +++ b/mumd/src/state.rs @@ -1,3 +1,4 @@ +use log::*; use mumble_protocol::control::msgs; use std::collections::HashMap; use std::collections::hash_map::Entry; @@ -25,7 +26,7 @@ impl Server { pub fn parse_channel_state(&mut self, msg: Box) { if !msg.has_channel_id() { - eprintln!("Can't parse channel state without channel id"); + warn!("Can't parse channel state without channel id"); return; } match self.channels.entry(msg.get_channel_id()) { @@ -36,7 +37,7 @@ impl Server { pub fn parse_user_state(&mut self, msg: Box) { if !msg.has_session() { - eprintln!("Can't parse user state without session"); + warn!("Can't parse user state without session"); return; } match self.users.entry(msg.get_session()) { -- cgit v1.2.1