diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index aeef9ab..ec1bc7a 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -14,6 +14,7 @@ "terminal.integrated.defaultProfile.linux": "zsh", "rust-analyzer.check.command": "clippy", "evenBetterToml.formatter.alignEntries": true, + "evenBetterToml.formatter.columnWidth": 100, "[rust]": { "editor.defaultFormatter": "rust-lang.rust-analyzer" }, diff --git a/.gitignore b/.gitignore index 60e3942..15ba9b6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ *.chls *.chlz - # Added by cargo /target diff --git a/Cargo.lock b/Cargo.lock index ae2103e..4e702d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -97,12 +97,6 @@ version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" -[[package]] -name = "arc-swap" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" - [[package]] name = "async-stream" version = "0.3.6" @@ -122,7 +116,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] [[package]] @@ -173,12 +167,12 @@ dependencies = [ "clap", "directories", "futures-util", - "log", - "log4rs", "rpassword", "serde", "serde_json", "tokio", + "tracing", + "tracing-subscriber", ] [[package]] @@ -192,12 +186,12 @@ dependencies = [ "cookie_store", "futures-util", "lazy_static", - "log", "regex", "reqwest", "reqwest_cookie_store", "serde", "serde_json", + "tracing", ] [[package]] @@ -206,12 +200,6 @@ version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - [[package]] name = "bytes" version = "1.9.0" @@ -278,7 +266,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] [[package]] @@ -347,23 +335,6 @@ dependencies = [ "powerfmt", ] -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "destructure_traitobject" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c877555693c14d2f84191cfd3ad8582790fc52b5e2274b40b59cf5f5cea25c7" - [[package]] name = "directories" version = "5.0.1" @@ -393,7 +364,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] [[package]] @@ -489,7 +460,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] [[package]] @@ -606,12 +577,6 @@ version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - [[package]] name = "hyper" version = "1.5.2" @@ -822,7 +787,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] [[package]] @@ -936,45 +901,17 @@ dependencies = [ [[package]] name = "log" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" -dependencies = [ - "serde", -] - -[[package]] -name = "log-mdc" -version = "0.1.0" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a94d21414c1f4a51209ad204c1776a3d0765002c76c6abcb602a6f09f1e881c7" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] -name = "log4rs" -version = "1.3.0" +name = "matchers" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0816135ae15bd0391cf284eab37e6e3ee0a6ee63d2ceeb659862bd8d0a984ca6" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" dependencies = [ - "anyhow", - "arc-swap", - "chrono", - "derivative", - "fnv", - "humantime", - "libc", - "log", - "log-mdc", - "once_cell", - "parking_lot", - "rand", - "serde", - "serde-value", - "serde_json", - "serde_yaml", - "thiserror", - "thread-id", - "typemap-ors", - "winapi", + "regex-automata", ] [[package]] @@ -1036,6 +973,15 @@ dependencies = [ "tempfile", ] +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys 0.59.0", +] + [[package]] name = "num-conv" version = "0.1.0" @@ -1089,7 +1035,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] [[package]] @@ -1116,15 +1062,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" -[[package]] -name = "ordered-float" -version = "2.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" -dependencies = [ - "num-traits", -] - [[package]] name = "parking_lot" version = "0.12.3" @@ -1178,15 +1115,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" -[[package]] -name = "ppv-lite86" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy", -] - [[package]] name = "proc-macro2" version = "1.0.93" @@ -1221,36 +1149,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - [[package]] name = "redox_syscall" version = "0.5.8" @@ -1512,16 +1410,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde-value" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" -dependencies = [ - "ordered-float", - "serde", -] - [[package]] name = "serde_derive" version = "1.0.217" @@ -1530,7 +1418,7 @@ checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] [[package]] @@ -1558,16 +1446,12 @@ dependencies = [ ] [[package]] -name = "serde_yaml" -version = "0.9.34+deprecated" +name = "sharded-slab" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ - "indexmap", - "itoa", - "ryu", - "serde", - "unsafe-libyaml", + "lazy_static", ] [[package]] @@ -1634,17 +1518,6 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.96" @@ -1673,7 +1546,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] [[package]] @@ -1728,17 +1601,16 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] [[package]] -name = "thread-id" -version = "4.2.2" +name = "thread_local" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfe8f25bbdd100db7e1d34acf7fd2dc59c4bf8f7483f505eaa7d4f12f76cc0ea" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" dependencies = [ - "libc", - "winapi", + "cfg-if", ] [[package]] @@ -1808,7 +1680,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] [[package]] @@ -1879,9 +1751,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tracing-core" version = "0.1.33" @@ -1889,49 +1773,68 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", + "valuable", ] [[package]] -name = "try-lock" -version = "0.2.5" +name = "tracing-log" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] [[package]] -name = "typemap-ors" -version = "1.0.0" +name = "tracing-serde" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a68c24b707f02dd18f1e4ccceb9d49f2058c2fb86384ef9972592904d7a28867" +checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1" dependencies = [ - "unsafe-any-ors", + "serde", + "tracing-core", ] [[package]] -name = "unicase" -version = "2.8.1" +name = "tracing-subscriber" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" +checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", +] [[package]] -name = "unicode-ident" -version = "1.0.14" +name = "try-lock" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] -name = "unsafe-any-ors" -version = "1.0.0" +name = "unicase" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a303d30665362d9680d7d91d78b23f5f899504d4f08b3c4cf08d055d87c0ad" -dependencies = [ - "destructure_traitobject", -] +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] -name = "unsafe-libyaml" -version = "0.2.11" +name = "unicode-ident" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "untrusted" @@ -1968,6 +1871,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + [[package]] name = "vcpkg" version = "0.2.15" @@ -2017,7 +1926,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.96", + "syn", "wasm-bindgen-shared", ] @@ -2052,7 +1961,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2076,28 +1985,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - [[package]] name = "windows-core" version = "0.52.0" @@ -2317,31 +2204,10 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", "synstructure", ] -[[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "byteorder", - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.96", -] - [[package]] name = "zerofrom" version = "0.1.5" @@ -2359,7 +2225,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", "synstructure", ] @@ -2388,5 +2254,5 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] diff --git a/Cargo.toml b/Cargo.toml index b76440e..a0a2dda 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,17 +7,17 @@ repository = "https://github.com/azerpas/bourso-api" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bourso_api = { path = "./src/bourso_api" } -tokio = { version = "1.33.0", features = ["full"] } -anyhow = { version = "1.0.75" } -clap = { version = "4.4.6" } -rpassword = { version = "7.2.0" } -directories = { version = "5.0.1" } -serde = { version = "1.0.189", features = ["derive"] } -serde_json = { version = "1.0.107" } -log = { version = "0.4.20" } -log4rs = { version = "1.3.0" } -futures-util = { version = "0.3.31"} +bourso_api = { path = "./src/bourso_api" } +tokio = { version = "1.33.0", features = ["full"] } +anyhow = { version = "1.0.75" } +clap = { version = "4.4.6" } +rpassword = { version = "7.2.0" } +directories = { version = "5.0.1" } +serde = { version = "1.0.189", features = ["derive"] } +serde_json = { version = "1.0.107" } +tracing = { version = "0.1.41" } +tracing-subscriber = { version = "0.3.20", features = ["fmt", "env-filter", "json"] } +futures-util = { version = "0.3.31" } [lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tarpaulin_include)'] } diff --git a/src/bourso_api/Cargo.toml b/src/bourso_api/Cargo.toml index 56e6356..7365fb7 100644 --- a/src/bourso_api/Cargo.toml +++ b/src/bourso_api/Cargo.toml @@ -16,7 +16,7 @@ serde_json = { version = "1.0.107" } reqwest_cookie_store = { version = "0.8.0" } cookie_store = { version = "0.21.1" } chrono = { version = "0.4.39" } -log = { version = "0.4.20" } +tracing = { version = "0.1.41" } futures-util = { version = "0.3.31" } async-stream = { version = "0.3.6" } diff --git a/src/bourso_api/src/client/account.rs b/src/bourso_api/src/client/account.rs index 878df80..a4fdf2e 100644 --- a/src/bourso_api/src/client/account.rs +++ b/src/bourso_api/src/client/account.rs @@ -8,8 +8,8 @@ use crate::{ use super::BoursoWebClient; use anyhow::{Context, Result}; -use log::debug; use regex::Regex; +use tracing::debug; impl BoursoWebClient { /// Get the accounts list. diff --git a/src/bourso_api/src/client/mod.rs b/src/bourso_api/src/client/mod.rs index 497b1ca..16992a3 100644 --- a/src/bourso_api/src/client/mod.rs +++ b/src/bourso_api/src/client/mod.rs @@ -11,10 +11,10 @@ use std::sync::Arc; use anyhow::{bail, Result}; use cookie_store::Cookie; use error::ClientError; -use log::{debug, error, info}; use regex::Regex; use reqwest_cookie_store::{CookieStore, CookieStoreMutex}; use serde::{Deserialize, Serialize}; +use tracing::{debug, error, info}; use self::config::{extract_brs_config, Config}; diff --git a/src/bourso_api/src/client/trade/order.rs b/src/bourso_api/src/client/trade/order.rs index a121d2a..9df813c 100644 --- a/src/bourso_api/src/client/trade/order.rs +++ b/src/bourso_api/src/client/trade/order.rs @@ -1,7 +1,7 @@ use anyhow::{Context, Result}; -use log::{debug, info}; use serde::{Deserialize, Serialize}; use serde_json::Value; +use tracing::{debug, info}; use crate::{ account::{Account, AccountKind}, @@ -89,8 +89,15 @@ impl BoursoWebClient { .await?; info!( - "Order for {} {} successfully passed with ID {} ✅", - quantity, symbol, response.order_id + quantity, + symbol, + order_id = response.order_id, + order_price_limit = order_data.order_price_limit, + "Order for {} {} successfully passed with ID {} at price {:?} ✅", + quantity, + symbol, + response.order_id, + order_data.order_price_limit ); Ok((response.order_id, order_data.order_price_limit)) diff --git a/src/bourso_api/src/client/transfer/mod.rs b/src/bourso_api/src/client/transfer/mod.rs index e38c05b..f70148b 100644 --- a/src/bourso_api/src/client/transfer/mod.rs +++ b/src/bourso_api/src/client/transfer/mod.rs @@ -3,6 +3,7 @@ use crate::account::{Account, AccountKind}; use crate::{client::transfer::error::TransferError, client::BoursoWebClient, constants::BASE_URL}; use anyhow::{bail, Context, Result}; use futures_util::stream::Stream; +use tracing::debug; mod error; @@ -70,7 +71,7 @@ impl BoursoWebClient { let res = self.client.get(&init_transfer_url).send().await?; if res.status() != 302 { - log::debug!("Init transfer response: {:?}", res); + debug!("Init transfer response: {:?}", res); bail!(TransferError::TransferInitiationFailed); } @@ -97,7 +98,7 @@ impl BoursoWebClient { let res = self.client.get(url).send().await?; if res.status() != 200 { - log::debug!("First transfer step response: {:?}", res); + debug!("First transfer step response: {:?}", res); bail!(TransferError::TransferInitiationFailed); } @@ -138,7 +139,7 @@ impl BoursoWebClient { let res = self.client.post(&url).multipart(data).send().await?; if res.status() != 200 { - log::debug!("Set debit account response: {:?}", res); + debug!("Set debit account response: {:?}", res); bail!(TransferError::SetDebitAccountFailed); } @@ -177,7 +178,7 @@ impl BoursoWebClient { let res = self.client.post(&url).multipart(data).send().await?; if res.status() != 200 { - log::debug!("Set credit account response: {:?}", res); + debug!("Set credit account response: {:?}", res); bail!(TransferError::SetCreditAccountFailed); } @@ -211,7 +212,7 @@ impl BoursoWebClient { let res = self.client.post(&url).multipart(data).send().await?; if res.status() != 200 { - log::debug!("Set amount response: {:?}", res); + debug!("Set amount response: {:?}", res); bail!(TransferError::SetAmountFailed); } @@ -246,7 +247,7 @@ impl BoursoWebClient { .await?; if res.status() != 200 { - log::debug!("Submit transfer response: {:?}", res); + debug!("Submit transfer response: {:?}", res); bail!(TransferError::Step7Failed); } @@ -282,7 +283,7 @@ impl BoursoWebClient { let res = self.client.post(&url).multipart(data).send().await?; if res.status() != 200 { - log::debug!("Set reason response: {:?}", res); + debug!("Set reason response: {:?}", res); bail!(TransferError::SetReasonFailed); } @@ -318,7 +319,7 @@ impl BoursoWebClient { .await?; if res.status() != 200 { - log::debug!("Confirm transfer response: {:?}", res); + debug!("Confirm transfer response: {:?}", res); bail!(TransferError::SubmitTransferFailed); } @@ -327,7 +328,7 @@ impl BoursoWebClient { if body.as_str().contains("Confirmation") { Ok(()) } else { - log::debug!("Cannot find confirmation message in response {:?}", body); + debug!("Cannot find confirmation message in response {:?}", body); bail!(TransferError::InvalidTransfer); } } @@ -359,7 +360,7 @@ impl BoursoWebClient { return; } - log::debug!( + debug!( "Initiating transfer of {:.2} EUR from account {} to account {}", amount, from_account.id, diff --git a/src/lib.rs b/src/lib.rs index 9876bac..84d1235 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,16 +10,15 @@ use bourso_api::{ }; use clap::ArgMatches; use futures_util::{pin_mut, StreamExt}; -use log::{info, warn}; +use tracing::{debug, info, warn}; + +pub mod settings; +pub mod validate; -mod settings; use settings::{get_settings, save_settings, Settings}; -mod validate; #[cfg(not(tarpaulin_include))] pub async fn parse_matches(matches: ArgMatches) -> Result<()> { - use log::debug; - let settings = match matches.get_one::("credentials") { Some(credentials_path) => Settings::load(credentials_path)?, None => get_settings()?, @@ -70,16 +69,20 @@ pub async fn parse_matches(matches: ArgMatches) -> Result<()> { match quote_matches.subcommand() { Some(("highest", _)) => { - info!("Highest quote: {:#?}", quotes.d.get_highest_value()); + let highest_quote = quotes.d.get_highest_value(); + info!(highest_quote, "Highest quote: {:#?}", highest_quote); } Some(("lowest", _)) => { - info!("Lowest quote: {:#?}", quotes.d.get_lowest_value()); + let lowest_quote = quotes.d.get_lowest_value(); + info!(lowest_quote, "Lowest quote: {:#?}", lowest_quote); } Some(("volume", _)) => { - info!("Volume: {:#?}", quotes.d.get_volume()); + let volume = quotes.d.get_volume(); + info!(volume, "Volume: {:#?}", volume); } Some(("average", _)) => { - info!("Average quote: {:#?}", quotes.d.get_average_value()); + let average_quote = quotes.d.get_average_value(); + info!(average_quote, "Average quote: {:#?}", average_quote); } Some(("last", _)) => { let quote: QuoteTab; @@ -92,7 +95,8 @@ pub async fn parse_matches(matches: ArgMatches) -> Result<()> { } info!( - "Last quote: current: {}, open: {}, high: {}, low: {}, volume: {}", + close = quote.close, open = quote.open, high = quote.high, low = quote.low, volume = quote.volume, + "Last quote: current: {:#?}, open: {:#?}, high: {:#?}, low: {:#?}, volume: {:#?}", quote.close, quote.open, quote.high, quote.low, quote.volume ); } @@ -100,13 +104,9 @@ pub async fn parse_matches(matches: ArgMatches) -> Result<()> { info!("Quotes:"); for quote in quotes.d.quote_tab.iter() { info!( - "Quote day {}: Close: {}, Open: {}, High: {}, Low: {}, Volume: {}", - quote.date, - quote.close, - quote.open, - quote.high, - quote.low, - quote.volume + date = quote.date, close = quote.close, open = quote.open, high = quote.high, low = quote.low, volume = quote.volume, + "Quote day {:#?}: Close: {:#?}, Open: {:#?}, High: {:#?}, Low: {:#?}, Volume: {:#?}", + quote.date, quote.close, quote.open, quote.high, quote.low, quote.volume, ); } } diff --git a/src/main.rs b/src/main.rs index a1077b0..b155f0f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,32 +1,21 @@ use anyhow::Result; use bourso_api::client::trade::order::OrderSide; +use bourso_cli::{settings::init_logger, validate::validate_account_id}; use clap::{ builder::{PossibleValue, ValueParser}, Arg, Command, }; -use log::debug; -use validate::validate_account_id; - -use crate::settings::init_logger; - -mod settings; -mod validate; - #[tokio::main] async fn main() -> Result<()> { const VERSION: Option<&str> = option_env!("CARGO_PKG_VERSION"); - debug!("Version: {:?}", VERSION); init_logger()?; let account_arg = Arg::new("account") .short('a') .long("account") - .help( - r#"The account to use by its 'id' (e.g: 'e51f635524a7d506e4d4a7a8088b6278'). - You can get this info with the command `bourso accounts`"#, - ) + .help("The account to use by its 'id' (e.g: 'e51f635524a7d506e4d4a7a8088b6278'). You can get this info with the command `bourso accounts`") .value_parser(clap::value_parser!(String)) // Enforce input as String .value_parser(ValueParser::new(validate_account_id)) .required(true); diff --git a/src/settings.rs b/src/settings.rs index 0c538cb..580fd7c 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -1,16 +1,5 @@ use anyhow::{Context, Result}; use directories::UserDirs; -use log::LevelFilter; -use log4rs::{ - append::{ - console::{ConsoleAppender, Target}, - file::FileAppender, - }, - config::{Appender, Root}, - encode::pattern::PatternEncoder, - filter::threshold::ThresholdFilter, - Config, -}; use serde::{Deserialize, Serialize}; use std::fs; use std::io::prelude::*; @@ -25,7 +14,6 @@ pub struct Settings { #[cfg(not(tarpaulin_include))] impl Settings { - #[allow(dead_code)] // Not sure why, but rustc thinks this is unused pub fn load(path: &str) -> Result { let file_content = match fs::read_to_string(path) { Ok(data) => data, @@ -46,7 +34,6 @@ impl Settings { } #[cfg(not(tarpaulin_include))] -#[allow(dead_code)] // Not sure why, but rustc thinks this is unused pub fn get_settings() -> Result { let user_dirs = UserDirs::new().context("Failed to get user directories")?; let mut path = user_dirs.home_dir().to_path_buf(); @@ -77,7 +64,6 @@ pub fn get_settings() -> Result { /// Save the settings to the settings file, if it doesn't exist, create it #[cfg(not(tarpaulin_include))] -#[allow(dead_code)] // Not sure why, but rustc thinks this is unused pub fn save_settings(settings: &Settings) -> Result<()> { let user_dirs = UserDirs::new().context("Failed to get user directories")?; let mut path = user_dirs.home_dir().to_path_buf(); @@ -92,93 +78,59 @@ pub fn save_settings(settings: &Settings) -> Result<()> { Ok(()) } -#[cfg(not(tarpaulin_include))] -#[allow(dead_code)] // Not sure why, but rustc thinks this is unused pub fn init_logger() -> Result<()> { - use std::env; - - use log::debug; - - let log_level = match env::var("RUST_LOG") { - Ok(level) => match level.as_str() { - "trace" => LevelFilter::Trace, - "debug" => LevelFilter::Debug, - "info" => LevelFilter::Info, - "warn" => LevelFilter::Warn, - "error" => LevelFilter::Error, - _ => { - env::set_var("RUST_LOG", "info"); - LevelFilter::Info - } - }, - Err(_) => { - env::set_var("RUST_LOG", "info"); - LevelFilter::Info - } - }; + use std::io::IsTerminal; + use std::{fs, io}; + use tracing_subscriber::filter::LevelFilter; + use tracing_subscriber::{fmt, prelude::*, EnvFilter}; - debug!("Log level: {:?}", log_level); + let env_filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info")); - // Create the .bourso directory if it doesn't exist + // Create ~/.bourso/bourso.log if it doesn't exist let user_dirs = UserDirs::new().context("Failed to get user directories")?; let mut path = user_dirs.home_dir().to_path_buf(); - path = path.join(".bourso"); - + path.push(".bourso"); fs::create_dir_all(&path)?; - path = path.join("bourso.log"); - - let stderr = ConsoleAppender::builder() - .target(Target::Stderr) - .encoder(Box::new(PatternEncoder::new("{h({l})} {M} > {m}{n}"))) - .build(); - - let logfile = FileAppender::builder() - .encoder(Box::new(PatternEncoder::new("{d} [{t}] {l} {M} > {m}{n}"))) - .build(path) - .unwrap(); - - let config = Config::builder() - .appender(Appender::builder().build("logfile", Box::new(logfile))) - .appender( - Appender::builder() - .filter(Box::new(ThresholdFilter::new(log_level))) - .build("stderr", Box::new(stderr)), - ) - .build( - Root::builder() - .appender("logfile") - .appender("stderr") - .build(LevelFilter::Trace), - ) - .unwrap(); - - log4rs::init_config(config)?; + path.push("bourso.log"); + + // Pretty console (stderr), filtered by RUST_LOG + let console_layer = fmt::layer() + .with_writer(io::stderr) + .with_ansi(IsTerminal::is_terminal(&io::stderr())) + .with_level(true) + .with_target(true) + .without_time() + .compact() + .fmt_fields({ + fmt::format::debug_fn(move |writer, field, value| { + if field.name() == "message" { + write!(writer, "{:?}", value)?; + } + Ok(()) + }) + }) + .with_filter(env_filter.clone()); + + // JSON file (capture everything) + let log_path = path.clone(); + let json_layer = fmt::layer() + .with_writer(move || { + fs::OpenOptions::new() + .create(true) + .append(true) + .open(&log_path) + .expect("open ~/.bourso/bourso.log") + }) + .json() + .with_target(true) + .with_level(true) + .flatten_event(true) + .with_filter(LevelFilter::TRACE); + + tracing_subscriber::registry() + .with(console_layer) + .with(json_layer) + .init(); Ok(()) } - -#[cfg(test)] -mod tests { - use std::env; - - use log::LevelFilter; - - #[test] - fn test_get_settings() { - let f = match env::var("RUST_LOG") { - Ok(level) => match level.as_str() { - "trace" => LevelFilter::Trace, - "debug" => LevelFilter::Debug, - "info" => LevelFilter::Info, - "warn" => LevelFilter::Warn, - "error" => LevelFilter::Error, - _ => LevelFilter::Info, - }, - Err(_) => { - env::set_var("RUST_LOG", "info"); - LevelFilter::Info - } - }; - assert_eq!(f, LevelFilter::Info); - } -} diff --git a/src/validate.rs b/src/validate.rs index 9919635..7011d93 100644 --- a/src/validate.rs +++ b/src/validate.rs @@ -1,4 +1,3 @@ -#[allow(dead_code)] // Not sure why, but rustc thinks this is unused pub fn validate_account_id(account_id: &str) -> Result { if account_id.trim().len() == 32 { Ok(account_id.to_owned())