Skip to content

Commit

Permalink
Merge pull request #13 from husni-zuhdi/feat-implement-tracing
Browse files Browse the repository at this point in the history
Feat implement tracing
  • Loading branch information
husni-zuhdi authored Sep 7, 2024
2 parents 4d77ba2 + a850abf commit 8cc977e
Show file tree
Hide file tree
Showing 16 changed files with 197 additions and 146 deletions.
7 changes: 2 additions & 5 deletions internal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,11 @@ build = "build.rs"
[dependencies]
axum = { version = "0.7.5", features = ["macros"] }
tokio = { version = "1.0", features = ["full"] }
# tracing = "0.1" # Might not need this
# tracing-subscriber = { version = "0.3", features = ["env-filter"] } # Might not need this
tracing = { version = "0.1", features = ["attributes"] }
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
tower = { version = "0.4", features = ["util"] }
tower-http = { version = "0.5.0", features = ["fs", "trace"] }
askama = { version = "0.12.1"}
env_logger = "0.10.1"
log = "0.4.20"
serde = { version="1.0.192", features = ["derive"]}
serde_json = "1.0.108"
markdown = "1.0.0-alpha.17"
Expand All @@ -26,7 +24,6 @@ regex = "1.10.6"
sqlx = { version = "=0.8.1", features = ["sqlite", "runtime-tokio"] }
async-trait = "0.1.81"
dyn-clone = "1.0.17"
# rusqlite = "=0.32.1"

[build-dependencies]
anyhow = "1.0.86"
Expand Down
2 changes: 1 addition & 1 deletion internal/src/api/filesystem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ use crate::model::blog::{
use crate::repo::api::ApiRepo;
use crate::utils::capitalize;
use async_trait::async_trait;
use log::{debug, info};
use markdown::{to_html_with_options, CompileOptions, Constructs, Options, ParseOptions};
use std::fs;
use std::path::PathBuf;
use tracing::{debug, info};

#[derive(Clone)]
pub struct FilesystemApiUseCase {
Expand Down
4 changes: 2 additions & 2 deletions internal/src/api/github.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ use crate::repo::api::ApiRepo;
use crate::utils::capitalize;
use async_trait::async_trait;
use http_body_util::BodyExt;
use log::{debug, error, info, warn};
use markdown::{to_html_with_options, Options};
use octocrab;
use octocrab::models::repos::Content;
use regex::Regex;
use serde_json;
use std::num::IntErrorKind;
use tracing::{debug, error, info, warn};

#[derive(Clone)]
pub struct GithubApiUseCase {
Expand Down Expand Up @@ -155,7 +155,7 @@ impl GithubApiUseCase {
}
}
} else {
info!("Tree {} is not a directory. Skipped.", &tree.path);
debug!("Tree {} is not a directory. Skipped.", &tree.path);
None
}
}
Expand Down
91 changes: 7 additions & 84 deletions internal/src/app.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,23 @@
use crate::api::filesystem::FilesystemApiUseCase;
use crate::api::github::GithubApiUseCase;
use crate::database::memory::MemoryBlogRepo;
use crate::database::sqlite::SqliteBlogRepo;
use crate::config::Config;
use crate::handler;
use crate::model::axum::AppState;
use crate::port::blog::command::BlogCommandPort;
use crate::port::blog::query::BlogQueryPort;
use crate::repo::api::ApiRepo;
use crate::{config::Config, usecase::blog::BlogUseCase};
use crate::state::state_factory;
use axum::{
routing::{get, get_service},
Router,
};
use log::info;
use std::sync::Arc;
use tokio::sync::Mutex;
use tower_http::services::{ServeDir, ServeFile};
use tracing::info;

