Use tracing library
This commit is contained in:
parent
69aa7393fe
commit
ab5e187212
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -2677,6 +2677,8 @@ dependencies = [
|
|||||||
"sqlx",
|
"sqlx",
|
||||||
"time",
|
"time",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tracing",
|
||||||
|
"tracing-subscriber",
|
||||||
"url",
|
"url",
|
||||||
"uuid",
|
"uuid",
|
||||||
]
|
]
|
||||||
|
@ -22,3 +22,5 @@ tokio = "1.43.0"
|
|||||||
time = "0.3.37"
|
time = "0.3.37"
|
||||||
base64 = "0.21"
|
base64 = "0.21"
|
||||||
getrandom = "0.2"
|
getrandom = "0.2"
|
||||||
|
tracing = "0.1"
|
||||||
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use crate::feeds::Feed;
|
use crate::feeds::Feed;
|
||||||
use crate::user::User;
|
use crate::user::User;
|
||||||
|
use tracing::info;
|
||||||
|
|
||||||
struct DemoFeed {
|
struct DemoFeed {
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
@ -75,5 +76,5 @@ pub async fn setup_demo_data(pool: &sqlx::SqlitePool) {
|
|||||||
.expect("Failed to create demo feed");
|
.expect("Failed to create demo feed");
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Successfully set up demo data");
|
info!("Successfully set up demo data");
|
||||||
}
|
}
|
||||||
|
@ -1,29 +1,31 @@
|
|||||||
|
use feed_rs;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
use tracing::{error, info};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FeedError;
|
pub struct FeedError;
|
||||||
|
|
||||||
pub async fn fetch_feed(url: &Url) -> Result<feed_rs::model::Feed, FeedError> {
|
pub async fn fetch_feed(url: &Url) -> Result<feed_rs::model::Feed, FeedError> {
|
||||||
println!("Making a request to fetch feed `{url}`");
|
info!("Making a request to fetch feed `{url}`");
|
||||||
|
|
||||||
// Fetch the feed content
|
// Fetch the feed content
|
||||||
let response = reqwest::get(url.as_ref()).await.map_err(|e| {
|
let response = reqwest::get(url.as_ref()).await.map_err(|e| {
|
||||||
eprintln!("Failed to fetch feed: {}", e);
|
error!("Failed to fetch feed: {}", e);
|
||||||
FeedError
|
FeedError
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let content = response.text().await.map_err(|e| {
|
let content = response.text().await.map_err(|e| {
|
||||||
eprintln!("Failed to read response body: {}", e);
|
error!("Failed to read response body: {}", e);
|
||||||
FeedError
|
FeedError
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Parse the feed
|
// Parse the feed
|
||||||
let feed_data = feed_rs::parser::parse(content.as_bytes()).map_err(|e| {
|
let feed_data = feed_rs::parser::parse(content.as_bytes()).map_err(|e| {
|
||||||
eprintln!("Failed to parse feed content: {}", e);
|
error!("Failed to parse feed content: {}", e);
|
||||||
FeedError
|
FeedError
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
println!("Fetched feed: {}", url.as_ref());
|
info!("Fetched feed: {}", url.as_ref());
|
||||||
|
|
||||||
Ok(feed_data)
|
Ok(feed_data)
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ use rocket::serde::{self, json::Json, Deserialize, Serialize};
|
|||||||
use rocket_db_pools::Connection;
|
use rocket_db_pools::Connection;
|
||||||
use sqlx::types::JsonValue;
|
use sqlx::types::JsonValue;
|
||||||
use sqlx::Executor;
|
use sqlx::Executor;
|
||||||
|
use tracing::error;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
@ -42,7 +43,7 @@ impl Feed {
|
|||||||
{
|
{
|
||||||
// Convert categorization to JSON value
|
// Convert categorization to JSON value
|
||||||
let categorization_json = serde::json::to_value(&self.categorization).map_err(|e| {
|
let categorization_json = serde::json::to_value(&self.categorization).map_err(|e| {
|
||||||
eprintln!("Failed to serialize categorization: {}", e);
|
error!("Failed to serialize categorization: {}", e);
|
||||||
sqlx::Error::Decode(Box::new(e))
|
sqlx::Error::Decode(Box::new(e))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
20
src/main.rs
20
src/main.rs
@ -2,6 +2,8 @@
|
|||||||
extern crate rocket;
|
extern crate rocket;
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
use tracing::{info, Level};
|
||||||
|
use tracing_subscriber::FmtSubscriber;
|
||||||
|
|
||||||
mod demo;
|
mod demo;
|
||||||
mod feed_utils;
|
mod feed_utils;
|
||||||
@ -89,8 +91,24 @@ async fn setup_database(demo: bool, rocket: Rocket<Build>) -> fairing::Result {
|
|||||||
|
|
||||||
#[launch]
|
#[launch]
|
||||||
fn rocket() -> _ {
|
fn rocket() -> _ {
|
||||||
|
// Initialize the tracing subscriber
|
||||||
|
FmtSubscriber::builder()
|
||||||
|
.with_max_level(Level::INFO)
|
||||||
|
.with_target(false)
|
||||||
|
.with_thread_ids(true)
|
||||||
|
.with_file(true)
|
||||||
|
.with_line_number(true)
|
||||||
|
.with_thread_names(true)
|
||||||
|
.pretty()
|
||||||
|
.init();
|
||||||
|
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
|
|
||||||
|
info!("Starting RSS Reader");
|
||||||
|
if args.demo {
|
||||||
|
info!("Running in demo mode");
|
||||||
|
}
|
||||||
|
|
||||||
let db_url = if args.demo {
|
let db_url = if args.demo {
|
||||||
// Use a temporary file for demo mode instead of in-memory database
|
// Use a temporary file for demo mode instead of in-memory database
|
||||||
let temp_db = "/tmp/rss-reader-temp-db.sqlite";
|
let temp_db = "/tmp/rss-reader-temp-db.sqlite";
|
||||||
@ -100,6 +118,7 @@ fn rocket() -> _ {
|
|||||||
}
|
}
|
||||||
// Create the new database file
|
// Create the new database file
|
||||||
std::fs::File::create(temp_db).expect("Failed to create temporary database file");
|
std::fs::File::create(temp_db).expect("Failed to create temporary database file");
|
||||||
|
info!("Created temporary database at {}", temp_db);
|
||||||
format!("sqlite:{}", temp_db)
|
format!("sqlite:{}", temp_db)
|
||||||
} else {
|
} else {
|
||||||
let database = args
|
let database = args
|
||||||
@ -109,6 +128,7 @@ fn rocket() -> _ {
|
|||||||
if !std::path::Path::new(&database).exists() {
|
if !std::path::Path::new(&database).exists() {
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
File::create(&database).expect("Failed to create database file");
|
File::create(&database).expect("Failed to create database file");
|
||||||
|
info!("Created new database at {}", database);
|
||||||
}
|
}
|
||||||
format!("sqlite:{}", database)
|
format!("sqlite:{}", database)
|
||||||
};
|
};
|
||||||
|
19
src/poll.rs
19
src/poll.rs
@ -7,6 +7,7 @@ use rocket::serde::uuid::Uuid;
|
|||||||
use rocket::serde::{self, json::Json, Serialize};
|
use rocket::serde::{self, json::Json, Serialize};
|
||||||
use rocket_db_pools::Connection;
|
use rocket_db_pools::Connection;
|
||||||
use sqlx::{Acquire, SqliteConnection};
|
use sqlx::{Acquire, SqliteConnection};
|
||||||
|
use tracing::{error, info};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
const POLLING_INTERVAL: Duration = Duration::minutes(20);
|
const POLLING_INTERVAL: Duration = Duration::minutes(20);
|
||||||
@ -39,7 +40,7 @@ async fn update_entry_db(
|
|||||||
) -> Result<(), Status> {
|
) -> Result<(), Status> {
|
||||||
// Start a transaction for batch update
|
// Start a transaction for batch update
|
||||||
let mut tx = db.begin().await.map_err(|e| {
|
let mut tx = db.begin().await.map_err(|e| {
|
||||||
eprintln!("Failed to start transaction: {}", e);
|
error!("Failed to start transaction: {}", e);
|
||||||
Status::InternalServerError
|
Status::InternalServerError
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@ -52,7 +53,7 @@ async fn update_entry_db(
|
|||||||
.execute(&mut *tx)
|
.execute(&mut *tx)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
eprintln!("Failed to update feed last_checked_time: {}", e);
|
error!("Failed to update feed last_checked_time: {}", e);
|
||||||
Status::InternalServerError
|
Status::InternalServerError
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@ -95,9 +96,9 @@ async fn update_entry_db(
|
|||||||
.await;
|
.await;
|
||||||
|
|
||||||
if let Err(e) = result {
|
if let Err(e) = result {
|
||||||
eprintln!("Failed to save feed entry: {}", e);
|
error!("Failed to save feed entry: {}", e);
|
||||||
tx.rollback().await.map_err(|e| {
|
tx.rollback().await.map_err(|e| {
|
||||||
eprintln!("Failed to rollback transaction: {}", e);
|
error!("Failed to rollback transaction: {}", e);
|
||||||
Status::InternalServerError
|
Status::InternalServerError
|
||||||
})?;
|
})?;
|
||||||
return Err(Status::InternalServerError);
|
return Err(Status::InternalServerError);
|
||||||
@ -106,7 +107,7 @@ async fn update_entry_db(
|
|||||||
|
|
||||||
// Commit the transaction
|
// Commit the transaction
|
||||||
tx.commit().await.map_err(|e| {
|
tx.commit().await.map_err(|e| {
|
||||||
eprintln!("Failed to commit transaction: {}", e);
|
error!("Failed to commit transaction: {}", e);
|
||||||
Status::InternalServerError
|
Status::InternalServerError
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@ -136,7 +137,7 @@ async fn read_entries(feed_id: &str, db: &mut SqliteConnection) -> Result<Vec<En
|
|||||||
.fetch_all(db)
|
.fetch_all(db)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
eprintln!("Failed to read feed entries: {}", e);
|
error!("Failed to read feed entries: {}", e);
|
||||||
Status::InternalServerError
|
Status::InternalServerError
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@ -214,17 +215,19 @@ pub async fn poll_feed(
|
|||||||
|
|
||||||
let now = Utc::now();
|
let now = Utc::now();
|
||||||
let last_checked = now - feed.last_checked_time;
|
let last_checked = now - feed.last_checked_time;
|
||||||
println!("Feed last checked: {}", last_checked);
|
info!("Feed {} last checked: {}", feed_id, last_checked);
|
||||||
let entries = if last_checked < POLLING_INTERVAL {
|
let entries = if last_checked < POLLING_INTERVAL {
|
||||||
println!("reading entries out of db");
|
info!("Reading entries from database for feed {}", feed_id);
|
||||||
read_entries(&feed_id, &mut db).await?
|
read_entries(&feed_id, &mut db).await?
|
||||||
} else {
|
} else {
|
||||||
|
info!("Fetching new entries for feed {}", feed_id);
|
||||||
let entries = fetch_new_entries(&url).await?;
|
let entries = fetch_new_entries(&url).await?;
|
||||||
update_entry_db(&entries, &feed_id, &mut db).await?;
|
update_entry_db(&entries, &feed_id, &mut db).await?;
|
||||||
entries
|
entries
|
||||||
};
|
};
|
||||||
|
|
||||||
let count = entries.len();
|
let count = entries.len();
|
||||||
|
info!("Returning {} entries for feed {}", count, feed_id);
|
||||||
|
|
||||||
Ok(Json(FeedPollResponse { count, entries }))
|
Ok(Json(FeedPollResponse { count, entries }))
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ use rocket::serde::{json::Json, Deserialize, Serialize};
|
|||||||
use rocket::State;
|
use rocket::State;
|
||||||
use rocket_db_pools::Connection;
|
use rocket_db_pools::Connection;
|
||||||
use rocket_dyn_templates::{context, Template};
|
use rocket_dyn_templates::{context, Template};
|
||||||
|
use tracing::error;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::session_store::SessionStore;
|
use crate::session_store::SessionStore;
|
||||||
@ -114,7 +115,7 @@ pub async fn create_user(
|
|||||||
match user.write_to_database(&mut **db).await {
|
match user.write_to_database(&mut **db).await {
|
||||||
Ok(_) => Ok(Json(user)),
|
Ok(_) => Ok(Json(user)),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("Database error: {}", e);
|
error!("Database error: {}", e);
|
||||||
match e {
|
match e {
|
||||||
sqlx::Error::Database(db_err) if db_err.is_unique_violation() => {
|
sqlx::Error::Database(db_err) if db_err.is_unique_violation() => {
|
||||||
Err(Status::Conflict)
|
Err(Status::Conflict)
|
||||||
@ -360,7 +361,7 @@ pub async fn setup(
|
|||||||
match user.write_to_database(&mut **db).await {
|
match user.write_to_database(&mut **db).await {
|
||||||
Ok(_) => Ok(Status::Created),
|
Ok(_) => Ok(Status::Created),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("Database error: {}", e);
|
error!("Database error: {}", e);
|
||||||
match e {
|
match e {
|
||||||
sqlx::Error::Database(db_err) if db_err.is_unique_violation() => {
|
sqlx::Error::Database(db_err) if db_err.is_unique_violation() => {
|
||||||
Err(Json(SetupError {
|
Err(Json(SetupError {
|
||||||
|
Loading…
Reference in New Issue
Block a user