polish: professionalize all user-facing log output and UX

- Unified log prefix to [ostp] across all modules (was [OSTP Core],
  [ostp-server], [ostp-client], [client], [bridge])
- Removed informal/casual phrasing from all user-visible messages
- Startup messages are clean and concise (mode, server, status)
- Error messages are actionable without being alarming
- Essential server logs (client connect/disconnect) always visible
- Essential client logs (connection status, errors) always visible
- TUN tunnel messages consistent across Windows and Linux
- Removed noisy eprintln from UDP reader hot path
- Status format: [ostp] Status: Connected (rtt=12.3ms)
This commit is contained in:
ospab 2026-05-17 03:26:15 +03:00
parent 7424ccc0ff
commit 8eb3fc72cb
6 changed files with 64 additions and 76 deletions

View File

@ -108,9 +108,9 @@ impl Bridge {
let mut keepalive_tick = tokio::time::interval(Duration::from_secs(5));
let mut retransmit_tick = tokio::time::interval(Duration::from_millis(50));
let init_msg = if self.mode == "tun" {
"Bridge & TUN Tunnel Manager initialized".to_string()
"Bridge initialized (TUN mode)".to_string()
} else {
"Bridge & SOCKS5 Proxy initialized".to_string()
"Bridge initialized (proxy mode)".to_string()
};
tx.send(UiEvent::Log(init_msg)).await.ok();
@ -203,7 +203,7 @@ impl Bridge {
}
}
None => {
let _ = tx.send(UiEvent::Log("UDP reader channel closed".to_string())).await;
let _ = tx.send(UiEvent::Log("UDP channel closed, resetting connection".to_string())).await;
self.running = false;
crate::sysproxy::disable_windows_proxy();
sessions_opt = None;
@ -226,7 +226,7 @@ impl Bridge {
stream_map.clear();
self.reset_proxy_streams(&tx, &proxy_tx, "manual stop");
tx.send(UiEvent::TunnelStopped).await.ok();
let stop_msg = if self.mode == "tun" { "TUN Tunnel stopped" } else { "Bridge stopped" };
let stop_msg = if self.mode == "tun" { "TUN tunnel stopped" } else { "Bridge stopped" };
tx.send(UiEvent::Log(stop_msg.to_string())).await.ok();
} else {
tx.send(UiEvent::Log("Connecting to remote server...".to_string())).await.ok();
@ -263,12 +263,10 @@ impl Bridge {
Bytes::copy_from_slice(&buf[..n])
};
if udp_tx_clone.send((idx, inbound)).await.is_err() {
eprintln!("[bridge] UDP receiver task exiting: bridge channel full or closed");
break;
}
}
Err(e) => {
eprintln!("[bridge] UDP socket recv error: {e}");
Err(_) => {
break;
}
}
@ -309,7 +307,7 @@ impl Bridge {
throughput_bps: 0,
}).await.ok();
self.metrics.connection_state.store(2, Ordering::Relaxed);
let start_msg = if self.mode == "tun" { "TUN Tunnel established" } else { "Connection established" };
let start_msg = if self.mode == "tun" { "TUN tunnel established" } else { "Connection established" };
tx.send(UiEvent::Log(start_msg.to_string())).await.ok();
}
}
@ -626,11 +624,11 @@ impl Bridge {
} else {
format!("{}:3478", self.turn_server)
};
tx.send(UiEvent::Log(format!("TURN: Allocating relay via {}", turn_addr))).await.ok();
tx.send(UiEvent::Log(format!("Allocating TURN relay via {}", turn_addr))).await.ok();
match perform_turn_allocation(&socket, &turn_addr, &self.turn_username, &self.turn_password, &self.server_addr).await {
Ok(relay_addr) => {
tx.send(UiEvent::Log(format!("TURN: Relay allocated. Traffic tunnelled via {}", relay_addr))).await.ok();
tx.send(UiEvent::Log(format!("TURN relay allocated ({})", relay_addr))).await.ok();
// Re-connect the UDP socket to the TURN server so all sends go through it.
// The TURN server forwards ChannelData to the OSTP server transparently.
socket
@ -639,7 +637,7 @@ impl Bridge {
.with_context(|| format!("failed to re-connect to TURN {}", turn_addr))?;
}
Err(e) => {
tx.send(UiEvent::Log(format!("TURN allocation failed: {e}. Falling back to direct UDP."))).await.ok();
tx.send(UiEvent::Log(format!("TURN allocation failed: {}. Using direct UDP.", e))).await.ok();
socket
.connect(&self.server_addr)
.await
@ -647,7 +645,7 @@ impl Bridge {
}
}
} else {
tx.send(UiEvent::Log(format!("Connected UDP directly to {}", self.server_addr))).await.ok();
tx.send(UiEvent::Log(format!("Connected to {}", self.server_addr))).await.ok();
socket
.connect(&self.server_addr)
.await

View File

@ -110,7 +110,7 @@ fn relaunch_as_admin() -> Result<()> {
pub async fn run_client(config: crate::config::ClientConfig) -> Result<()> {
#[cfg(target_os = "windows")]
if config.mode == "tun" && !is_admin() {
println!("[ostp-client] TUN mode requires Administrator privileges. Relaunching executable as Admin...");
println!("[ostp] TUN mode requires administrator privileges. Relaunching...");
relaunch_as_admin()?;
}
@ -150,7 +150,7 @@ pub async fn run_client_core(
log_to_core_file(&format!("[core] Starting run_client_core in mode: {}", config.mode));
if config.mode == "tun" && !config.exclusions.processes.is_empty() {
println!("[ostp-client] WARNING: process exclusions are not supported in the current TUN implementation");
println!("[ostp] Process exclusions are not supported in TUN mode");
}
let (proxy_events_tx, proxy_events_rx) = mpsc::channel(256);
@ -177,25 +177,25 @@ pub async fn run_client_core(
match msg {
crate::app::UiEvent::Log(text) => {
if debug_enabled || is_essential_log(&text) {
log_to_core_file(&format!("[client] {text}"));
println!("[client] {text}");
log_to_core_file(&format!("[ostp] {text}"));
println!("[ostp] {text}");
}
}
crate::app::UiEvent::Metrics { status, rtt_ms, .. } => {
let status_str = status.as_str().to_string();
if last_status != Some(status_str.clone()) {
last_status = Some(status_str.clone());
println!("[client] status={status_str} rtt_ms={:.1}", rtt_ms);
println!("[ostp] Status: {} (rtt={:.1}ms)", status_str, rtt_ms);
}
}
crate::app::UiEvent::Traffic { .. } => {}
crate::app::UiEvent::ProfileChanged(profile) => {
if debug_enabled {
println!("[client] profile={profile:?}");
println!("[ostp] Obfuscation profile: {profile:?}");
}
}
crate::app::UiEvent::TunnelStopped => {
println!("[client] Connection lost or failed. Reconnecting in 5s...");
println!("[ostp] Connection interrupted. Reconnecting in 5 seconds...");
let cmd_tx_inner = cmd_tx_clone.clone();
tokio::spawn(async move {
tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;
@ -280,14 +280,15 @@ fn is_essential_log(text: &str) -> bool {
matches!(
text,
"Connection established"
| "TUN Tunnel established"
| "TUN tunnel established"
| "TUN tunnel stopped"
| "Bridge stopped"
| "TUN Tunnel stopped"
| "Runtime config reloaded"
| "Connecting to remote server..."
) || text.starts_with("Connected UDP directly to ")
|| text.starts_with("TURN: Relay allocated")
) || text.starts_with("Connected to ")
|| text.starts_with("TURN relay allocated")
|| text.starts_with("TURN allocation failed")
|| text.starts_with("Allocating TURN relay")
|| text.starts_with("Connection failed:")
|| text.starts_with("Connection lost")
|| text.starts_with("Protocol tick fatal error")

View File

@ -43,7 +43,7 @@ pub async fn run_linux_tunnel(
) -> Result<()> {
let debug = config.debug;
if debug {
println!("[ostp-client] Starting Linux TUN handler initialization...");
println!("[ostp] Initializing TUN tunnel...");
}
let exe = std::env::current_exe()?;
@ -102,7 +102,7 @@ pub async fn run_linux_tunnel(
let server_ip_str = server_ip.to_string();
if debug {
println!("[ostp-client] Resolved remote server IP: {}", server_ip_str);
println!("[ostp-client] Resolved server IP: {}", server_ip_str);
}
// 3. Detect current default gateway and interface
@ -132,7 +132,7 @@ pub async fn run_linux_tunnel(
}
if debug {
println!("[ostp-client] Physical route anchor: gateway={} interface={}", default_gw, default_if);
println!("[ostp-client] Default route: gateway={} interface={}", default_gw, default_if);
}
// 4. Setup commands (Using standard /1 routing trick for fail-proof overriding)
@ -187,7 +187,7 @@ pub async fn run_linux_tunnel(
child: None,
};
println!("[client] TUN Tunnel established, Linux traffic is now routing through OSTP.");
println!("[ostp] TUN tunnel active. All traffic is routed through OSTP.");
if debug {
let stdout = child.stdout.take().unwrap();
@ -213,12 +213,12 @@ pub async fn run_linux_tunnel(
// 6. Wait for shutdown signal
let _ = shutdown.changed().await;
println!("[client] Deactivating TUN tunnel and restoring Linux network topology...");
println!("[ostp] Deactivating TUN tunnel...");
// Drop guard runs cleanup automatically
drop(_guard);
println!("[client] Linux TUN Tunnel stopped.");
println!("[ostp] TUN tunnel stopped.");
Ok(())
}

View File

@ -37,7 +37,7 @@ pub async fn run_wintun_tunnel(
let debug = config.debug;
if debug {
println!("[ostp-client] Initializing high-performance TUN tunnel via tun2socks...");
println!("[ostp] Initializing TUN tunnel...");
}
let exe = std::env::current_exe()?;
@ -64,12 +64,12 @@ pub async fn run_wintun_tunnel(
let server_ip_str = server_ip.to_string();
if debug {
println!("[ostp-client] Resolved remote server IP: {}", server_ip_str);
println!("[ostp-client] Resolved server IP: {}", server_ip_str);
}
// 3. Run PowerShell script to configure system routes
if debug {
println!("[ostp-client] Injecting system routing tables and excluding remote proxy...");
println!("[ostp-client] Configuring system routes...");
}
let current_exe = std::env::current_exe()?.to_string_lossy().into_owned();
@ -111,7 +111,7 @@ pub async fn run_wintun_tunnel(
let proxy_url = format!("http://{}", config.local_proxy.bind_addr);
if debug {
println!("[ostp-client] Spawning tun2socks daemon pointing to {}", proxy_url);
println!("[ostp-client] Starting tun2socks (proxy={})", proxy_url);
}
// Spawning buffer to allow local proxy listener to finish binding to local address
@ -139,7 +139,7 @@ pub async fn run_wintun_tunnel(
tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
if debug {
println!("[ostp-client] Applying network configurations onto 'ostp_tun' interface...");
println!("[ostp-client] Applying network configuration...");
}
let mut net_setup = String::from("\
@ -150,7 +150,7 @@ pub async fn run_wintun_tunnel(
if let Some(ref dns) = config.dns_server {
if !dns.is_empty() {
if debug {
println!("[ostp-client] Applying custom DNS server: {}", dns);
println!("[ostp-client] DNS server: {}", dns);
}
net_setup.push_str(&format!("netsh interface ipv4 set dnsservers name=\"ostp_tun\" static {} primary\n", dns));
}
@ -161,7 +161,7 @@ pub async fn run_wintun_tunnel(
.args(["-Command", &net_setup])
.output()?;
println!("[client] TUN Tunnel established, internet traffic is now routing through OSTP.");
println!("[ostp] TUN tunnel active. All traffic is routed through OSTP.");
// 6. Spawn thread to keep logging tun2socks output if in debug mode
let mut stdout = child.stdout.take();
@ -192,12 +192,12 @@ pub async fn run_wintun_tunnel(
// 7. Wait for shutdown signal
let _ = shutdown.changed().await;
println!("[client] Deactivating TUN tunnel and restoring system network topology...");
println!("[ostp] Deactivating TUN tunnel...");
// Drop guard runs cleanup automatically
drop(_guard);
println!("[client] TUN Tunnel stopped.");
println!("[ostp] TUN tunnel stopped.");
Ok(())
}

View File

@ -152,23 +152,21 @@ pub async fn run_server(
while let Some(ev) = ui_event_rx.recv().await {
match ev {
UiEvent::Log(msg) => {
if debug
|| msg.starts_with("Listening on ")
|| msg.starts_with("Hot-reloaded ")
|| msg.starts_with("Client ")
|| msg.starts_with("Cleaning up resources")
{
println!("[ostp-server] {msg}");
// Essential logs always visible; debug logs gated behind flag
let is_essential = msg.starts_with("Client ")
|| msg.starts_with("Listening")
|| msg.starts_with("Shutdown")
|| msg.starts_with("Session ");
if debug || is_essential {
println!("[ostp] {msg}");
}
}
UiEvent::KeyCreated { key } => {
if debug {
println!("[ostp-server] New access key created: {key}");
}
println!("[ostp] Access key created: {key}");
}
UiEvent::UnauthorizedProbe { peer, bytes } => {
if debug {
println!("[ostp-server] WARNING: unauthorized probe from {peer} ({bytes} bytes)");
println!("[ostp] Unauthorized probe from {peer} ({bytes} bytes)");
}
}
UiEvent::PeerSeen { .. } => {}
@ -177,15 +175,15 @@ pub async fn run_server(
}
});
println!("[ostp-server] Listening on {bind_addr}");
println!("[ostp] Listening on {bind_addr}");
tokio::select! {
res = run_server_loop(socket, dispatcher, max_datagram_size, ui_cmd_rx, ui_event_tx, shared_keys, outbound, debug) => {
if let Err(e) = res {
eprintln!("[ostp-server] error: {e}");
eprintln!("[ostp] Server error: {e}");
}
}
_ = wait_for_shutdown_signal() => {
println!("[ostp-server] shutdown signal received");
println!("[ostp] Shutdown signal received");
}
}
@ -361,7 +359,7 @@ async fn run_server_loop(
let _ = socket.send_to(&frame, peer_addr).await?;
}
for sid in dropped_sessions {
let _ = ui_event_tx.send(UiEvent::Log(format!("Cleaning up resources for expired session {sid}")));
let _ = ui_event_tx.send(UiEvent::Log(format!("Session {sid} expired, releasing resources")));
let mut streams_to_cancel = Vec::new();
for (&(session_id, stream_id), _) in &remotes {
if session_id == sid {

View File

@ -203,10 +203,9 @@ struct MuxConfig {
async fn main() -> Result<()> {
let res = run_app().await;
if let Err(e) = res {
eprintln!("\n====================================================");
eprintln!("[FATAL ERROR] Program terminated unexpectedly:");
eprintln!(" {}", e);
eprintln!("====================================================");
eprintln!();
eprintln!("[ostp] Fatal error: {}", e);
eprintln!();
#[cfg(target_os = "windows")]
{
@ -270,13 +269,13 @@ fn get_or_ask_public_ip(config_path: &std::path::Path) -> String {
}
if let Some(detected) = detect_local_public_ip() {
println!("[OSTP Core] Auto-detected public network IP: {}", detected);
println!("[ostp] Detected public IP: {}", detected);
let _ = std::fs::write(&cache_path, &detected);
return detected;
}
print!("\n[OSTP Core] Could not automatically detect your Server's Public IP.\n");
print!(">>> Please enter your Public IP or Domain Name for user links: ");
print!("\n[ostp] Could not detect the server public IP automatically.\n");
print!(" Enter your public IP or domain: ");
use std::io::Write;
let _ = std::io::stdout().flush();
@ -303,7 +302,7 @@ async fn run_app() -> Result<()> {
}
if let Some(url) = args.url {
println!("[OSTP Core] Booting direct client connection via share link...");
println!("[ostp] Connecting via share link...");
let client_cfg = parse_ostp_link(&url)
.map_err(|e| anyhow!("Share Link Error: {e}"))?;
return run_client_directly(client_cfg).await;
@ -390,7 +389,7 @@ async fn run_app() -> Result<()> {
}}"#, key)
};
fs::write(&args.config, &content)?;
println!("Successfully initialized configuration at {:?}", args.config);
println!("[ostp] Configuration written to {:?}", args.config);
if is_server {
let mut stripped = json_comments::StripComments::new(content.as_bytes());
@ -398,7 +397,7 @@ async fn run_app() -> Result<()> {
if let AppMode::Server(s) = config.mode {
let key = &s.access_keys[0];
let host = get_or_ask_public_ip(&args.config);
println!("\n>>> Handy Client Share Link for your users:");
println!("\n Share link for client distribution:");
println!(" ostp://{}@{}:50000", key, host);
}
}
@ -439,7 +438,7 @@ async fn run_app() -> Result<()> {
parts[0].to_string()
};
println!("\n>>> Ready-to-use OSTP client share links from {:?}:", args.config);
println!("\n Client share links from {:?}:", args.config);
for (idx, key) in server_cfg.access_keys.iter().enumerate() {
println!(" [{}] ostp://{}@{}:{}", idx + 1, key, host, port);
}
@ -453,9 +452,9 @@ async fn run_app() -> Result<()> {
match config.mode {
AppMode::Server(server_cfg) => {
println!("[OSTP Core] Starting in SERVER mode on {}", server_cfg.listen);
println!("[ostp] Starting server on {}", server_cfg.listen);
if let Some(turn) = server_cfg.turn_server {
println!("[OSTP Core] TURN integration enabled: {}", turn);
println!("[ostp] TURN relay enabled: {}", turn);
}
// Temporarily pass control to the isolated server implementation
let debug = server_cfg.debug.unwrap_or(false);
@ -487,17 +486,9 @@ async fn run_app() -> Result<()> {
}
async fn run_client_directly(client_cfg: ClientConfig) -> Result<()> {
println!("[OSTP Core] Starting in CLIENT mode connecting to {}", client_cfg.server);
if let Some(ref tun) = client_cfg.tun {
if tun.enable {
println!("[OSTP Core] TUN mode enabled.");
if let Some(ref path) = tun.wintun_path {
println!("[OSTP Core] Using custom wintun path: {}", path);
}
}
}
println!("[OSTP Core] Client logic loaded.");
let is_tun_enabled = client_cfg.tun.as_ref().map(|t| t.enable).unwrap_or(false);
let mode_str = if is_tun_enabled { "tun" } else { "proxy" };
println!("[ostp] Starting client (mode={}, server={})", mode_str, client_cfg.server);
let turn_cfg = client_cfg.turn.as_ref();
let client_conf = ostp_client::config::ClientConfig {
mode: if is_tun_enabled { "tun".to_string() } else { "proxy".to_string() },