refactor: config log
This commit is contained in:
parent
7b706b54ce
commit
690ea42d85
|
|
@ -68,11 +68,11 @@ jobs:
|
|||
- name: Migrate database
|
||||
run: |
|
||||
sudo apt-get install libpq-dev -y
|
||||
SKIP_DOCKER=true POSTGRES_PORT=5433 ./scripts/init_database.sh
|
||||
SKIP_DOCKER=true POSTGRES_PORT=5433 ./build/init_database.sh
|
||||
|
||||
- name: Check sqlx-data.json is up-to-date
|
||||
run: |
|
||||
cargo sqlx prepare --check -- --bin http_server
|
||||
cargo sqlx prepare --check -- --bin appflowy_server
|
||||
|
||||
- name: Run cargo test
|
||||
run: cargo test
|
||||
|
|
@ -140,7 +140,7 @@ jobs:
|
|||
- name: Migrate database
|
||||
run: |
|
||||
sudo apt-get install libpq-dev -y
|
||||
SKIP_DOCKER=true POSTGRES_PORT=5433 ./scripts/init_database.sh
|
||||
SKIP_DOCKER=true POSTGRES_PORT=5433 ./build/init_database.sh
|
||||
|
||||
- run: rustup component add clippy
|
||||
- run: cargo clippy -- -D warnings
|
||||
|
|
|
|||
|
|
@ -401,9 +401,9 @@ dependencies = [
|
|||
"sqlx",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-appender",
|
||||
"tracing-actix-web",
|
||||
"tracing-bunyan-formatter",
|
||||
"tracing-futures",
|
||||
"tracing-log",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
|
|
@ -2137,7 +2137,7 @@ dependencies = [
|
|||
"thiserror",
|
||||
"tokio-stream",
|
||||
"url",
|
||||
"uuid",
|
||||
"uuid 0.8.2",
|
||||
"whoami",
|
||||
]
|
||||
|
||||
|
|
@ -2388,14 +2388,15 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-appender"
|
||||
version = "0.2.2"
|
||||
name = "tracing-actix-web"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09d48f71a791638519505cefafe162606f706c25592e4bde4d97600c0195312e"
|
||||
checksum = "4082e4d81173e0b7ad3cfb71e9eaef0dd0cbb7b139fdb56394f488a3b0760b23"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"time 0.3.20",
|
||||
"tracing-subscriber",
|
||||
"actix-web",
|
||||
"pin-project",
|
||||
"tracing",
|
||||
"uuid 1.3.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2437,16 +2438,6 @@ dependencies = [
|
|||
"valuable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-futures"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2"
|
||||
dependencies = [
|
||||
"pin-project",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-log"
|
||||
version = "0.1.3"
|
||||
|
|
@ -2567,6 +2558,15 @@ version = "0.8.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
version = "0.1.0"
|
||||
|
|
|
|||
|
|
@ -36,10 +36,10 @@ derive_more = {version = "0.99"}
|
|||
|
||||
# tracing
|
||||
tracing = { version = "0.1.37" }
|
||||
tracing-futures = "0.2.5"
|
||||
tracing-subscriber = { version = "0.3.16", features = ["registry", "env-filter", "ansi", "json"] }
|
||||
tracing-bunyan-formatter = "0.3.6"
|
||||
tracing-appender = "0.2.2"
|
||||
tracing-actix-web = "0.7"
|
||||
tracing-log = "0.1.1"
|
||||
|
||||
ormx = { version = "0.10.0", features = ["postgres"]}
|
||||
[dependencies.sqlx]
|
||||
|
|
@ -56,7 +56,7 @@ features = [
|
|||
]
|
||||
|
||||
[[bin]]
|
||||
name = "http_server"
|
||||
name = "appflowy_server"
|
||||
path = "src/main.rs"
|
||||
|
||||
|
||||
|
|
|
|||
12
Dockerfile
12
Dockerfile
|
|
@ -2,11 +2,11 @@ FROM rust:1.56.1 as builder
|
|||
WORKDIR /app
|
||||
|
||||
COPY . .
|
||||
WORKDIR /app/services/http_server
|
||||
WORKDIR /app/services/appflowy_server
|
||||
ENV SQLX_OFFLINE true
|
||||
RUN RUSTFLAGS="-C opt-level=2" cargo build --release --bin http_server
|
||||
RUN RUSTFLAGS="-C opt-level=2" cargo build --release --bin appflowy_server
|
||||
# Size optimization
|
||||
#RUN strip ./target/release/http_server
|
||||
#RUN strip ./target/release/appflowy_server
|
||||
|
||||
FROM debian:bullseye-slim AS runtime
|
||||
WORKDIR /app
|
||||
|
|
@ -17,7 +17,7 @@ RUN apt-get update -y \
|
|||
&& apt-get clean -y \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY --from=builder /app/services/target/release/http_server /usr/local/bin/http_server
|
||||
COPY --from=builder /app/services/http_server/configuration configuration
|
||||
COPY --from=builder /app/services/target/release/appflowy_server /usr/local/bin/appflowy_server
|
||||
COPY --from=builder /app/services/appflowy_server/configuration configuration
|
||||
ENV APP_ENVIRONMENT production
|
||||
CMD ["http_server"]
|
||||
CMD ["appflowy_server"]
|
||||
|
|
|
|||
4
Makefile
4
Makefile
|
|
@ -1,4 +1,4 @@
|
|||
ROOT = "./scripts"
|
||||
ROOT = "./build"
|
||||
SEMVER_VERSION=$(shell grep version Cargo.toml | awk -F"\"" '{print $$2}' | head -n 1)
|
||||
|
||||
.PHONY: init_database docker_image local_server docker_test
|
||||
|
|
@ -8,7 +8,7 @@ init_database:
|
|||
|
||||
docker_image:
|
||||
source $(ROOT)/docker_env.sh && docker-compose up -d postgres_db
|
||||
source $(ROOT)/docker_env.sh && docker-compose up -d http_server
|
||||
source $(ROOT)/docker_env.sh && docker-compose up -d appflowy_server
|
||||
|
||||
local_server:
|
||||
cargo run
|
||||
|
|
|
|||
|
|
@ -8,15 +8,15 @@ services:
|
|||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||
ports:
|
||||
- "5434:5432"
|
||||
http_server:
|
||||
appflowy_server:
|
||||
restart: on-failure
|
||||
environment:
|
||||
- APP_ENVIRONMENT=production
|
||||
- DATABASE_URL="postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db/${POSTGRES_DB}"
|
||||
build:
|
||||
context: ../../
|
||||
dockerfile: ./services/http_server/Dockerfile
|
||||
image: http_server:${BACKEND_VERSION}
|
||||
dockerfile: ./services/appflowy_server/Dockerfile
|
||||
image: appflowy_server:${BACKEND_VERSION}
|
||||
depends_on:
|
||||
- postgres_db
|
||||
ports:
|
||||
|
|
|
|||
|
|
@ -3,10 +3,11 @@ use actix_web::{dev::Server, middleware, web, web::Data, App, HttpServer};
|
|||
use sqlx::{postgres::PgPoolOptions, PgPool};
|
||||
use std::net::TcpListener;
|
||||
use std::sync::Arc;
|
||||
use tracing_actix_web::TracingLogger;
|
||||
|
||||
use crate::api::{token_scope, user_scope};
|
||||
|
||||
use crate::config::config::{Config, DatabaseSettings};
|
||||
use crate::config::config::{Config, DatabaseSetting};
|
||||
use crate::config::env::{domain, secret};
|
||||
use crate::middleware::cors::default_cors;
|
||||
use crate::state::State;
|
||||
|
|
@ -46,6 +47,7 @@ pub fn run(listener: TcpListener, state: State) -> Result<Server, std::io::Error
|
|||
.wrap(middleware::Logger::default())
|
||||
.wrap(IdentityMiddleware::default())
|
||||
.wrap(default_cors())
|
||||
.wrap(TracingLogger::default())
|
||||
.app_data(web::JsonConfig::default().limit(4096))
|
||||
.service(user_scope())
|
||||
.service(token_scope())
|
||||
|
|
@ -72,7 +74,7 @@ pub async fn init_state(configuration: &Config) -> State {
|
|||
}
|
||||
}
|
||||
|
||||
pub async fn get_connection_pool(setting: &DatabaseSettings) -> Result<PgPool, sqlx::Error> {
|
||||
pub async fn get_connection_pool(setting: &DatabaseSetting) -> Result<PgPool, sqlx::Error> {
|
||||
PgPoolOptions::new()
|
||||
.connect_timeout(std::time::Duration::from_secs(5))
|
||||
.connect_with(setting.with_db())
|
||||
|
|
|
|||
|
|
@ -1,22 +0,0 @@
|
|||
use tracing_subscriber::layer::SubscriberExt;
|
||||
use tracing_subscriber::util::SubscriberInitExt;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
pub fn init_log() {
|
||||
if std::env::var_os("RUST_LOG").is_none() {
|
||||
std::env::set_var("RUST_LOG", "debug");
|
||||
}
|
||||
let subscriber = tracing_subscriber::fmt()
|
||||
.with_target(true)
|
||||
.with_max_level(tracing::Level::TRACE)
|
||||
.with_writer(std::io::stderr)
|
||||
.with_thread_ids(true)
|
||||
.compact()
|
||||
.finish()
|
||||
.with(EnvFilter::from_default_env());
|
||||
|
||||
// let formatting_layer = BunyanFormattingLayer::new(self.name, std::io::stdout);
|
||||
// set_global_default(subscriber.with(JsonStorageLayer).with(formatting_layer)).map_err(|e| format!("{:?}", e))?;
|
||||
|
||||
subscriber.try_init().unwrap()
|
||||
}
|
||||
|
|
@ -1 +1 @@
|
|||
pub mod log;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use std::convert::{TryFrom, TryInto};
|
|||
|
||||
#[derive(serde::Deserialize, Clone, Debug)]
|
||||
pub struct Config {
|
||||
pub database: DatabaseSettings,
|
||||
pub database: DatabaseSetting,
|
||||
pub application: ApplicationSettings,
|
||||
}
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ pub struct ApplicationSettings {
|
|||
}
|
||||
|
||||
#[derive(serde::Deserialize, Clone, Debug)]
|
||||
pub struct DatabaseSettings {
|
||||
pub struct DatabaseSetting {
|
||||
pub username: String,
|
||||
pub password: String,
|
||||
#[serde(deserialize_with = "deserialize_number_from_string")]
|
||||
|
|
@ -35,7 +35,7 @@ pub struct DatabaseSettings {
|
|||
pub require_ssl: bool,
|
||||
}
|
||||
|
||||
impl DatabaseSettings {
|
||||
impl DatabaseSetting {
|
||||
pub fn without_db(&self) -> PgConnectOptions {
|
||||
let ssl_mode = if self.require_ssl {
|
||||
PgSslMode::Require
|
||||
|
|
|
|||
|
|
@ -4,3 +4,4 @@ pub mod component;
|
|||
pub mod config;
|
||||
pub mod middleware;
|
||||
pub mod state;
|
||||
pub mod telemetry;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
use appflowy_server::application::{init_state, Application};
|
||||
use appflowy_server::component::log::init_log;
|
||||
use appflowy_server::config::config::get_configuration;
|
||||
use appflowy_server::telemetry::{get_subscriber, init_subscriber};
|
||||
|
||||
#[actix_web::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
init_log();
|
||||
let subscriber = get_subscriber("appflowy_server".into(), "info".into(), std::io::stdout);
|
||||
init_subscriber(subscriber);
|
||||
|
||||
let configuration = get_configuration().expect("Failed to read configuration.");
|
||||
let state = init_state(&configuration).await;
|
||||
let application = Application::build(configuration, state).await?;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
use actix_web::rt::task::JoinHandle;
|
||||
use tracing::subscriber::set_global_default;
|
||||
use tracing::Subscriber;
|
||||
use tracing_bunyan_formatter::{BunyanFormattingLayer, JsonStorageLayer};
|
||||
use tracing_log::LogTracer;
|
||||
use tracing_subscriber::fmt::MakeWriter;
|
||||
use tracing_subscriber::{layer::SubscriberExt, EnvFilter, Registry};
|
||||
|
||||
/// Compose multiple layers into a `tracing`'s subscriber.
|
||||
pub fn get_subscriber<Sink>(
|
||||
name: String,
|
||||
env_filter: String,
|
||||
sink: Sink,
|
||||
) -> impl Subscriber + Sync + Send
|
||||
where
|
||||
Sink: for<'a> MakeWriter<'a> + Send + Sync + 'static,
|
||||
{
|
||||
let env_filter =
|
||||
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new(env_filter));
|
||||
let formatting_layer = BunyanFormattingLayer::new(name, sink);
|
||||
Registry::default()
|
||||
.with(env_filter)
|
||||
.with(JsonStorageLayer)
|
||||
.with(formatting_layer)
|
||||
}
|
||||
|
||||
/// Register a subscriber as global default to process span data.
|
||||
///
|
||||
/// It should only be called once!
|
||||
pub fn init_subscriber(subscriber: impl Subscriber + Sync + Send) {
|
||||
LogTracer::init().expect("Failed to set logger");
|
||||
set_global_default(subscriber).expect("Failed to set subscriber");
|
||||
}
|
||||
|
||||
pub fn spawn_blocking_with_tracing<F, R>(f: F) -> JoinHandle<R>
|
||||
where
|
||||
F: FnOnce() -> R + Send + 'static,
|
||||
R: Send + 'static,
|
||||
{
|
||||
let current_span = tracing::Span::current();
|
||||
actix_web::rt::task::spawn_blocking(move || current_span.in_scope(f))
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
mod test_server;
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
use appflowy_server::application::{init_state, Application};
|
||||
use appflowy_server::config::config::{get_configuration, DatabaseSetting};
|
||||
use appflowy_server::state::State;
|
||||
use sqlx::types::Uuid;
|
||||
use sqlx::{Connection, Executor, PgConnection, PgPool};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TestServer {
|
||||
pub state: State,
|
||||
}
|
||||
|
||||
pub async fn spawn_server() -> TestServer {
|
||||
let database_name = Uuid::new_v4().to_string();
|
||||
let configuration = {
|
||||
let mut c = get_configuration().expect("Failed to read configuration.");
|
||||
c.database.database_name = database_name.clone();
|
||||
// Use a random OS port
|
||||
c.application.port = 0;
|
||||
c
|
||||
};
|
||||
|
||||
let _ = configure_database(&configuration.database).await;
|
||||
let state = init_state(&configuration).await;
|
||||
let application = Application::build(configuration.clone(), state.clone())
|
||||
.await
|
||||
.expect("Failed to build application.");
|
||||
|
||||
let _ = tokio::spawn(async {
|
||||
let _ = application.run_until_stopped();
|
||||
});
|
||||
|
||||
TestServer { state }
|
||||
}
|
||||
|
||||
async fn configure_database(config: &DatabaseSetting) -> PgPool {
|
||||
// Create database
|
||||
let mut connection = PgConnection::connect_with(&config.without_db())
|
||||
.await
|
||||
.expect("Failed to connect to Postgres");
|
||||
connection
|
||||
.execute(&*format!(r#"CREATE DATABASE "{}";"#, config.database_name))
|
||||
.await
|
||||
.expect("Failed to create database.");
|
||||
|
||||
// Migrate database
|
||||
let connection_pool = PgPool::connect_with(config.with_db())
|
||||
.await
|
||||
.expect("Failed to connect to Postgres.");
|
||||
|
||||
sqlx::migrate!("./migrations")
|
||||
.run(&connection_pool)
|
||||
.await
|
||||
.expect("Failed to migrate the database");
|
||||
|
||||
connection_pool
|
||||
}
|
||||
Loading…
Reference in New Issue