diff --git a/Cargo.lock b/Cargo.lock
index f947c7f..80c6943 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -775,6 +775,8 @@ dependencies = [
"csv",
"recipes",
"static_dir",
+ "tracing",
+ "tracing-subscriber",
"warp",
]
@@ -1026,9 +1028,9 @@ dependencies = [
[[package]]
name = "once_cell"
-version = "1.10.0"
+version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
+checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
[[package]]
name = "opaque-debug"
@@ -1310,6 +1312,15 @@ dependencies = [
"digest 0.10.3",
]
+[[package]]
+name = "sharded-slab"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31"
+dependencies = [
+ "lazy_static",
+]
+
[[package]]
name = "slab"
version = "0.4.5"
@@ -1460,6 +1471,15 @@ dependencies = [
"syn",
]
+[[package]]
+name = "thread_local"
+version = "1.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180"
+dependencies = [
+ "once_cell",
+]
+
[[package]]
name = "time"
version = "0.1.43"
@@ -1547,23 +1567,61 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
[[package]]
name = "tracing"
-version = "0.1.31"
+version = "0.1.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6c650a8ef0cd2dd93736f033d21cbd1224c5a967aa0c258d00fcf7dafef9b9f"
+checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160"
dependencies = [
"cfg-if",
"log",
"pin-project-lite",
+ "tracing-attributes",
"tracing-core",
]
[[package]]
-name = "tracing-core"
+name = "tracing-attributes"
version = "0.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03cfcb51380632a72d3111cb8d3447a8d908e577d31beeac006f836383d29a23"
+checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b7358be39f2f274f322d2aaed611acc57f382e8eb1e5b48cb9ae30933495ce7"
+dependencies = [
+ "once_cell",
+ "valuable",
+]
+
+[[package]]
+name = "tracing-log"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922"
dependencies = [
"lazy_static",
+ "log",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-subscriber"
+version = "0.3.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3a713421342a5a666b7577783721d3117f1b69a393df803ee17bb73b1e122a59"
+dependencies = [
+ "ansi_term",
+ "sharded-slab",
+ "smallvec",
+ "thread_local",
+ "tracing-core",
+ "tracing-log",
]
[[package]]
@@ -1666,6 +1724,12 @@ version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
+[[package]]
+name = "valuable"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
+
[[package]]
name = "value-bag"
version = "1.0.0-alpha.8"
diff --git a/kitchen/Cargo.toml b/kitchen/Cargo.toml
index 288315d..8699bc6 100644
--- a/kitchen/Cargo.toml
+++ b/kitchen/Cargo.toml
@@ -7,6 +7,8 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
+tracing = "0.1.35"
+tracing-subscriber = "0.3.14"
recipes = {path = "../recipes" }
csv = "1.1.1"
warp = "0.3.2"
diff --git a/kitchen/src/cli.rs b/kitchen/src/cli.rs
index 89f7e9e..d450271 100644
--- a/kitchen/src/cli.rs
+++ b/kitchen/src/cli.rs
@@ -21,6 +21,7 @@ use csv;
use crate::api::ParseError;
use recipes::{parse, IngredientAccumulator, Recipe};
+use tracing::{error, info, instrument, warn};
// TODO(jwall): We should think a little more closely about
// the error modeling for this application.
@@ -29,13 +30,14 @@ macro_rules! try_open {
match File::open(&$path) {
Ok(reader) => reader,
Err(e) => {
- eprintln!("Error opening file for read: {:?}", $path);
+ error!(path=?$path, "Error opening file for read");
return Err(ParseError::from(e));
}
}
};
}
+#[instrument]
pub fn parse_recipe
(path: P) -> Result
where
P: AsRef + Debug,
@@ -47,6 +49,7 @@ where
Ok(parse::as_recipe(&i)?)
}
+#[instrument]
pub fn read_menu_list(path: P) -> Result, ParseError>
where
P: AsRef + Debug,
@@ -54,7 +57,7 @@ where
let path = path.as_ref();
let wd = path.parent().unwrap();
let mut br = BufReader::new(try_open!(path));
- eprintln!("Switching to {:?}", wd);
+ info!(directory=?wd, "Switching working directory");
std::env::set_current_dir(wd)?;
let mut buf = String::new();
let mut recipe_list = Vec::new();
diff --git a/kitchen/src/main.rs b/kitchen/src/main.rs
index d0a3081..bf7bea5 100644
--- a/kitchen/src/main.rs
+++ b/kitchen/src/main.rs
@@ -12,11 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use std::env;
+use std::io;
use std::net::SocketAddr;
use std::path::PathBuf;
use clap;
use clap::{clap_app, crate_authors, crate_version};
+use tracing::{error, info, instrument, warn, Level};
+use tracing_subscriber::FmtSubscriber;
pub mod api;
mod cli;
@@ -30,6 +33,7 @@ where
(version: crate_version!())
(author: crate_authors!())
(about: "Kitchen Management CLI")
+ (@arg verbose: --verbose -v "Verbosity level for logging (error, warn, info, debug, trace")
(@subcommand recipe =>
(about: "parse a recipe file and output info about it")
(@arg ingredients: -i --ingredients "Output the ingredients list.")
@@ -49,8 +53,29 @@ where
.setting(clap::AppSettings::SubcommandRequiredElseHelp)
}
+#[instrument]
fn main() {
let matches = create_app().get_matches();
+ let subscriber_builder = if let Some(verbosity) = matches.value_of("verbosity") {
+ // Se want verbosity level
+ let level = match verbosity {
+ "error" | "ERROR" => Level::ERROR,
+ "warn" | "WARN" => Level::WARN,
+ "info" | "INFO" => Level::INFO,
+ "debug" | "DEBUG" => Level::DEBUG,
+ "trace" | "TRACE" => Level::TRACE,
+ _ => {
+ println!("Invalid logging level using TRACE");
+ Level::TRACE
+ }
+ };
+ FmtSubscriber::builder().with_max_level(level)
+ } else {
+ FmtSubscriber::builder().with_max_level(Level::INFO)
+ };
+ tracing::subscriber::set_global_default(subscriber_builder.with_writer(io::stderr).finish())
+ .expect("setting default subscriber failed");
+
if let Some(matches) = matches.subcommand_matches("recipe") {
// The input argument is required so if we made it here then it's safe to unrwap this value.
let recipe_file = matches.value_of("INPUT").unwrap();
@@ -58,8 +83,8 @@ fn main() {
Ok(r) => {
cli::output_recipe_info(r, matches.is_present("ingredients"));
}
- Err(e) => {
- eprintln!("{:?}", e);
+ Err(err) => {
+ error!(?err);
}
}
} else if let Some(matches) = matches.subcommand_matches("groceries") {
@@ -73,8 +98,8 @@ fn main() {
cli::output_ingredients_list(rs);
}
}
- Err(e) => {
- eprintln!("{:?}", e);
+ Err(err) => {
+ error!(?err);
}
}
} else if let Some(matches) = matches.subcommand_matches("serve") {
@@ -91,8 +116,7 @@ fn main() {
} else {
"127.0.0.1:3030".parse().unwrap()
};
- println!("Launching web interface...");
- println!("listening on {}", listen_socket);
+ info!(listen=%listen_socket, "Launching web interface...");
async_std::task::block_on(async { web::ui_main(recipe_dir_path, listen_socket).await });
}
}
diff --git a/kitchen/src/web.rs b/kitchen/src/web.rs
index bcec864..d45e3cf 100644
--- a/kitchen/src/web.rs
+++ b/kitchen/src/web.rs
@@ -17,10 +17,12 @@ use std::path::PathBuf;
use async_std::fs::{self, read_dir, read_to_string, DirEntry};
use async_std::stream::StreamExt;
use static_dir::static_dir;
+use tracing::{info, instrument, warn};
use warp::{http::StatusCode, hyper::Uri, Filter};
use crate::api::ParseError;
+#[instrument(fields(recipe_dir=?recipe_dir_path), skip_all)]
pub async fn get_recipes(recipe_dir_path: PathBuf) -> Result, ParseError> {
let mut entries = read_dir(recipe_dir_path).await?;
let mut entry_vec = Vec::new();
@@ -35,19 +37,20 @@ pub async fn get_recipes(recipe_dir_path: PathBuf) -> Result, ParseE
.any(|&s| s == entry.file_name().to_string_lossy().to_string())
{
// add it to the entry
- eprintln!("adding recipe file {}", entry.file_name().to_string_lossy());
+ info!("adding recipe file {}", entry.file_name().to_string_lossy());
let recipe_contents = read_to_string(entry.path()).await?;
entry_vec.push(recipe_contents);
} else {
- eprintln!(
- "skipping file {} not a recipe",
- entry.path().to_string_lossy()
+ warn!(
+ file = %entry.path().to_string_lossy(),
+ "skipping file not a recipe",
);
}
}
Ok(entry_vec)
}
+#[instrument(fields(recipe_dir=?recipe_dir_path,listen=?listen_socket), skip_all)]
pub async fn ui_main(recipe_dir_path: PathBuf, listen_socket: SocketAddr) {
let root = warp::path::end().map(|| warp::redirect::found(Uri::from_static("/ui")));
let ui = warp::path("ui").and(static_dir!("../web/dist"));
@@ -56,7 +59,7 @@ pub async fn ui_main(recipe_dir_path: PathBuf, listen_socket: SocketAddr) {
// recipes api path route
let recipe_path = warp::path("recipes").then(move || {
let dir_path = (&dir_path).clone();
- eprintln!("servicing recipe api request.");
+ info!(?dir_path, "servicing recipe api request.");
async move {
match get_recipes(dir_path).await {
Ok(recipes) => {
@@ -74,7 +77,7 @@ pub async fn ui_main(recipe_dir_path: PathBuf, listen_socket: SocketAddr) {
let mut file_path = (&recipe_dir_path).clone();
file_path.push("categories.txt");
let categories_path = warp::path("categories").then(move || {
- eprintln!("servicing category api request");
+ info!(?file_path, "servicing category api request");
let file_path = (&file_path).clone();
async move {
match fs::metadata(&file_path).await {