wip: add logging capabilities
This commit is contained in:
parent
d84c58fd1c
commit
3d12877e27
5 changed files with 384 additions and 17 deletions
115
src/config.rs
115
src/config.rs
|
|
@ -1,13 +1,116 @@
|
|||
use std::path::PathBuf;
|
||||
use clap::Parser;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::path::PathBuf;
|
||||
use tracing_core::{Level, LevelFilter};
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct Args {
|
||||
path: PathBuf,
|
||||
pub enum VerbosityFilter {
|
||||
Off,
|
||||
Error,
|
||||
Warn,
|
||||
Info,
|
||||
Debug,
|
||||
Trace,
|
||||
}
|
||||
|
||||
impl Args {
|
||||
impl VerbosityFilter {
|
||||
fn with_offset(&self, offset: i16) -> VerbosityFilter {
|
||||
let value = match self {
|
||||
Self::Off => 0_i16,
|
||||
Self::Error => 1,
|
||||
Self::Warn => 2,
|
||||
Self::Info => 3,
|
||||
Self::Debug => 4,
|
||||
Self::Trace => 5,
|
||||
};
|
||||
match value.saturating_add(offset) {
|
||||
i16::MIN..=0 => Self::Off,
|
||||
1 => Self::Error,
|
||||
2 => Self::Warn,
|
||||
3 => Self::Info,
|
||||
4 => Self::Debug,
|
||||
5..=i16::MAX => Self::Trace,
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
impl From<LevelFilter> for VerbosityFilter {
|
||||
fn from(level: LevelFilter) -> Self {
|
||||
match level {
|
||||
LevelFilter::OFF => Self::Off,
|
||||
LevelFilter::ERROR => Self::Error,
|
||||
LevelFilter::WARN => Self::Warn,
|
||||
LevelFilter::INFO => Self::Info,
|
||||
LevelFilter::DEBUG => Self::Debug,
|
||||
LevelFilter::TRACE => Self::Trace,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<VerbosityFilter> for Option<Level> {
|
||||
fn from(filter: VerbosityFilter) -> Self {
|
||||
match filter {
|
||||
VerbosityFilter::Off => None,
|
||||
VerbosityFilter::Error => Some(Level::ERROR),
|
||||
VerbosityFilter::Warn => Some(Level::WARN),
|
||||
VerbosityFilter::Info => Some(Level::INFO),
|
||||
VerbosityFilter::Debug => Some(Level::DEBUG),
|
||||
VerbosityFilter::Trace => Some(Level::TRACE),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl From<Option<Level>> for VerbosityFilter {
|
||||
fn from(level: Option<Level>) -> Self {
|
||||
match level {
|
||||
None => Self::Off,
|
||||
Some(Level::ERROR) => Self::Error,
|
||||
Some(Level::WARN) => Self::Warn,
|
||||
Some(Level::INFO) => Self::Info,
|
||||
Some(Level::DEBUG) => Self::Debug,
|
||||
Some(Level::TRACE) => Self::Trace,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Parser, Serialize, Deserialize)]
|
||||
pub struct Config {
|
||||
path: PathBuf,
|
||||
#[arg(
|
||||
long,
|
||||
short = 'v',
|
||||
action = clap::ArgAction::Count,
|
||||
global = true,
|
||||
help = "Increase logging verbosity",
|
||||
)]
|
||||
verbose: u8,
|
||||
|
||||
#[arg(
|
||||
long,
|
||||
short = 'q',
|
||||
action = clap::ArgAction::Count,
|
||||
global = true,
|
||||
help = "Decrease logging verbosity",
|
||||
conflicts_with = "verbose",
|
||||
)]
|
||||
quiet: u8,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn path(&self) -> &PathBuf {
|
||||
&self.path
|
||||
}
|
||||
}
|
||||
/// Gets the filter that should be applied to the logger.
|
||||
///
|
||||
pub fn filter(&self) -> VerbosityFilter {
|
||||
let offset = self.verbose as i16 - self.quiet as i16;
|
||||
VerbosityFilter::Error.with_offset(offset)
|
||||
}
|
||||
|
||||
pub fn tracing_level(&self) -> Option<tracing_core::Level> {
|
||||
self.filter().into()
|
||||
}
|
||||
|
||||
/// Get the tracing level filter.
|
||||
pub fn tracing_level_filter(&self) -> tracing_core::LevelFilter {
|
||||
self.filter().into()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
26
src/main.rs
26
src/main.rs
|
|
@ -1,24 +1,34 @@
|
|||
use std::fs::File;
|
||||
use clap::Parser;
|
||||
use readwise_bulk_upload::config::Args;
|
||||
use readwise_bulk_upload::config::Config;
|
||||
use readwise_bulk_upload::readwise::DocumentPayload;
|
||||
use readwise_bulk_upload::sql::{TaskManager};
|
||||
use readwise_bulk_upload::sql::TaskManager;
|
||||
use readwise_bulk_upload::{Error, Result};
|
||||
use std::fs::File;
|
||||
use tracing_subscriber;
|
||||
use figment::{Figment, providers::{Serialized, Env, Format}};
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
let args = Args::parse();
|
||||
let args: Config = Figment::new()
|
||||
.merge(Serialized::defaults(Config::parse()))
|
||||
.merge(Env::prefixed("APP_"))
|
||||
.extract()?;
|
||||
|
||||
let file = File::open(args.path())
|
||||
.map_err(|_| Error::Runtime(format!(
|
||||
tracing_subscriber::fmt()
|
||||
.with_max_level(args.verbose)
|
||||
.init();
|
||||
|
||||
let file = File::open(args.path()).map_err(|_| {
|
||||
Error::Runtime(format!(
|
||||
r#"The file "{}" could not be open"#,
|
||||
args.path().display()
|
||||
)))?;
|
||||
))
|
||||
})?;
|
||||
|
||||
let documents: Vec<DocumentPayload> = serde_json::from_reader(file)?;
|
||||
|
||||
let task_manager = TaskManager::new().await?;
|
||||
|
||||
|
||||
task_manager.load_tasks(documents).await?;
|
||||
|
||||
Ok(())
|
||||
|
|
|
|||
12
src/sql.rs
12
src/sql.rs
|
|
@ -4,6 +4,7 @@ use serde::Serialize;
|
|||
use sqlx::sqlite::{SqliteConnectOptions, SqliteJournalMode};
|
||||
use sqlx::{QueryBuilder, Sqlite, SqlitePool};
|
||||
use tokio::fs;
|
||||
use tracing::{info, instrument};
|
||||
|
||||
static SQLITE_BIND_LIMIT: usize = 32766;
|
||||
|
||||
|
|
@ -20,6 +21,7 @@ pub trait TaskPayload {
|
|||
fn get_key(&self) -> String;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TaskManager {
|
||||
pool: SqlitePool,
|
||||
}
|
||||
|
|
@ -51,9 +53,10 @@ impl TaskManager {
|
|||
Ok(pool)
|
||||
}
|
||||
|
||||
#[instrument(skip(self, values))]
|
||||
pub async fn load_tasks<T>(&self, values: Vec<T>) -> crate::Result<()>
|
||||
where
|
||||
T: TaskPayload + Serialize,
|
||||
T: TaskPayload + Serialize + std::fmt::Debug,
|
||||
{
|
||||
let mut tx = self.pool.begin().await?;
|
||||
let mut builder: QueryBuilder<'_, Sqlite> =
|
||||
|
|
@ -65,6 +68,7 @@ impl TaskManager {
|
|||
.collect();
|
||||
|
||||
|
||||
let mut affected_rows = 0;
|
||||
// Chunk the query by the size limit of bind params
|
||||
for chunk in args?.chunks(SQLITE_BIND_LIMIT / 3) {
|
||||
builder.push_values(chunk, |mut builder, item| {
|
||||
|
|
@ -77,12 +81,14 @@ impl TaskManager {
|
|||
|
||||
let query = builder.build();
|
||||
|
||||
query.execute(&mut *tx).await?;
|
||||
affected_rows += query.execute(&mut *tx).await?.rows_affected();
|
||||
builder.reset();
|
||||
}
|
||||
|
||||
|
||||
tx.commit().await?;
|
||||
|
||||
info!("{} rows inserted.", affected_rows);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue