feat: logging

This commit is contained in:
Lucas Colombo 2024-04-01 14:15:54 -03:00
parent 38442e5146
commit adb088cadc
Signed by: lucas
GPG Key ID: EF34786CFEFFAE35
9 changed files with 91 additions and 31 deletions

View File

@ -5,7 +5,7 @@
// "entities": true, // "entities": true,
// //
".env": true, // ".env": true,
"Taskfile.yaml": true, "Taskfile.yaml": true,
".cocorc": true, ".cocorc": true,
".task": true, ".task": true,

16
Cargo.lock generated
View File

@ -767,6 +767,7 @@ name = "entities"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"eyre", "eyre",
"lool",
"sea-orm", "sea-orm",
] ]
@ -1095,7 +1096,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"entities", "entities",
"eyre", "eyre",
"log", "lool",
"prost", "prost",
"tonic", "tonic",
"tonic-build", "tonic-build",
@ -1467,6 +1468,17 @@ dependencies = [
"value-bag", "value-bag",
] ]
[[package]]
name = "lool"
version = "0.0.5"
source = "sparse+http://lugit.local/api/packages/lucodear/cargo/"
checksum = "c727e0c375380178e0b15f8f54f249e5e2a9e72c20475e8a7807f4c72d253106"
dependencies = [
"bitflags 2.5.0",
"eyre",
"log",
]
[[package]] [[package]]
name = "matchers" name = "matchers"
version = "0.1.0" version = "0.1.0"
@ -2250,7 +2262,7 @@ dependencies = [
"entities", "entities",
"eyre", "eyre",
"grpc", "grpc",
"log", "lool",
"tokio", "tokio",
] ]

View File

@ -25,8 +25,8 @@ path = "app/main.rs"
members = [".", "migration", "entities", "grpc"] members = [".", "migration", "entities", "grpc"]
[workspace.dependencies] [workspace.dependencies]
log = { version = "0.4.21" } lool = { version = "0.0.5", registry = "lugit" } # crates: disable-check
eyre = { version = "0.6.12" } eyre = { version = "0.6.12", default-features = false }
[dependencies] [dependencies]
# internal # internal
@ -34,8 +34,8 @@ entities = { path = "entities" }
grpc = { path = "grpc" } grpc = { path = "grpc" }
# workspace # workspace
log = { workspace = true }
eyre = { workspace = true, default-features = false, features = ["auto-install"] } eyre = { workspace = true, default-features = false, features = ["auto-install"] }
lool = { workspace = true, features = ["logger", "macros", "cli-stylize"] }
# external # external
tokio = { version = "1.36.0", features = ["macros", "rt-multi-thread"] } tokio = { version = "1.36.0", features = ["macros", "rt-multi-thread"] }

View File

@ -37,4 +37,4 @@ tasks:
lint: lint:
desc: 🧶 lint rustler desc: 🧶 lint rustler
cmds: cmds:
- cargo clippy --fix --workspace --allow-dirty - cargo clippy --fix --workspace --allow-staged

View File

@ -1,16 +1,21 @@
use {dotenvy::dotenv, eyre::Result, log::info}; use {
dotenvy::dotenv,
eyre::Result,
lool::logger::{info, ConsoleLogger, Level},
};
// TODO: here we will trigger the start of both the grpc server and the websocket gateway // TODO: here we will trigger the start of both the grpc server and the websocket gateway
// look at: https://github.com/hyperium/tonic/discussions/740 // look at: https://github.com/hyperium/tonic/discussions/740
#[tokio::main] #[tokio::main]
async fn main() -> Result<()> { async fn main() -> Result<()> {
ConsoleLogger::default_setup(Level::Trace, "rustler")?;
dotenv()?; dotenv()?;
let conn = entities::db::get_connection().await?; let conn = entities::db::get_connection().await?;
info!("Starting gRPC server...");
grpc::server::start(conn.clone()).await?; grpc::server::start(conn.clone()).await?;
info!("Shutting down");
Ok(()) Ok(())
} }

View File

