Use log crate

This commit is contained in:
wyhaya
2020-01-13 20:55:30 +08:00
parent d4d796d3b1
commit e78cf2ba82
7 changed files with 112 additions and 63 deletions

33
Cargo.lock generated
View File

@@ -2,7 +2,7 @@
# It is not intended for manual editing.
[[package]]
name = "ace"
version = "0.0.3"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -455,13 +455,13 @@ dependencies = [
[[package]]
name = "regex"
version = "1.3.1"
version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -522,7 +522,7 @@ dependencies = [
[[package]]
name = "thread_local"
version = "0.3.6"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -540,7 +540,7 @@ dependencies = [
[[package]]
name = "tokio"
version = "0.2.6"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -553,12 +553,12 @@ dependencies = [
"mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
"pin-project-lite 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-macros 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-macros 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-macros"
version = "0.2.0"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -577,15 +577,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "updns"
version = "0.1.2"
version = "0.2.0"
dependencies = [
"ace 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ace 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -627,7 +628,7 @@ dependencies = [
]
[metadata]
"checksum ace 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "42d6302f03bbae8544fb07d9ab94bfbe2a5dbaadc857749d9fad959b55f13069"
"checksum ace 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efcf59867ff84f1cae9358064c6bd2a17b856d3a2bcd1cb4660c60c6f4d21c0a"
"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d"
"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee"
"checksum arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d73f9beda665eaa98ab9e4f7442bd4e7de6652587de55b2525e52e29c1b0ba"
@@ -684,7 +685,7 @@ dependencies = [
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
"checksum redox_users 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ecedbca3bf205f8d8f5c2b44d83cd0690e39ee84b951ed649e9f1841132b66d"
"checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd"
"checksum regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b5508c1941e4e7cb19965abef075d35a9a8b5cdf0846f30b4050e9b55dc55e87"
"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716"
"checksum rust-argon2 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ca4eaef519b494d1f2848fc602d18816fed808a981aedf4f1f00ceb7c9d32cf"
"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
@@ -692,10 +693,10 @@ dependencies = [
"checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
"checksum syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "661641ea2aa15845cddeb97dad000d22070bb5c1fb456b96c1cba883ec691e92"
"checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f"
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
"checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
"checksum tokio 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0e1bef565a52394086ecac0a6fa3b8ace4cb3a138ee1d96bd2b93283b56824e3"
"checksum tokio-macros 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5795a71419535c6dcecc9b6ca95bdd3c2d6142f7e8343d7beb9923f129aa87e"
"checksum tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "ffa2fdcfa937b20cb3c822a635ceecd5fc1a27a6a474527e5516aa24b8c8820a"
"checksum tokio-macros 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "50a61f268a3db2acee8dcab514efc813dc6dbe8a00e86076f935f94304b59a7a"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"

View File

@@ -1,6 +1,6 @@
[package]
name = "updns"
version = "0.1.2"
version = "0.2.0"
edition = "2018"
authors = ["wyhaya <wyhaya@gmail.com>"]
@@ -18,10 +18,11 @@ keywords = [
]
[dependencies]
ace = "0.0.3"
ace = "0.1.0"
dirs = "2.0.2"
futures = "0.3.1"
lazy_static = "1.4.0"
regex = "1.3.1"
log = { version = "0.4.8", features = ["max_level_trace", "release_max_level_info"] }
regex = "1.3.3"
time = "0.1.42"
tokio = {version = "0.2.6", features = ["fs", "io-util", "macros", "net", "stream", "time"]}
tokio = { version = "0.2.9", features = ["fs", "io-util", "macros", "net", "stream", "time"] }

View File

@@ -51,14 +51,15 @@ Usage:
Command:
add Add a DNS record
ls Print all configured DNS records
config Call vim to edit the configuration file
config Call 'vim' to edit the configuration file
path Print related directories
help Print help information
version Print version information
Option:
-c Specify a config file
-w Check the interval of the configuration file
-i Check the interval time of the configuration file
format: 1ms, 1s, 1m, 1h, 1d
```
## Config

View File

@@ -1,5 +1,6 @@
use crate::matcher::Matcher;
use futures::future::{BoxFuture, FutureExt};
use lazy_static::lazy_static;
use regex::Regex;
use std::{
borrow::Cow,
@@ -7,6 +8,7 @@ use std::{
path::{Path, PathBuf},
result,
slice::Iter,
time::Duration,
};
use tokio::{
fs,
@@ -18,6 +20,32 @@ lazy_static! {
static ref COMMENT_REGEX: Regex = Regex::new("#.*$").unwrap();
}
// Parse time format into Duration
pub fn try_parse_duration(text: &str) -> result::Result<Duration, ()> {
lazy_static! {
static ref REGEX_MATCH_TIME: Regex =
Regex::new(r"^(?P<time>\d+(\.\d+)?)(?P<unit>d|h|m|s|ms)$").unwrap();
}
let reg: &Regex = &REGEX_MATCH_TIME;
let cap = reg.captures(text).ok_or_else(|| ())?;
let time = cap.name("time").unwrap();
let unit = cap.name("unit").unwrap();
let n = time.as_str().parse::<f64>().map_err(|_| ())?;
let ms = match unit.as_str() {
"d" => 24_f64 * 60_f64 * 60_f64 * 1000_f64 * n,
"h" => 60_f64 * 60_f64 * 1000_f64 * n,
"m" => 60_f64 * 1000_f64 * n,
"s" => 1000_f64 * n,
"ms" => n,
_ => panic!(),
};
Ok(Duration::from_millis(ms as u64))
}
#[derive(Debug)]
pub struct Invalid {
pub line: usize,
@@ -85,7 +113,7 @@ pub struct Config {
pub bind: Vec<SocketAddr>,
pub proxy: Vec<SocketAddr>,
pub hosts: Hosts,
pub timeout: Option<u64>,
pub timeout: Option<Duration>,
pub invalid: Vec<Invalid>,
}
@@ -228,7 +256,7 @@ impl Parser {
Ok(addr) => config.proxy.push(addr),
Err(_) => invalid!(InvalidType::SocketAddr),
},
"timeout" => match value.parse::<u64>() {
"timeout" => match try_parse_duration(value) {
Ok(timeout) => config.timeout = Some(timeout),
Err(_) => invalid!(InvalidType::Timeout),
},

26
src/logger.rs Normal file
View File

@@ -0,0 +1,26 @@
use log::{LevelFilter, Metadata, Record, SetLoggerError};
static LOGGER: Logger = Logger;
pub fn init() -> Result<(), SetLoggerError> {
log::set_logger(&LOGGER).map(|()| log::set_max_level(LevelFilter::Trace))
}
struct Logger;
impl log::Log for Logger {
fn enabled(&self, _: &Metadata) -> bool {
true
}
fn log(&self, record: &Record) {
println!(
"[{}] {:<5} {}",
time::now().strftime("%F %T").unwrap(),
record.level(),
record.args()
);
}
fn flush(&self) {}
}

View File

@@ -1,8 +1,6 @@
#[macro_use]
extern crate lazy_static;
mod config;
mod lib;
mod logger;
mod matcher;
mod watch;
@@ -11,6 +9,7 @@ use config::{Config, Hosts, Invalid, Parser};
use dirs;
use futures::prelude::*;
use lib::*;
use log::*;
use regex::Regex;
use std::{
env,
@@ -30,13 +29,13 @@ const CONFIG_FILE: [&str; 2] = [".updns", "config"];
const DEFAULT_BIND: &str = "0.0.0.0:53";
const DEFAULT_PROXY: [&str; 2] = ["8.8.8.8:53", "1.1.1.1:53"];
const DEFAULT_TIMEOUT: u64 = 2000;
const DEFAULT_TIMEOUT: Duration = Duration::from_millis(2000);
const WATCH_INTERVAL: u64 = 5000;
const WATCH_INTERVAL: Duration = Duration::from_millis(5000);
static mut PROXY: Vec<SocketAddr> = Vec::new();
static mut HOSTS: Option<Hosts> = None;
static mut TIMEOUT: u64 = DEFAULT_TIMEOUT;
static mut TIMEOUT: Duration = DEFAULT_TIMEOUT;
macro_rules! exit {
($($arg:tt)*) => {
@@ -46,27 +45,11 @@ macro_rules! exit {
}
};
}
macro_rules! error {
($($arg:tt)*) => {
eprint!("{} ERROR ", time::now().strftime("[%Y-%m-%d %H:%M:%S]").unwrap());
eprintln!($($arg)*);
};
}
macro_rules! info {
($($arg:tt)*) => {
print!("{} INFO ", time::now().strftime("[%Y-%m-%d %H:%M:%S]").unwrap());
println!($($arg)*);
};
}
macro_rules! warn {
($($arg:tt)*) => {
print!("{} WARN ", time::now().strftime("[%Y-%m-%d %H:%M:%S]").unwrap());
println!($($arg)*);
};
}
#[tokio::main]
async fn main() {
let _ = logger::init();
let app = App::new(env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"))
.cmd("add", "Add a DNS record")
.cmd("ls", "Print all configured DNS records")
@@ -75,12 +58,18 @@ async fn main() {
.cmd("help", "Print help information")
.cmd("version", "Print version information")
.opt("-c", "Specify a config file")
.opt("-w", "Check the interval of the configuration file (ms)");
.opt(
"-i",
vec![
"Check the interval time of the configuration file",
"format: 1ms, 1s, 1m, 1h, 1d",
],
);
let config_path = match app.value("-c") {
Some(values) => {
if values.is_empty() {
exit!("'-c' value: [CONFIG]");
exit!("'-c' missing a value: [FILE]");
}
PathBuf::from(values[0])
}
@@ -91,14 +80,17 @@ async fn main() {
};
// Check profile interval
let watch_interval = match app.value("-w") {
let watch_interval = match app.value("-i") {
Some(values) => {
if values.is_empty() {
exit!("'-w' value: [ms]");
exit!("'-i' missing a value: : [1ms, 1s, 1m, 1h, 1d]");
}
values[0]
.parse::<u64>()
.unwrap_or_else(|_| exit!("Cannot resolve '{}' to number", &values[0]))
config::try_parse_duration(values[0]).unwrap_or_else(|_| {
exit!(
"Cannot resolve '{}' to interval time, format: 1ms, 1s, 1m, 1h, 1d",
&values[0]
)
})
}
None => WATCH_INTERVAL,
};
@@ -166,9 +158,9 @@ async fn main() {
config_path.display()
);
}
"help" => app.help(),
"version" => app.version(),
_ => app.error_try("help"),
"help" => app.print_help(),
"version" => app.print_version(),
_ => app.print_error_try("help"),
}
return;
}
@@ -195,7 +187,7 @@ async fn main() {
watch_config(config_path, watch_interval).await;
}
fn update_config(mut proxy: Vec<SocketAddr>, hosts: Hosts, timeout: Option<u64>) {
fn update_config(mut proxy: Vec<SocketAddr>, hosts: Hosts, timeout: Option<Duration>) {
if proxy.is_empty() {
proxy = DEFAULT_PROXY
.iter()
@@ -234,7 +226,7 @@ fn output_invalid(errors: &[Invalid]) {
}
}
async fn watch_config(p: PathBuf, t: u64) {
async fn watch_config(p: PathBuf, t: Duration) {
let mut watch = Watch::new(&p, t).await;
while let Some(_) = watch.next().await {
@@ -288,7 +280,7 @@ async fn proxy(buf: &[u8]) -> Result<Vec<u8>> {
for addr in proxy.iter() {
let mut socket = UdpSocket::bind(("0.0.0.0", 0)).await?;
let data: Result<Vec<u8>> = timeout(Duration::from_millis(unsafe { TIMEOUT }), async {
let data: Result<Vec<u8>> = timeout(unsafe { TIMEOUT }, async {
socket.send_to(&buf, addr).await?;
let mut res = [0; 512];
let len = socket.recv(&mut res).await?;

View File

@@ -19,13 +19,13 @@ pub struct Watch {
}
impl Watch {
pub async fn new<P: AsRef<Path>>(path: P, duration: u64) -> Watch {
pub async fn new<P: AsRef<Path>>(path: P, duration: Duration) -> Watch {
let path = path.as_ref().to_path_buf();
Watch {
path: path.clone(),
state: None,
modified: Self::modified(path).await,
timer: interval(Duration::from_millis(duration)),
timer: interval(duration),
}
}