/// Run the axum web application
pub async fn app() -> () {
// Setup Config
let config = Config::from_envar();
let endpoint = format!("{}:{}", &config.svc_endpoint, &config.svc_port);

// Initialize Logger
env_logger::init_from_env(env_logger::Env::new().default_filter_or(config.log_level.clone()));
// Initialize Tracing
tracing_subscriber::fmt()
.with_max_level(config.log_level)
.init();

// Init app state
let app_state = state_factory(config).await;
Expand All @@ -49,73 +42,3 @@ pub async fn app() -> () {
let listener = tokio::net::TcpListener::bind(endpoint).await.unwrap();
axum::serve(listener, app).await.unwrap();
}

/// Build App State for Axum Application
async fn state_factory(config: Config) -> AppState {
// Setup blog use case
let data_source_is_configured_sqlite =
config.data_source == "sqlite" && config.database_url != "";
let github_api_is_enabled =
!config.gh_owner.is_empty() && !config.gh_repo.is_empty() && !config.gh_branch.is_empty();

let mut blog_uc = if data_source_is_configured_sqlite {
// Use SqliteBlogRepo
let repo = SqliteBlogRepo::new(config.database_url.clone()).await;
BlogUseCase::new(Box::new(repo))
} else {
// // Use MemoryBlogRepo
let repo = MemoryBlogRepo::default();
BlogUseCase::new(Box::new(repo))
// }
};

let fs_usecase = FilesystemApiUseCase::new("./statics/blogs/".to_string()).await;
let blogs_metadata = fs_usecase.list_metadata().await;
for metadata in blogs_metadata {
// Check if blog id is in the database
let blog_is_not_stored = !blog_uc.check_id(metadata.id.clone()).await.0;
if blog_is_not_stored {
info!("Start to fetch Blog {}.", &metadata.id);
let blog = fs_usecase.fetch(metadata.clone()).await;
info!("Finished to fetch Blog {}.", &metadata.id);

info!("Start to store Blog {}.", &metadata.id);
let _ = blog_uc
.add(blog.id, blog.name, blog.filename, blog.source, blog.body)
.await;
info!("Finished to store Blog {}.", &metadata.id);
}
}

if github_api_is_enabled {
let github_usecase = GithubApiUseCase::new(
config.gh_owner.clone(),
config.gh_repo.clone(),
config.gh_branch.clone(),
)
.await;
let blogs_metadata = github_usecase.list_metadata().await;
for metadata in blogs_metadata {
// Check if blog id is in the database
let blog_is_not_stored = !blog_uc.check_id(metadata.id.clone()).await.0;
if blog_is_not_stored {
info!("Start to fetch Blog {}.", &metadata.id);
let blog = github_usecase.fetch(metadata.clone()).await;
info!("Finished to fetch Blog {}.", &metadata.id);

info!("Start to store Blog {}.", &metadata.id);
let _ = blog_uc
.add(blog.id, blog.name, blog.filename, blog.source, blog.body)
.await;
info!("Finished to store Blog {}.", &metadata.id);
}
}
}

let blog_usecase = Arc::new(Mutex::new(blog_uc));

AppState {
config,
blog_usecase,
}
}
106 changes: 72 additions & 34 deletions internal/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use log::warn;
use std::env;
use tracing::warn;

/// Struct Config for setup environment variables
#[derive(PartialEq, Debug, Clone)]
pub struct Config {
pub svc_endpoint: String,
pub svc_port: String,
pub log_level: String,
pub log_level: tracing::Level,
pub environment: String,
pub data_source: String,
pub database_url: String,
Expand All @@ -21,7 +21,7 @@ impl Default for Config {
fn default() -> Self {
let svc_endpoint: String = "localhost".to_string();
let svc_port: String = "8080".to_string();
let log_level: String = "info".to_string();
let log_level = tracing::Level::INFO;
let environment: String = "release".to_string();
let data_source: String = "memory".to_string();
let database_url: String = "".to_owned();
Expand Down Expand Up @@ -70,7 +70,22 @@ impl Config {
.expect("failed to load SVC_PORT environment variable. Double check your config");

// Optional
let log_level: String = Self::parse_optional_envar("LOG_LEVEL", "info");
let log_level: tracing::Level = match env::var("LOG_LEVEL") {
Err(e) => {
warn!(
"Failed to load LOG_LEVEL environment variable. Set default to 'info'. Error {}", e
);
tracing::Level::INFO
}
Ok(val) => match val.as_str() {
"error" => tracing::Level::ERROR,
"warn" => tracing::Level::WARN,
"info" => tracing::Level::INFO,
"debug" => tracing::Level::DEBUG,
"trace" => tracing::Level::TRACE,
_ => tracing::Level::INFO,
},
};
let environment: String = Self::parse_optional_envar("ENVIRONMENT", "release");
let data_source: String = Self::parse_optional_envar("DATA_SOURCE", "memory");
let database_url: String = Self::parse_optional_envar("DATABASE_URL", "");
Expand Down Expand Up @@ -100,7 +115,7 @@ mod test {
fn test_default() {
let svc_endpoint: String = "localhost".to_string();
let svc_port: String = "8080".to_string();
let log_level: String = "info".to_string();
let log_level = tracing::Level::INFO;
let environment: String = "release".to_string();
let data_source: String = "memory".to_string();
let database_url: String = "".to_string();
Expand All @@ -126,7 +141,7 @@ mod test {
let svc_endpoint = "localhost";
let svc_port = "8080";
let log_level = "";
let expected_log_level = "info";
let expected_log_level = tracing::Level::INFO;
let environment = "";
let expected_environment = "release";
let data_source = "";
Expand All @@ -136,15 +151,17 @@ mod test {
let gh_repo = "";
let gh_branch = "";

env::set_var("SVC_ENDPOINT", svc_endpoint);
env::set_var("SVC_PORT", svc_port);
env::set_var("LOG_LEVEL", log_level);
env::set_var("ENVIRONMENT", environment);
env::set_var("DATA_SOURCE", data_source);
env::set_var("DATABASE_URL", database_url);
env::set_var("GITHUB_OWNER", gh_owner);
env::set_var("GITHUB_REPO", gh_repo);
env::set_var("GITHUB_BRANCH", gh_branch);
set_envars(
svc_endpoint,
svc_port,
log_level,
environment,
data_source,
database_url,
gh_owner,
gh_repo,
gh_branch,
);

let result = Config::from_envar();

Expand All @@ -158,51 +175,72 @@ mod test {
assert_eq!(result.gh_repo, gh_repo);
assert_eq!(result.gh_branch, gh_branch);

env::remove_var("SVC_ENDPOINT");
env::remove_var("SVC_PORT");
env::remove_var("LOG_LEVEL");
env::remove_var("ENVIRONMENT");
env::remove_var("DATA_SOURCE");
env::remove_var("DATABASE_URL");
env::remove_var("GITHUB_OWNER");
env::remove_var("GITHUB_REPO");
env::remove_var("GITHUB_BRANCH");
remove_envars()
}

#[test]
fn test_from_envar_with_optionals() {
let svc_endpoint = "localhost";
let svc_port = "8080";
let log_level = "info";
let expected_log_level = tracing::Level::INFO;
let environment = "dev";
let data_source = "sqlite";
let database_url = "sqlite:husni-portfolio.db";
let gh_owner = "husni-zuhdi";
let gh_repo = "husni-blog-resources";
let gh_branch = "main";

env::set_var("SVC_ENDPOINT", svc_endpoint);
env::set_var("SVC_PORT", svc_port);
env::set_var("LOG_LEVEL", log_level);
env::set_var("ENVIRONMENT", environment);
env::set_var("DATA_SOURCE", data_source);
env::set_var("DATABASE_URL", database_url);
env::set_var("GITHUB_OWNER", gh_owner);
env::set_var("GITHUB_REPO", gh_repo);
env::set_var("GITHUB_BRANCH", gh_branch);
set_envars(
svc_endpoint,
svc_port,
log_level,
environment,
data_source,
database_url,
gh_owner,
gh_repo,
gh_branch,
);

let result = Config::from_envar();

assert_eq!(result.svc_endpoint, svc_endpoint);
assert_eq!(result.svc_port, svc_port);
assert_eq!(result.log_level, log_level);
assert_eq!(result.log_level, expected_log_level);
assert_eq!(result.environment, environment);
assert_eq!(result.data_source, data_source);
assert_eq!(result.database_url, database_url);
assert_eq!(result.gh_owner, gh_owner);
assert_eq!(result.gh_repo, gh_repo);
assert_eq!(result.gh_branch, gh_branch);

remove_envars()
}

fn set_envars(
svc_endpoint: &str,
svc_port: &str,
log_level: &str,
environment: &str,
data_source: &str,
database_url: &str,
gh_owner: &str,
gh_repo: &str,
gh_branch: &str,
) {
env::set_var("SVC_ENDPOINT", svc_endpoint);
env::set_var("SVC_PORT", svc_port);
env::set_var("LOG_LEVEL", log_level);
env::set_var("ENVIRONMENT", environment);
env::set_var("DATA_SOURCE", data_source);
env::set_var("DATABASE_URL", database_url);
env::set_var("GITHUB_OWNER", gh_owner);
env::set_var("GITHUB_REPO", gh_repo);
env::set_var("GITHUB_BRANCH", gh_branch);
}

fn remove_envars() {
env::remove_var("SVC_ENDPOINT");
env::remove_var("SVC_PORT");
env::remove_var("LOG_LEVEL");
Expand Down
7 changes: 2 additions & 5 deletions internal/src/database/memory.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
use crate::model::blog::{
Blog, BlogBody, BlogDeleted, BlogEndPage, BlogFilename, BlogId, BlogName, BlogSource,
BlogStartPage, BlogStored,
};
use crate::model::blog::*;
use crate::repo::blog::BlogRepo;
use async_trait::async_trait;
use log::{debug, info, warn};
use tracing::{debug, info, warn};

#[derive(Clone)]
pub struct MemoryBlogRepo {
Expand Down
7 changes: 2 additions & 5 deletions internal/src/database/sqlite.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
use crate::model::blog::{
Blog, BlogBody, BlogDeleted, BlogEndPage, BlogFilename, BlogId, BlogName, BlogSource,
BlogStartPage, BlogStored,
};
use crate::model::blog::*;
use crate::repo::blog::BlogRepo;
use async_trait::async_trait;
use log::{debug, info};
use sqlx::sqlite::SqlitePool;
use sqlx::{query, query_as, Sqlite};
use tracing::{debug, info};

#[derive(Clone)]
pub struct SqliteBlogRepo {
Expand Down
Loading

0 comments on commit 8cc977e

Please sign in to comment.