@ -11,6 +11,7 @@ path = "src/lib.rs"
[dependencies] [dependencies]
# common # common
eyre = { workspace = true, default-features = false } eyre = { workspace = true, default-features = false }
lool = { workspace = true }
# external # external
sea-orm = { version = "0.12.15", features = [ sea-orm = { version = "0.12.15", features = [

View File

@ -6,13 +6,33 @@ pub use sea_orm;
pub mod db { pub mod db {
use { use {
eyre::Result, eyre::Result,
sea_orm::{ConnectionTrait, Database, DatabaseConnection, DbBackend, Statement}, lool::{cli::stylize::Stylize, logger::info, s},
sea_orm::{
ConnectOptions, ConnectionTrait, Database, DatabaseConnection, DbBackend, Statement,
},
std::sync::Arc, std::sync::Arc,
}; };
const RUSTLER_DATABASE: &str = "RUSTLER_DATABASE";
fn get_default_conn_str() -> String {
let conn_str = s!("sqlite://rustler.db?mode=rwc");
info!(
"No `{}` env var found, using default: {}",
RUSTLER_DATABASE.italic(),
conn_str.green()
);
conn_str
}
pub async fn get_connection() -> Result<Arc<DatabaseConnection>> { pub async fn get_connection() -> Result<Arc<DatabaseConnection>> {
let db_conn_str = std::env::var("DATABASE_URL")?; let db_conn_str =
let conn = Arc::new(Database::connect(&db_conn_str).await?); std::env::var(RUSTLER_DATABASE).unwrap_or_else(|_| get_default_conn_str());
let mut conn_opts = ConnectOptions::new(db_conn_str.to_owned());
conn_opts.sqlx_logging(false);
let conn = Arc::new(Database::connect(conn_opts).await?);
conn.query_one(Statement::from_string( conn.query_one(Statement::from_string(
DbBackend::Sqlite, DbBackend::Sqlite,
@ -23,6 +43,7 @@ pub mod db {
)) ))
.await?; .await?;
info!("Database to {} connection established", db_conn_str.green());
Ok(conn) Ok(conn)
} }
} }

View File

@ -10,7 +10,7 @@ path = "src/lib.rs"
[dependencies] [dependencies]
# common # common
log = { workspace = true } lool = { workspace = true, features = ["logger"]}
eyre = { workspace = true, default-features = false } eyre = { workspace = true, default-features = false }
# internal # internal

View File

@ -1,7 +1,13 @@
use { use {
self::market_mod::Empty,
entities::{market, sea_orm::DatabaseConnection}, entities::{market, sea_orm::DatabaseConnection},
eyre::Result, eyre::Result,
std::{sync::Arc, time::Instant}, lool::{cli::stylize::Stylize, logger::info},
market_mod::{
market_api_server::{MarketApi, MarketApiServer},
Market, Markets,
},
std::{net::SocketAddr, sync::Arc, time::Instant},
tonic::{transport::Server, Request, Response, Status}, tonic::{transport::Server, Request, Response, Status},
}; };
@ -9,12 +15,7 @@ pub mod market_mod {
tonic::include_proto!("market"); tonic::include_proto!("market");
} }
use market_mod::{ const RUSTLER_GRPC_API_ADDR: &str = "RUSTLER_GRPC_API_ADDR";
market_api_server::{MarketApi, MarketApiServer},
Market, Markets,
};
use self::market_mod::Empty;
impl Market { impl Market {
fn into_model(self) -> market::Model { fn into_model(self) -> market::Model {
@ -56,37 +57,57 @@ pub struct GrpcServer {
impl MarketApi for GrpcServer { impl MarketApi for GrpcServer {
async fn get_all(&self, _: Request<Empty>) -> Result<Response<Markets>, Status> { async fn get_all(&self, _: Request<Empty>) -> Result<Response<Markets>, Status> {
let start = Instant::now(); let start = Instant::now();
if let Ok(mkts) = self.svc.get_all().await { let response = if let Ok(mkts) = self.svc.get_all().await {
println!("get_all took {:?}", start.elapsed());
Ok(Response::new(Markets { Ok(Response::new(Markets {
markets: mkts.into_iter().map(Market::from_model).collect(), markets: mkts.into_iter().map(Market::from_model).collect(),
})) }))
} else { } else {
println!("get_all took {:?}", start.elapsed());
Err(Status::internal("Failed to get markets")) Err(Status::internal("Failed to get markets"))
} };
info!("`MarketApi.get_all` took {:?}", start.elapsed());
response
} }
async fn create(&self, market: Request<Market>) -> Result<Response<Market>, Status> { async fn create(&self, market: Request<Market>) -> Result<Response<Market>, Status> {
let start = Instant::now(); let start = Instant::now();
let mkt = market.into_inner().into_model(); let mkt = market.into_inner().into_model();
if let Ok(m) = self.svc.create(mkt).await { let response = if let Ok(m) = self.svc.create(mkt).await {
println!("create took {:?}", start.elapsed());
Ok(Response::new(Market::from_model(m))) Ok(Response::new(Market::from_model(m)))
} else { } else {
println!("create took {:?} on err", start.elapsed());
Err(Status::internal("Failed to create market")) Err(Status::internal("Failed to create market"))
} };
info!("`MarketApi.create` took {:?}", start.elapsed());
response
} }
} }
/// Starts the gRPC server /// Starts the gRPC server
pub async fn start(conn: Arc<DatabaseConnection>) -> Result<()> { pub async fn start(conn: Arc<DatabaseConnection>) -> Result<()> {
let addr = "0.0.0.0:50051".parse()?; fn get_default_addr() -> String {
let svc = market::Service::new(conn).await; let addr = "0.0.0.0:50051";
info!(
"`{}` not set, using default {}",
RUSTLER_GRPC_API_ADDR.italic(),
addr.green()
);
addr.to_owned()
}
let addr: SocketAddr =
std::env::var(RUSTLER_GRPC_API_ADDR).unwrap_or_else(|_| get_default_addr()).parse()?;
let svc = market::Service::new(conn).await;
let server = GrpcServer { svc }; let server = GrpcServer { svc };
info!(
"🎉 gRPC server listening on {}",
addr.clone().to_string().green()
);
Server::builder().add_service(MarketApiServer::new(server)).serve(addr).await?; Server::builder().add_service(MarketApiServer::new(server)).serve(addr).await?;
Ok(()) Ok(())