migrate to tracing and remove log
This commit is contained in:
parent
d3a3b1e1f2
commit
88430a3e51
1
.env
1
.env
@ -5,4 +5,5 @@ ACTIX_DEMO_RUST_LOG=debug
|
|||||||
ACTIX_DEMO_TEST_RUST_LOG=debug
|
ACTIX_DEMO_TEST_RUST_LOG=debug
|
||||||
ACTIX_DEMO_HTTP_HOST=127.0.0.1
|
ACTIX_DEMO_HTTP_HOST=127.0.0.1
|
||||||
ACTIX_DEMO_HASH_COST=8
|
ACTIX_DEMO_HASH_COST=8
|
||||||
|
ACTIX_DEMO_LOGGER_FORMAT=plain
|
||||||
|
|
||||||
|
194
Cargo.lock
generated
194
Cargo.lock
generated
@ -57,12 +57,10 @@ dependencies = [
|
|||||||
"diesel",
|
"diesel",
|
||||||
"diesel_migrations",
|
"diesel_migrations",
|
||||||
"dotenv",
|
"dotenv",
|
||||||
"env_logger",
|
|
||||||
"envy",
|
"envy",
|
||||||
"futures",
|
"futures",
|
||||||
"lazy-regex",
|
"lazy-regex",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
|
||||||
"nanoid",
|
"nanoid",
|
||||||
"r2d2",
|
"r2d2",
|
||||||
"rand 0.8.3",
|
"rand 0.8.3",
|
||||||
@ -71,6 +69,12 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"timeago",
|
"timeago",
|
||||||
|
"tracing",
|
||||||
|
"tracing-actix-web",
|
||||||
|
"tracing-bunyan-formatter",
|
||||||
|
"tracing-futures",
|
||||||
|
"tracing-log",
|
||||||
|
"tracing-subscriber",
|
||||||
"uuid",
|
"uuid",
|
||||||
"validator",
|
"validator",
|
||||||
"validator_derive",
|
"validator_derive",
|
||||||
@ -453,17 +457,6 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "atty"
|
|
||||||
version = "0.2.14"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
|
||||||
dependencies = [
|
|
||||||
"hermit-abi",
|
|
||||||
"libc",
|
|
||||||
"winapi 0.3.9",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "0.1.7"
|
version = "0.1.7"
|
||||||
@ -975,19 +968,6 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "env_logger"
|
|
||||||
version = "0.8.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "17392a012ea30ef05a610aa97dfb49496e71c9f676b27879922ea5bdf60d9d3f"
|
|
||||||
dependencies = [
|
|
||||||
"atty",
|
|
||||||
"humantime",
|
|
||||||
"log",
|
|
||||||
"regex",
|
|
||||||
"termcolor",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "envy"
|
name = "envy"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
@ -1176,6 +1156,16 @@ dependencies = [
|
|||||||
"version_check 0.9.3",
|
"version_check 0.9.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gethostname"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e692e296bfac1d2533ef168d0b60ff5897b8b70a4009276834014dd8924cc028"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"winapi 0.3.9",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.1.16"
|
version = "0.1.16"
|
||||||
@ -1319,12 +1309,6 @@ version = "1.4.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4a1ce40d6fc9764887c2fdc7305c3dcc429ba11ff981c1509416afd5697e4437"
|
checksum = "4a1ce40d6fc9764887c2fdc7305c3dcc429ba11ff981c1509416afd5697e4437"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "humantime"
|
|
||||||
version = "2.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "idna"
|
name = "idna"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
@ -1529,6 +1513,15 @@ version = "0.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4"
|
checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "matchers"
|
||||||
|
version = "0.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1"
|
||||||
|
dependencies = [
|
||||||
|
"regex-automata",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "matches"
|
name = "matches"
|
||||||
version = "0.1.8"
|
version = "0.1.8"
|
||||||
@ -1700,6 +1693,12 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.7.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "opaque-debug"
|
name = "opaque-debug"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
@ -2179,6 +2178,16 @@ dependencies = [
|
|||||||
"regex-syntax",
|
"regex-syntax",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-automata"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.6.23"
|
version = "0.6.23"
|
||||||
@ -2359,6 +2368,15 @@ dependencies = [
|
|||||||
"opaque-debug",
|
"opaque-debug",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sharded-slab"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "79c719719ee05df97490f80a45acfc99e5a30ce98a1e4fb67aee422745ae14e3"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "signal-hook-registry"
|
name = "signal-hook-registry"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
@ -2472,15 +2490,6 @@ dependencies = [
|
|||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "termcolor"
|
|
||||||
version = "1.1.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
|
|
||||||
dependencies = [
|
|
||||||
"winapi-util",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.24"
|
version = "1.0.24"
|
||||||
@ -2501,6 +2510,15 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thread_local"
|
||||||
|
version = "1.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "threadpool"
|
name = "threadpool"
|
||||||
version = "1.8.1"
|
version = "1.8.1"
|
||||||
@ -2627,9 +2645,51 @@ dependencies = [
|
|||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"log",
|
"log",
|
||||||
"pin-project-lite 0.2.6",
|
"pin-project-lite 0.2.6",
|
||||||
|
"tracing-attributes",
|
||||||
"tracing-core",
|
"tracing-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-actix-web"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cc36fc2f840643e49d220d07cd7ca81bc31c7f6df25f164d4257971533dab354"
|
||||||
|
dependencies = [
|
||||||
|
"actix-web",
|
||||||
|
"futures",
|
||||||
|
"tracing",
|
||||||
|
"tracing-futures",
|
||||||
|
"uuid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-attributes"
|
||||||
|
version = "0.1.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c42e6fa53307c8a17e4ccd4dc81cf5ec38db9209f59b222210375b54ee40d1e2"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-bunyan-formatter"
|
||||||
|
version = "0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dce1eae70720bd6bb3944f7cf501761aeae658bd1f9293aa373c71a195064910"
|
||||||
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
|
"gethostname",
|
||||||
|
"log",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"tracing",
|
||||||
|
"tracing-core",
|
||||||
|
"tracing-log",
|
||||||
|
"tracing-subscriber",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-core"
|
name = "tracing-core"
|
||||||
version = "0.1.17"
|
version = "0.1.17"
|
||||||
@ -2649,6 +2709,49 @@ dependencies = [
|
|||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-log"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
"log",
|
||||||
|
"tracing-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-serde"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fb65ea441fbb84f9f6748fd496cf7f63ec9af5bca94dd86456978d055e8eb28b"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"tracing-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-subscriber"
|
||||||
|
version = "0.2.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aa5553bf0883ba7c9cbe493b085c29926bd41b66afc31ff72cf17ff4fb60dcd5"
|
||||||
|
dependencies = [
|
||||||
|
"ansi_term",
|
||||||
|
"chrono",
|
||||||
|
"lazy_static",
|
||||||
|
"matchers",
|
||||||
|
"regex",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"sharded-slab",
|
||||||
|
"smallvec",
|
||||||
|
"thread_local",
|
||||||
|
"tracing",
|
||||||
|
"tracing-core",
|
||||||
|
"tracing-log",
|
||||||
|
"tracing-serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "trust-dns-proto"
|
name = "trust-dns-proto"
|
||||||
version = "0.19.7"
|
version = "0.19.7"
|
||||||
@ -2959,15 +3062,6 @@ version = "0.4.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi-util"
|
|
||||||
version = "0.1.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
|
||||||
dependencies = [
|
|
||||||
"winapi 0.3.9",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-x86_64-pc-windows-gnu"
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
@ -11,8 +11,6 @@ actix-files = "0.5.0"
|
|||||||
actix-http = "2.2.0"
|
actix-http = "2.2.0"
|
||||||
bytes = "1.0.1"
|
bytes = "1.0.1"
|
||||||
futures = "0.3.14"
|
futures = "0.3.14"
|
||||||
log = "0.4.14"
|
|
||||||
env_logger = "0.8.3"
|
|
||||||
serde_json = "1.0.64"
|
serde_json = "1.0.64"
|
||||||
# json = "0.12.4"
|
# json = "0.12.4"
|
||||||
# listenfd = "0.3.3"
|
# listenfd = "0.3.3"
|
||||||
@ -36,6 +34,12 @@ derive-new = "0.5.9"
|
|||||||
diesel_migrations = "1.4.0"
|
diesel_migrations = "1.4.0"
|
||||||
actix-threadpool = "0.3.3"
|
actix-threadpool = "0.3.3"
|
||||||
envy = "0.4"
|
envy = "0.4"
|
||||||
|
tracing = { version = "0.1" }
|
||||||
|
tracing-log = "0.1.2"
|
||||||
|
tracing-subscriber = { version = "0.2.18", features = ["fmt", "registry", "env-filter"] }
|
||||||
|
tracing-futures = "0.2.5"
|
||||||
|
tracing-actix-web = "0.2.1"
|
||||||
|
tracing-bunyan-formatter = "0.2.4"
|
||||||
|
|
||||||
[dependencies.build-info]
|
[dependencies.build-info]
|
||||||
version = "=0.0.23"
|
version = "=0.0.23"
|
||||||
|
@ -44,7 +44,7 @@ impl ResponseError for DomainError {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
DomainError::DbError { source: _ } => {
|
DomainError::DbError { source: _ } => {
|
||||||
log::error!("{}", err);
|
tracing::error!("{}", err);
|
||||||
HttpResponse::InternalServerError().json(ErrorModel {
|
HttpResponse::InternalServerError().json(ErrorModel {
|
||||||
// error_code: 500,
|
// error_code: 500,
|
||||||
success: false,
|
success: false,
|
||||||
@ -52,7 +52,7 @@ impl ResponseError for DomainError {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
DomainError::DbPoolError { source: _ } => {
|
DomainError::DbPoolError { source: _ } => {
|
||||||
log::error!("{}", err);
|
tracing::error!("{}", err);
|
||||||
HttpResponse::InternalServerError().json(ErrorModel {
|
HttpResponse::InternalServerError().json(ErrorModel {
|
||||||
// error_code: 500,
|
// error_code: 500,
|
||||||
success: false,
|
success: false,
|
||||||
@ -67,14 +67,14 @@ impl ResponseError for DomainError {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
DomainError::EntityDoesNotExistError { message: _ } => {
|
DomainError::EntityDoesNotExistError { message: _ } => {
|
||||||
HttpResponse::Accepted().json(ErrorModel {
|
HttpResponse::NotFound().json(ErrorModel {
|
||||||
// error_code: 400,
|
// error_code: 400,
|
||||||
success: false,
|
success: false,
|
||||||
reason: err.to_string(),
|
reason: err.to_string(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
DomainError::ThreadPoolError { message: _ } => {
|
DomainError::ThreadPoolError { message: _ } => {
|
||||||
log::error!("{}", err);
|
tracing::error!("{}", err);
|
||||||
HttpResponse::InternalServerError().json(ErrorModel {
|
HttpResponse::InternalServerError().json(ErrorModel {
|
||||||
// error_code: 400,
|
// error_code: 400,
|
||||||
success: false,
|
success: false,
|
||||||
@ -82,7 +82,7 @@ impl ResponseError for DomainError {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
DomainError::AuthError { message: _ } => {
|
DomainError::AuthError { message: _ } => {
|
||||||
HttpResponse::Accepted().json(ErrorModel {
|
HttpResponse::Forbidden().json(ErrorModel {
|
||||||
// error_code: 400,
|
// error_code: 400,
|
||||||
success: false,
|
success: false,
|
||||||
reason: err.to_string(),
|
reason: err.to_string(),
|
||||||
|
22
src/lib.rs
22
src/lib.rs
@ -16,21 +16,31 @@ mod utils;
|
|||||||
|
|
||||||
use actix_files as fs;
|
use actix_files as fs;
|
||||||
use actix_identity::{CookieIdentityPolicy, IdentityService};
|
use actix_identity::{CookieIdentityPolicy, IdentityService};
|
||||||
use actix_web::{cookie::SameSite, middleware, web, App, HttpServer};
|
use actix_web::web::ServiceConfig;
|
||||||
use actix_web::{middleware::Logger, web::ServiceConfig};
|
use actix_web::{cookie::SameSite, web, App, HttpServer};
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use tracing_actix_web::TracingLogger;
|
||||||
|
|
||||||
use types::DbPool;
|
use types::DbPool;
|
||||||
|
|
||||||
build_info::build_info!(pub fn get_build_info);
|
build_info::build_info!(pub fn get_build_info);
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
|
#[serde(rename_all = "lowercase")]
|
||||||
|
pub enum LoggerFormat {
|
||||||
|
Json,
|
||||||
|
Plain,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, Clone)]
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
pub struct EnvConfig {
|
pub struct EnvConfig {
|
||||||
pub database_url: String,
|
pub database_url: String,
|
||||||
pub http_host: String,
|
pub http_host: String,
|
||||||
#[serde(default = "default_hash_cost")]
|
#[serde(default = "default_hash_cost")]
|
||||||
pub hash_cost: u8,
|
pub hash_cost: u8,
|
||||||
|
pub logger_format: LoggerFormat,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, Clone)]
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
@ -91,13 +101,9 @@ pub fn id_service(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn app_logger() -> Logger {
|
|
||||||
middleware::Logger::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn run(addr: String, app_data: AppData) -> io::Result<()> {
|
pub async fn run(addr: String, app_data: AppData) -> io::Result<()> {
|
||||||
let bi = get_build_info();
|
let bi = get_build_info();
|
||||||
log::info!("Starting {} {}", bi.crate_info.name, bi.crate_info.version);
|
tracing::info!("Starting {} {}", bi.crate_info.name, bi.crate_info.version);
|
||||||
println!(
|
println!(
|
||||||
r#"
|
r#"
|
||||||
__ .__ .___
|
__ .__ .___
|
||||||
@ -113,7 +119,7 @@ pub async fn run(addr: String, app_data: AppData) -> io::Result<()> {
|
|||||||
App::new()
|
App::new()
|
||||||
.configure(configure_app(app_data.clone()))
|
.configure(configure_app(app_data.clone()))
|
||||||
.wrap(id_service(&private_key))
|
.wrap(id_service(&private_key))
|
||||||
.wrap(app_logger())
|
.wrap(TracingLogger)
|
||||||
};
|
};
|
||||||
HttpServer::new(app).bind(addr)?.run().await
|
HttpServer::new(app).bind(addr)?.run().await
|
||||||
}
|
}
|
||||||
|
77
src/main.rs
77
src/main.rs
@ -1,9 +1,15 @@
|
|||||||
#![forbid(unsafe_code)]
|
#![forbid(unsafe_code)]
|
||||||
use actix_demo::{AppConfig, AppData, EnvConfig};
|
use actix_demo::{AppConfig, AppData, EnvConfig, LoggerFormat};
|
||||||
use diesel::{r2d2::ConnectionManager, SqliteConnection};
|
use diesel::{r2d2::ConnectionManager, SqliteConnection};
|
||||||
use env_logger::Env;
|
|
||||||
use io::ErrorKind;
|
use io::ErrorKind;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use tracing::subscriber::set_global_default;
|
||||||
|
use tracing_bunyan_formatter::{BunyanFormattingLayer, JsonStorageLayer};
|
||||||
|
use tracing_log::LogTracer;
|
||||||
|
use tracing_subscriber::fmt::format::FmtSpan;
|
||||||
|
use tracing_subscriber::{
|
||||||
|
layer::SubscriberExt, EnvFilter, FmtSubscriber, Registry,
|
||||||
|
};
|
||||||
|
|
||||||
#[actix_web::main]
|
#[actix_web::main]
|
||||||
async fn main() -> io::Result<()> {
|
async fn main() -> io::Result<()> {
|
||||||
@ -14,16 +20,6 @@ async fn main() -> io::Result<()> {
|
|||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let _ = env_logger::try_init_from_env(
|
|
||||||
Env::default().filter("ACTIX_DEMO_RUST_LOG"),
|
|
||||||
)
|
|
||||||
.map_err(|err| {
|
|
||||||
io::Error::new(
|
|
||||||
ErrorKind::Other,
|
|
||||||
format!("Failed to set up env logger: {:?}", err),
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let env_config = envy::prefixed("ACTIX_DEMO_")
|
let env_config = envy::prefixed("ACTIX_DEMO_")
|
||||||
.from_env::<EnvConfig>()
|
.from_env::<EnvConfig>()
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
@ -33,6 +29,8 @@ async fn main() -> io::Result<()> {
|
|||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
let _ = setup_logger(env_config.logger_format)?;
|
||||||
|
|
||||||
let connspec = &env_config.database_url;
|
let connspec = &env_config.database_url;
|
||||||
let manager = ConnectionManager::<SqliteConnection>::new(connspec);
|
let manager = ConnectionManager::<SqliteConnection>::new(connspec);
|
||||||
let pool = r2d2::Pool::builder().build(manager).map_err(|err| {
|
let pool = r2d2::Pool::builder().build(manager).map_err(|err| {
|
||||||
@ -68,3 +66,58 @@ async fn main() -> io::Result<()> {
|
|||||||
|
|
||||||
actix_demo::run(format!("{}:7800", env_config.http_host), app_data).await
|
actix_demo::run(format!("{}:7800", env_config.http_host), app_data).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn setup_logger(format: LoggerFormat) -> io::Result<()> {
|
||||||
|
let env_filter =
|
||||||
|
EnvFilter::try_from_env("ACTIX_DEMO_RUST_LOG").map_err(|err| {
|
||||||
|
io::Error::new(
|
||||||
|
ErrorKind::Other,
|
||||||
|
format!("Failed to set up env filter: {:?}", err),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let _ = LogTracer::init().map_err(|err| {
|
||||||
|
io::Error::new(
|
||||||
|
ErrorKind::Other,
|
||||||
|
format!("Failed to set up log tracer: {:?}", err),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let bi = actix_demo::get_build_info();
|
||||||
|
|
||||||
|
let _ = match format {
|
||||||
|
LoggerFormat::Json => {
|
||||||
|
let formatting_layer = BunyanFormattingLayer::new(
|
||||||
|
format!("actix-demo-{}", bi.crate_info.version),
|
||||||
|
// Output the formatted spans to stdout.
|
||||||
|
std::io::stdout,
|
||||||
|
);
|
||||||
|
let subscriber = Registry::default()
|
||||||
|
.with(env_filter)
|
||||||
|
.with(JsonStorageLayer)
|
||||||
|
.with(formatting_layer);
|
||||||
|
let _ = set_global_default(subscriber).map_err(|err| {
|
||||||
|
io::Error::new(
|
||||||
|
ErrorKind::Other,
|
||||||
|
format!("Failed to set subscriber: {:?}", err),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
|
||||||
|
LoggerFormat::Plain => {
|
||||||
|
let subscriber = FmtSubscriber::builder()
|
||||||
|
.pretty()
|
||||||
|
.with_span_events(FmtSpan::NEW)
|
||||||
|
.with_span_events(FmtSpan::CLOSE)
|
||||||
|
.with_env_filter(env_filter)
|
||||||
|
.finish();
|
||||||
|
let _ = set_global_default(subscriber).map_err(|err| {
|
||||||
|
io::Error::new(
|
||||||
|
ErrorKind::Other,
|
||||||
|
format!("Failed to set subscriber: {:?}", err),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
@ -38,6 +38,7 @@ pub async fn login(
|
|||||||
response
|
response
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: fix the response
|
||||||
#[get("/logout")]
|
#[get("/logout")]
|
||||||
pub async fn logout(
|
pub async fn logout(
|
||||||
id: Identity,
|
id: Identity,
|
||||||
@ -45,7 +46,7 @@ pub async fn logout(
|
|||||||
) -> Result<HttpResponse, Error> {
|
) -> Result<HttpResponse, Error> {
|
||||||
let maybe_identity = id.identity();
|
let maybe_identity = id.identity();
|
||||||
let response = if let Some(identity) = maybe_identity {
|
let response = if let Some(identity) = maybe_identity {
|
||||||
log::info!("Logging out {user}", user = identity);
|
tracing::info!("Logging out {user}", user = identity);
|
||||||
id.forget();
|
id.forget();
|
||||||
HttpResponse::Found().header("location", "/").finish()
|
HttpResponse::Found().header("location", "/").finish()
|
||||||
} else {
|
} else {
|
||||||
|
@ -7,11 +7,19 @@ use actix_web::error::ResponseError;
|
|||||||
use validator::Validate;
|
use validator::Validate;
|
||||||
|
|
||||||
/// Finds user by UID.
|
/// Finds user by UID.
|
||||||
|
#[tracing::instrument(
|
||||||
|
level = "debug",
|
||||||
|
skip(app_data),
|
||||||
|
fields(
|
||||||
|
user_id = %user_id.0
|
||||||
|
)
|
||||||
|
)]
|
||||||
pub async fn get_user(
|
pub async fn get_user(
|
||||||
app_data: web::Data<AppData>,
|
app_data: web::Data<AppData>,
|
||||||
user_id: web::Path<i32>,
|
user_id: web::Path<i32>,
|
||||||
) -> Result<HttpResponse, DomainError> {
|
) -> Result<HttpResponse, DomainError> {
|
||||||
let u_id = user_id.into_inner();
|
let u_id = user_id.into_inner();
|
||||||
|
tracing::info!("Getting user with id {}", u_id);
|
||||||
// use web::block to offload blocking Diesel code without blocking server thread
|
// use web::block to offload blocking Diesel code without blocking server thread
|
||||||
let res = web::block(move || {
|
let res = web::block(move || {
|
||||||
let pool = &app_data.pool;
|
let pool = &app_data.pool;
|
||||||
@ -20,6 +28,7 @@ pub async fn get_user(
|
|||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.map_err(|err| DomainError::new_thread_pool_error(err.to_string()))?;
|
.map_err(|err| DomainError::new_thread_pool_error(err.to_string()))?;
|
||||||
|
tracing::trace!("{:?}", res);
|
||||||
if let Some(user) = res {
|
if let Some(user) = res {
|
||||||
Ok(HttpResponse::Ok().json(user))
|
Ok(HttpResponse::Ok().json(user))
|
||||||
} else {
|
} else {
|
||||||
@ -61,7 +70,7 @@ pub async fn get_all_users(
|
|||||||
.await
|
.await
|
||||||
.map_err(|err| DomainError::new_thread_pool_error(err.to_string()))?;
|
.map_err(|err| DomainError::new_thread_pool_error(err.to_string()))?;
|
||||||
|
|
||||||
log::debug!("{:?}", users);
|
tracing::debug!("{:?}", users);
|
||||||
|
|
||||||
if !users.is_empty() {
|
if !users.is_empty() {
|
||||||
Ok(HttpResponse::Ok().json(users))
|
Ok(HttpResponse::Ok().json(users))
|
||||||
@ -87,7 +96,7 @@ pub async fn add_user(
|
|||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.map(|user| {
|
.map(|user| {
|
||||||
log::debug!("{:?}", user);
|
tracing::debug!("{:?}", user);
|
||||||
HttpResponse::Created().json(user)
|
HttpResponse::Created().json(user)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
@ -2,5 +2,3 @@ pub mod auth;
|
|||||||
pub mod regexs;
|
pub mod regexs;
|
||||||
pub use self::auth::*;
|
pub use self::auth::*;
|
||||||
pub use self::regexs::*;
|
pub use self::regexs::*;
|
||||||
pub mod ops;
|
|
||||||
pub use self::ops::*;
|
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
use std::fmt::Display;
|
|
||||||
|
|
||||||
pub trait LogErrorResult<T, E> {
|
|
||||||
fn log_err(self) -> Result<T, E>;
|
|
||||||
}
|
|
||||||
impl<T, E: Display> LogErrorResult<T, E> for Result<T, E> {
|
|
||||||
fn log_err(self) -> Result<T, E> {
|
|
||||||
self.map_err(|err| {
|
|
||||||
log::error!("{}", err.to_string());
|
|
||||||
err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait ResultOps<T, E> {
|
|
||||||
fn tap<U, F: FnOnce(T) -> U>(self, op: F) -> Result<T, E>;
|
|
||||||
fn tap_err<F, O: FnOnce(E) -> F>(self, op: O) -> Result<T, E>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Clone, E: Clone> ResultOps<T, E> for Result<T, E> {
|
|
||||||
fn tap<U, F: FnOnce(T) -> U>(self, op: F) -> Result<T, E> {
|
|
||||||
self.map(|x| {
|
|
||||||
op(x.clone());
|
|
||||||
x
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn tap_err<F, O: FnOnce(E) -> F>(self, op: O) -> Result<T, E> {
|
|
||||||
self.map_err(|err| {
|
|
||||||
op(err.clone());
|
|
||||||
err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,59 +1,92 @@
|
|||||||
extern crate actix_demo;
|
extern crate actix_demo;
|
||||||
use actix_demo::{AppConfig, AppData};
|
use actix_demo::{AppConfig, AppData, EnvConfig};
|
||||||
use actix_web::test;
|
use actix_web::test;
|
||||||
use actix_web::App;
|
use actix_web::App;
|
||||||
use diesel::SqliteConnection;
|
use diesel::SqliteConnection;
|
||||||
|
|
||||||
use diesel::r2d2::{self, ConnectionManager};
|
use diesel::r2d2::{self, ConnectionManager};
|
||||||
use env_logger::Env;
|
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::ErrorKind;
|
use std::io::ErrorKind;
|
||||||
|
use tracing::subscriber::set_global_default;
|
||||||
|
use tracing_actix_web::TracingLogger;
|
||||||
|
use tracing_log::LogTracer;
|
||||||
|
use tracing_subscriber::fmt::{format::FmtSpan, Subscriber as FmtSubscriber};
|
||||||
|
use tracing_subscriber::{layer::SubscriberExt, EnvFilter};
|
||||||
|
|
||||||
use actix_demo::configure_app;
|
use actix_demo::configure_app;
|
||||||
|
|
||||||
use actix_http::Request;
|
use actix_http::Request;
|
||||||
use actix_web::{dev as ax_dev, Error as AxError};
|
use actix_web::{dev as ax_dev, Error as AxError};
|
||||||
|
|
||||||
pub async fn test_app() -> impl ax_dev::Service<
|
pub async fn test_app() -> io::Result<
|
||||||
Request = Request,
|
impl ax_dev::Service<
|
||||||
Response = ax_dev::ServiceResponse<impl ax_dev::MessageBody>,
|
Request = Request,
|
||||||
Error = AxError,
|
Response = ax_dev::ServiceResponse<impl ax_dev::MessageBody>,
|
||||||
|
Error = AxError,
|
||||||
|
>,
|
||||||
> {
|
> {
|
||||||
let _ = dotenv::dotenv()
|
let _ = dotenv::dotenv().map_err(|err| {
|
||||||
|
io::Error::new(
|
||||||
|
ErrorKind::Other,
|
||||||
|
format!("Failed to set up env: {:?}", err),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let _ = envy::prefixed("ACTIX_DEMO_")
|
||||||
|
.from_env::<EnvConfig>()
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
io::Error::new(
|
io::Error::new(
|
||||||
ErrorKind::Other,
|
ErrorKind::Other,
|
||||||
format!("Failed to set up env: {:?}", err),
|
format!("Failed to parse config: {:?}", err),
|
||||||
)
|
)
|
||||||
})
|
})?;
|
||||||
.unwrap();
|
|
||||||
let _ = env_logger::builder()
|
let env_filter =
|
||||||
.is_test(true)
|
EnvFilter::try_from_env("ACTIX_DEMO_RUST_LOG").map_err(|err| {
|
||||||
.parse_env(Env::default().filter("ACTIX_DEMO_TEST_RUST_LOG"))
|
io::Error::new(
|
||||||
.try_init();
|
ErrorKind::Other,
|
||||||
|
format!("Failed to set up env logger: {:?}", err),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let _ = LogTracer::init().map_err(|err| {
|
||||||
|
io::Error::new(
|
||||||
|
ErrorKind::Other,
|
||||||
|
format!("Failed to set up log tracer: {:?}", err),
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
let subscriber = FmtSubscriber::builder()
|
||||||
|
.pretty()
|
||||||
|
.with_test_writer()
|
||||||
|
.with_span_events(FmtSpan::NEW)
|
||||||
|
.with_span_events(FmtSpan::CLOSE)
|
||||||
|
.finish()
|
||||||
|
.with(env_filter);
|
||||||
|
|
||||||
|
let _ = set_global_default(subscriber).map_err(|err| {
|
||||||
|
io::Error::new(
|
||||||
|
ErrorKind::Other,
|
||||||
|
format!("Failed to set subscriber: {:?}", err),
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
let connspec = ":memory:";
|
let connspec = ":memory:";
|
||||||
let manager = ConnectionManager::<SqliteConnection>::new(connspec);
|
let manager = ConnectionManager::<SqliteConnection>::new(connspec);
|
||||||
let pool = r2d2::Pool::builder()
|
let pool = r2d2::Pool::builder().build(manager).map_err(|err| {
|
||||||
.build(manager)
|
io::Error::new(
|
||||||
.map_err(|err| {
|
ErrorKind::Other,
|
||||||
io::Error::new(
|
format!("Failed to create pool: {:?}", err),
|
||||||
ErrorKind::Other,
|
)
|
||||||
format!("Failed to create pool: {:?}", err),
|
})?;
|
||||||
)
|
|
||||||
})
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let _ = {
|
let _ = {
|
||||||
let conn = &pool
|
let conn = &pool.get().map_err(|err| {
|
||||||
.get()
|
io::Error::new(
|
||||||
.map_err(|err| {
|
ErrorKind::Other,
|
||||||
io::Error::new(
|
format!("Failed to get connection: {:?}", err),
|
||||||
ErrorKind::Other,
|
)
|
||||||
format!("Failed to get connection: {:?}", err),
|
})?;
|
||||||
)
|
|
||||||
})
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let migrations_dir = diesel_migrations::find_migrations_directory()
|
let migrations_dir = diesel_migrations::find_migrations_directory()
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
@ -61,8 +94,7 @@ pub async fn test_app() -> impl ax_dev::Service<
|
|||||||
ErrorKind::Other,
|
ErrorKind::Other,
|
||||||
format!("Error finding migrations dir: {:?}", err),
|
format!("Error finding migrations dir: {:?}", err),
|
||||||
)
|
)
|
||||||
})
|
})?;
|
||||||
.unwrap();
|
|
||||||
let _ = diesel_migrations::run_pending_migrations_in_directory(
|
let _ = diesel_migrations::run_pending_migrations_in_directory(
|
||||||
conn,
|
conn,
|
||||||
&migrations_dir,
|
&migrations_dir,
|
||||||
@ -73,17 +105,16 @@ pub async fn test_app() -> impl ax_dev::Service<
|
|||||||
ErrorKind::Other,
|
ErrorKind::Other,
|
||||||
format!("Error running migrations: {:?}", err),
|
format!("Error running migrations: {:?}", err),
|
||||||
)
|
)
|
||||||
})
|
})?;
|
||||||
.unwrap();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
test::init_service(
|
Ok(test::init_service(
|
||||||
App::new()
|
App::new()
|
||||||
.configure(configure_app(AppData {
|
.configure(configure_app(AppData {
|
||||||
config: AppConfig { hash_cost: 8 },
|
config: AppConfig { hash_cost: 8 },
|
||||||
pool,
|
pool,
|
||||||
}))
|
}))
|
||||||
.wrap(actix_web::middleware::Logger::default()),
|
.wrap(TracingLogger),
|
||||||
)
|
)
|
||||||
.await
|
.await)
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,10 @@ mod tests {
|
|||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn get_build_info_should_succeed() {
|
async fn get_build_info_should_succeed() {
|
||||||
let req = test::TestRequest::get().uri("/api/build-info").to_request();
|
let req = test::TestRequest::get().uri("/api/build-info").to_request();
|
||||||
let resp = common::test_app().await.call(req).await.unwrap();
|
let resp = common::test_app().await.unwrap().call(req).await.unwrap();
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
let body: build_info::BuildInfo = test::read_body_json(resp).await;
|
let body: build_info::BuildInfo = test::read_body_json(resp).await;
|
||||||
|
tracing::debug!("{:?}", body);
|
||||||
assert_eq!(body, *get_build_info());
|
assert_eq!(body, *get_build_info());
|
||||||
log::debug!("{:?}", body);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,10 @@ mod tests {
|
|||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn get_users_api_should_return_error_message_if_no_users_exist() {
|
async fn get_users_api_should_return_error_message_if_no_users_exist() {
|
||||||
let req = test::TestRequest::get().uri("/api/users").to_request();
|
let req = test::TestRequest::get().uri("/api/users").to_request();
|
||||||
let resp = common::test_app().await.call(req).await.unwrap();
|
let resp = common::test_app().await.unwrap().call(req).await.unwrap();
|
||||||
assert_eq!(resp.status(), StatusCode::ACCEPTED);
|
assert_eq!(resp.status(), StatusCode::NOT_FOUND);
|
||||||
let body: ErrorModel = test::read_body_json(resp).await;
|
let body: ErrorModel = test::read_body_json(resp).await;
|
||||||
|
tracing::debug!("{:?}", body);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
body,
|
body,
|
||||||
ErrorModel {
|
ErrorModel {
|
||||||
@ -21,16 +22,16 @@ mod tests {
|
|||||||
reason: "Entity does not exist - No users available".to_owned()
|
reason: "Entity does not exist - No users available".to_owned()
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
log::debug!("{:?}", body);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn get_user_api_should_return_error_message_if_user_with_id_does_not_exist(
|
async fn get_user_api_should_return_error_message_if_user_with_id_does_not_exist(
|
||||||
) {
|
) {
|
||||||
let req = test::TestRequest::get().uri("/api/users/1").to_request();
|
let req = test::TestRequest::get().uri("/api/users/1").to_request();
|
||||||
let resp = common::test_app().await.call(req).await.unwrap();
|
let resp = common::test_app().await.unwrap().call(req).await.unwrap();
|
||||||
assert_eq!(resp.status(), StatusCode::ACCEPTED);
|
assert_eq!(resp.status(), StatusCode::NOT_FOUND);
|
||||||
let body: ErrorModel = test::read_body_json(resp).await;
|
let body: ErrorModel = test::read_body_json(resp).await;
|
||||||
|
tracing::debug!("{:?}", body);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
body,
|
body,
|
||||||
ErrorModel {
|
ErrorModel {
|
||||||
@ -39,6 +40,5 @@ mod tests {
|
|||||||
.to_owned()
|
.to_owned()
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
log::debug!("{:?}", body);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user