You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
use clap::{Arg,Command,ArgAction};fnmain(){let matches = Command::new("My Test Program").version("0.1.0").author("Hackerman Jones <[email protected]>").about("Teaches argument parsing").arg(Arg::new("file")// 用于后续的查找.short('f')// 短.long("file")// 长.value_name("FILE")// help时的提示,类似于--file <FILE>.action(ArgAction::Set)// 指定解析参数时的方法.help("A cool file"))// help的帮助.arg(Arg::new("num")// 当没设置.short('n') 和 .long("num") 时,为位置参数。.action(ArgAction::Set).value_parser([1,2,3,4,5])// 参数限制.help("Five less than your favorite number")).get_matches();let fi = "input.txt".to_string();let myfile = matches.get_one::<String>("file").unwrap_or(&fi);println!("The file passed is: {}", myfile);let num_str = matches.get_one::<String>("num");match num_str {None => println!("No idea what your favorite number is."),Some(s) => {match s.parse::<i32>(){Ok(n) => println!("Your favorite number is {}.", n),Err(_) => println!("That's not a number! {}", s),}}}}
use clap::Parser;#[derive(Parser,Debug)]#[command(name = "test")]#[command(author = "louivis")]#[command(version = "1.0")]#[command(about = "clap", long_about = "a tutorial of crate clap")]structArgs{/// Name of the person to greet#[arg(short='a', long="abc")]name:String,/// Number of times to greet#[arg(short, long, default_value_t = 1)]count:u8,/// phonephone:Option<String>,}fnmain(){let args = Args::parse();for _ in0..args.count{println!("Hello {}!", args.name)}}
parse_with_params
定义了一个名为parse_with_params的函数,它接受一个字符串切片input和一个实现了IntoIterator trait的迭代器iter。函数的目的是解析带有参数的URL,并返回一个Url类型的结果或者一个ParseError错误。其中:<I as IntoIterator>::Item: Borrow<(K, V)> :指定了I迭代器的元素类型必须实现Borrow trait,以便可以借用一个元组 (K, V)。这里<I as IntoIterator>::Item表示从 I 类型转换成的迭代器的元素类型; K: AsRef<str> : 指定了泛型参数 K 必须实现 AsRef<str> trait,这意味着 K 的类型可以被转换为字符串切片的引用。
use log::info;use env_logger::fmt::Target;use std::fs::OpenOptions;fnmain(){let file = OpenOptions::new().create(true).write(true).truncate(true).open("app.log").expect("Failed to open log file");
env_logger::builder().default_format().target(Target::Pipe(Box::new(file))).init();info!("starting up");println!("hello world");}
# Scan this file for changes every 30 secondsrefresh_rate: 30 secondsappenders:
# An appender named "stdout" that writes to stdoutstdout:
kind: consoleerror:
kind: filepath: "log/error.log"encoder:
pattern: "{d(%Y-%m-%d %H:%M:%S)} - {m}{n}"# An appender named "requests" that writes to a file with a custom pattern encoderrequests:
kind: filepath: "log/requests.log"encoder:
pattern: "{d} - {m}{n}"# Set the default logging level to "warn" and attach the "stdout" appender to the rootroot:
level: infoappenders:
- error
- stdoutloggers:
# Raise the maximum log level for events sent to the "app::backend::db" logger to "info"app::backend::db:
level: info# Route log events sent to the "app::requests" logger to the "requests" appender,# and *not* the normal appenders installed at the rootapp::requests:
level: infoappenders:
- requestsadditive: false
use log;use log4rs;fnmain(){
log4rs::init_file("target/config/config.yaml",Default::default()).unwrap();
log::info!("starting up");println!("hello world");}
命令行解析
默认:
env::args().collect()
使用clap解析
参数分为 可选参数(Options) 和 位置参数(Arguments)。
使用Builder模式构建命令行参数
使用衍生宏构建命令行参数
///
开始的 是--help
时的解释。#[arg(short, long)]
或#[arg(long="xyz", short='x')]
或#[arg(short, long, default_value_t = 1)]
标注的为可选参数。json解析
使用serde_json解析json。
Cargo.toml文件添加:
例子:
HTTP
使用reqwest发送请求
Cargo.toml文件添加:
简单请求:
复杂请求:
解释上述用到的几个方法:
定义了一个名为
parse_with_params
的函数,它接受一个字符串切片input
和一个实现了IntoIterator trait
的迭代器iter
。函数的目的是解析带有参数的URL,并返回一个Url
类型的结果或者一个ParseError
错误。其中:<I as IntoIterator>::Item: Borrow<(K, V)>
:指定了I
迭代器的元素类型必须实现Borrow trait
,以便可以借用一个元组(K, V)
。这里<I as IntoIterator>::Item
表示从 I 类型转换成的迭代器的元素类型;K: AsRef<str>
: 指定了泛型参数 K 必须实现AsRef<str> trait
,这意味着 K 的类型可以被转换为字符串切片的引用。日志记录
日志库通常会支持:日志分级、日志过滤、日志输出格式化、日志回滚等功能。
Log是Rust的轻量级日志接口。它抽象了日志实现,很好的兼容不同日志库。有大量日志库基于它实现的,最常用env_looger,log4rs等。
定义了如下等级:
Log只是个接口,实际还需要设置具体的日志库。如果没有设置具体的日志库,那么log门面库就退化成noop实现,也就是忽略所有的日志。
具体实现
env_logger
例子:
通过环境变量RUST_LOG控制日志等级。
env_logger 也可以通过Builder的format方法自定义日志格式:
也可以通过target方法自定义输出目标。
log4rs
log4j组件:
能输出日志到文件和控制台两种方式。配置方式:可以使用外部 yaml 文件,也可以通过生成器配置。
日志格式说明:https://docs.rs/log4rs/1.3.0/log4rs/encode/pattern/index.html#formatters
创建target/config/config.yaml文件
$ ./target/debug/test_log4rs 2024-03-19T10:43:17.403894+08:00 WARN syslog - File syslog warn 2024-03-19T10:43:17.403957+08:00 INFO businesslog - File businesslog info 2024-03-19T10:43:17.403967+08:00 WARN my_log - hello, warn!!! $ cat logs/sys.log 2024-03-19T10:43:17.403633+08:00 - File syslog warn $ cat logs/business.log 2024-03-19T10:43:17.403922+08:00 - File businesslog info
分布式跟踪
tracing 可以作为一个日志库使用,更重要的是一个分布式跟踪的 SDK,用于采集监控数据的,帮助我们分析程序中存在的问题。
分布式跟踪的核心就是在请求的开始生成一个 trace_id,然后将该 trace_id 一直往后透穿,请求经过的每个服务都会使用该 trace_id 记录相关信息,最终将整个请求形成一个完整的链路予以记录下来。
配合tracing-appender支持输出到文件。
tracing 使用 event 发出日志,使用 subscriber 收集日志。
各个模块:
The text was updated successfully, but these errors were encountered: