添加tracing日志并重构服务器启动逻辑
This commit is contained in:
parent
9c834ba1df
commit
4093178fc3
@ -1 +1,2 @@
|
||||
DATABASE_URL=postgres://postgres:postgres@localhost:5432/yggdrasil
|
||||
RUST_LOG=info
|
||||
|
||||
34
Cargo.lock
generated
34
Cargo.lock
generated
@ -2436,6 +2436,15 @@ dependencies = [
|
||||
"jni-sys 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.50.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
|
||||
dependencies = [
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-conv"
|
||||
version = "0.2.2"
|
||||
@ -3724,6 +3733,7 @@ dependencies = [
|
||||
"tower",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
"url",
|
||||
]
|
||||
|
||||
@ -3769,6 +3779,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"valuable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3781,6 +3792,17 @@ dependencies = [
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-log"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
|
||||
dependencies = [
|
||||
"log",
|
||||
"once_cell",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.3.23"
|
||||
@ -3788,12 +3810,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319"
|
||||
dependencies = [
|
||||
"matchers",
|
||||
"nu-ansi-term",
|
||||
"once_cell",
|
||||
"regex-automata",
|
||||
"sharded-slab",
|
||||
"smallvec",
|
||||
"thread_local",
|
||||
"tracing",
|
||||
"tracing-core",
|
||||
"tracing-log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3961,6 +3986,12 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
@ -4637,6 +4668,9 @@ dependencies = [
|
||||
"serde",
|
||||
"tokio",
|
||||
"tokio-postgres",
|
||||
"tower-http",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"uuid",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
|
||||
@ -15,6 +15,9 @@ chrono = { version = "0.4", features = ["serde"] }
|
||||
regex = "1.12"
|
||||
pulldown-cmark = "0.13"
|
||||
dotenvy = { version = "0.15", optional = true }
|
||||
tracing = { version = "0.1", optional = true }
|
||||
tracing-subscriber = { version = "0.3", optional = true }
|
||||
tower-http = { version = "0.6", features = ["trace"], optional = true }
|
||||
rand = { version = "0.8", features = ["getrandom"] }
|
||||
getrandom = { version = "0.2", features = ["js"] }
|
||||
http = "1"
|
||||
@ -42,4 +45,7 @@ server = [
|
||||
"dep:tokio-postgres",
|
||||
"dep:deadpool-postgres",
|
||||
"dep:dotenvy",
|
||||
"dep:tracing",
|
||||
"dep:tracing-subscriber",
|
||||
"dep:tower-http",
|
||||
]
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
use crate::api::auth::{get_current_user, logout};
|
||||
use crate::components::header::{Header, NavItemConfig};
|
||||
use crate::components::admin_skeleton::AdminDashboardSkeleton;
|
||||
use crate::components::footer::Footer;
|
||||
use crate::components::admin_skeleton::{AdminSkeleton, AdminDashboardSkeleton};
|
||||
use crate::components::header::{Header, NavItemConfig};
|
||||
use crate::components::write_skeleton::WriteSkeleton;
|
||||
use crate::context::UserContext;
|
||||
use crate::router::Route;
|
||||
@ -39,12 +39,12 @@ pub fn AdminLayout() -> Element {
|
||||
NavItemConfig {
|
||||
href: "/admin",
|
||||
label: "仪表盘",
|
||||
is_active: matches!(route, Route::AdminPage {}),
|
||||
is_active: matches!(route, Route::Admin {}),
|
||||
},
|
||||
NavItemConfig {
|
||||
href: "/admin/write",
|
||||
label: "写文章",
|
||||
is_active: matches!(route, Route::WritePage {}),
|
||||
is_active: matches!(route, Route::Write {}),
|
||||
},
|
||||
NavItemConfig {
|
||||
href: "/",
|
||||
@ -53,15 +53,13 @@ pub fn AdminLayout() -> Element {
|
||||
},
|
||||
];
|
||||
|
||||
let nav = navigator.clone();
|
||||
let logout_button = rsx! {
|
||||
button {
|
||||
class: "text-sm text-gray-600 dark:text-[#9b9c9d] hover:text-gray-900 dark:hover:text-[#dadadb] transition-colors",
|
||||
onclick: move |_| {
|
||||
let nav = nav.clone();
|
||||
spawn(async move {
|
||||
let _ = logout().await;
|
||||
let _ = nav.push("/login");
|
||||
let _ = navigator.push("/login");
|
||||
});
|
||||
},
|
||||
"登出"
|
||||
@ -94,7 +92,7 @@ pub fn AdminLayout() -> Element {
|
||||
Header { nav_items: admin_nav_items, right_content: logout_button }
|
||||
main { class: "flex-1 w-full max-w-5xl mx-auto px-6 py-8",
|
||||
{match route {
|
||||
Route::WritePage {} => rsx! { WriteSkeleton {} },
|
||||
Route::Write {} => rsx! { WriteSkeleton {} },
|
||||
_ => rsx! { AdminDashboardSkeleton {} },
|
||||
}}
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ use dioxus::prelude::*;
|
||||
|
||||
#[component]
|
||||
pub fn Footer() -> Element {
|
||||
let mut visible = use_signal(|| false);
|
||||
let visible = use_signal(|| false);
|
||||
|
||||
use_effect(move || {
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
|
||||
@ -2,5 +2,4 @@ pub mod header;
|
||||
pub mod footer;
|
||||
pub mod admin_layout;
|
||||
pub mod admin_skeleton;
|
||||
pub use admin_skeleton::{AdminSkeleton, AdminDashboardSkeleton};
|
||||
pub mod write_skeleton;
|
||||
|
||||
32
src/main.rs
32
src/main.rs
@ -9,17 +9,37 @@ mod router;
|
||||
mod tasks;
|
||||
mod theme;
|
||||
|
||||
use router::AppRouter;
|
||||
|
||||
fn main() {
|
||||
#[cfg(feature = "server")]
|
||||
{
|
||||
dotenvy::dotenv().ok();
|
||||
std::thread::spawn(|| {
|
||||
let rt = tokio::runtime::Runtime::new().expect("Failed to create Tokio runtime");
|
||||
rt.block_on(tasks::session_cleanup::run_cleanup());
|
||||
tracing_subscriber::fmt()
|
||||
.with_env_filter(
|
||||
tracing_subscriber::EnvFilter::try_from_default_env()
|
||||
.unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("info")),
|
||||
)
|
||||
.init();
|
||||
|
||||
dioxus::server::serve(|| async move {
|
||||
use dioxus::server::{axum, DioxusRouterExt, ServeConfig};
|
||||
use tower_http::trace::TraceLayer;
|
||||
|
||||
tokio::spawn(async {
|
||||
tasks::session_cleanup::run_cleanup().await;
|
||||
});
|
||||
|
||||
let config = ServeConfig::new();
|
||||
let router = axum::Router::new()
|
||||
.layer(TraceLayer::new_for_http())
|
||||
.serve_dioxus_application(config, router::AppRouter);
|
||||
|
||||
Ok(router)
|
||||
});
|
||||
}
|
||||
|
||||
dioxus::launch(AppRouter);
|
||||
#[cfg(not(feature = "server"))]
|
||||
{
|
||||
use router::AppRouter;
|
||||
dioxus::launch(AppRouter);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ use dioxus::prelude::*;
|
||||
use crate::pages::home::{Post, POSTS};
|
||||
|
||||
#[component]
|
||||
pub fn AdminPage() -> Element {
|
||||
pub fn Admin() -> Element {
|
||||
rsx! {
|
||||
div { class: "space-y-8",
|
||||
// 统计卡片
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
pub mod dashboard;
|
||||
pub mod write;
|
||||
|
||||
pub use dashboard::AdminPage;
|
||||
pub use write::WritePage;
|
||||
pub use dashboard::Admin;
|
||||
pub use write::Write;
|
||||
|
||||
@ -6,9 +6,9 @@ use wasm_bindgen::JsCast;
|
||||
use crate::components::write_skeleton::WriteSkeleton;
|
||||
|
||||
#[component]
|
||||
pub fn WritePage() -> Element {
|
||||
pub fn Write() -> Element {
|
||||
let mut title = use_signal(|| "".to_string());
|
||||
let mut content = use_signal(|| "".to_string());
|
||||
let content = use_signal(|| "".to_string());
|
||||
let mut loading = use_signal(|| true);
|
||||
|
||||
// 初始化 Tiptap 编辑器
|
||||
|
||||
@ -114,14 +114,14 @@ fn group_posts(posts: &[Post]) -> Vec<YearGroup> {
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn ArchivesPage() -> Element {
|
||||
pub fn Archives() -> Element {
|
||||
let route = use_route::<Route>();
|
||||
let nav_items = vec![
|
||||
NavItemConfig { href: "/", label: "首页", is_active: matches!(route, Route::HomePage {}) },
|
||||
NavItemConfig { href: "/archives", label: "归档", is_active: matches!(route, Route::ArchivesPage {}) },
|
||||
NavItemConfig { href: "/tags", label: "标签", is_active: matches!(route, Route::TagsPage {}) || matches!(route, Route::TagDetailPage { .. }) },
|
||||
NavItemConfig { href: "/search", label: "搜索", is_active: matches!(route, Route::SearchPage {}) },
|
||||
NavItemConfig { href: "/about", label: "关于", is_active: matches!(route, Route::AboutPage {}) },
|
||||
NavItemConfig { href: "/", label: "首页", is_active: matches!(route, Route::Home {}) },
|
||||
NavItemConfig { href: "/archives", label: "归档", is_active: matches!(route, Route::Archives {}) },
|
||||
NavItemConfig { href: "/tags", label: "标签", is_active: matches!(route, Route::Tags {}) || matches!(route, Route::TagDetail { .. }) },
|
||||
NavItemConfig { href: "/search", label: "搜索", is_active: matches!(route, Route::Search {}) },
|
||||
NavItemConfig { href: "/about", label: "关于", is_active: matches!(route, Route::About {}) },
|
||||
];
|
||||
|
||||
let grouped = group_posts(POSTS);
|
||||
|
||||
@ -60,14 +60,14 @@ pub const POSTS: &[Post] = &[
|
||||
];
|
||||
|
||||
#[component]
|
||||
pub fn HomePage() -> Element {
|
||||
pub fn Home() -> Element {
|
||||
let route = use_route::<Route>();
|
||||
let nav_items = vec![
|
||||
NavItemConfig { href: "/", label: "首页", is_active: matches!(route, Route::HomePage {}) },
|
||||
NavItemConfig { href: "/archives", label: "归档", is_active: matches!(route, Route::ArchivesPage {}) },
|
||||
NavItemConfig { href: "/tags", label: "标签", is_active: matches!(route, Route::TagsPage {}) || matches!(route, Route::TagDetailPage { .. }) },
|
||||
NavItemConfig { href: "/search", label: "搜索", is_active: matches!(route, Route::SearchPage {}) },
|
||||
NavItemConfig { href: "/about", label: "关于", is_active: matches!(route, Route::AboutPage {}) },
|
||||
NavItemConfig { href: "/", label: "首页", is_active: matches!(route, Route::Home {}) },
|
||||
NavItemConfig { href: "/archives", label: "归档", is_active: matches!(route, Route::Archives {}) },
|
||||
NavItemConfig { href: "/tags", label: "标签", is_active: matches!(route, Route::Tags {}) || matches!(route, Route::TagDetail { .. }) },
|
||||
NavItemConfig { href: "/search", label: "搜索", is_active: matches!(route, Route::Search {}) },
|
||||
NavItemConfig { href: "/about", label: "关于", is_active: matches!(route, Route::About {}) },
|
||||
];
|
||||
|
||||
rsx! {
|
||||
|
||||
@ -3,7 +3,7 @@ use dioxus::prelude::*;
|
||||
use crate::api::auth::{login, AuthResponse};
|
||||
|
||||
#[component]
|
||||
pub fn LoginPage() -> Element {
|
||||
pub fn Login() -> Element {
|
||||
let mut username = use_signal(|| "".to_string());
|
||||
let mut password = use_signal(|| "".to_string());
|
||||
let mut error = use_signal(|| None::<String>);
|
||||
|
||||
@ -3,7 +3,7 @@ use dioxus::prelude::*;
|
||||
use crate::api::auth::{register, AuthResponse};
|
||||
|
||||
#[component]
|
||||
pub fn RegisterPage() -> Element {
|
||||
pub fn Register() -> Element {
|
||||
let mut username = use_signal(|| "".to_string());
|
||||
let mut email = use_signal(|| "".to_string());
|
||||
let mut password = use_signal(|| "".to_string());
|
||||
|
||||
@ -40,14 +40,14 @@ fn posts_for_tag(tag: &str) -> Vec<Post> {
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn TagsPage() -> Element {
|
||||
pub fn Tags() -> Element {
|
||||
let route = use_route::<Route>();
|
||||
let nav_items = vec![
|
||||
NavItemConfig { href: "/", label: "首页", is_active: matches!(route, Route::HomePage {}) },
|
||||
NavItemConfig { href: "/archives", label: "归档", is_active: matches!(route, Route::ArchivesPage {}) },
|
||||
NavItemConfig { href: "/tags", label: "标签", is_active: matches!(route, Route::TagsPage {}) || matches!(route, Route::TagDetailPage { .. }) },
|
||||
NavItemConfig { href: "/search", label: "搜索", is_active: matches!(route, Route::SearchPage {}) },
|
||||
NavItemConfig { href: "/about", label: "关于", is_active: matches!(route, Route::AboutPage {}) },
|
||||
NavItemConfig { href: "/", label: "首页", is_active: matches!(route, Route::Home {}) },
|
||||
NavItemConfig { href: "/archives", label: "归档", is_active: matches!(route, Route::Archives {}) },
|
||||
NavItemConfig { href: "/tags", label: "标签", is_active: matches!(route, Route::Tags {}) || matches!(route, Route::TagDetail { .. }) },
|
||||
NavItemConfig { href: "/search", label: "搜索", is_active: matches!(route, Route::Search {}) },
|
||||
NavItemConfig { href: "/about", label: "关于", is_active: matches!(route, Route::About {}) },
|
||||
];
|
||||
|
||||
let tags = collect_tags();
|
||||
@ -92,14 +92,14 @@ pub fn TagsPage() -> Element {
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn TagDetailPage(tag: String) -> Element {
|
||||
pub fn TagDetail(tag: String) -> Element {
|
||||
let route = use_route::<Route>();
|
||||
let nav_items = vec![
|
||||
NavItemConfig { href: "/", label: "首页", is_active: matches!(route, Route::HomePage {}) },
|
||||
NavItemConfig { href: "/archives", label: "归档", is_active: matches!(route, Route::ArchivesPage {}) },
|
||||
NavItemConfig { href: "/tags", label: "标签", is_active: matches!(route, Route::TagsPage {}) || matches!(route, Route::TagDetailPage { .. }) },
|
||||
NavItemConfig { href: "/search", label: "搜索", is_active: matches!(route, Route::SearchPage {}) },
|
||||
NavItemConfig { href: "/about", label: "关于", is_active: matches!(route, Route::AboutPage {}) },
|
||||
NavItemConfig { href: "/", label: "首页", is_active: matches!(route, Route::Home {}) },
|
||||
NavItemConfig { href: "/archives", label: "归档", is_active: matches!(route, Route::Archives {}) },
|
||||
NavItemConfig { href: "/tags", label: "标签", is_active: matches!(route, Route::Tags {}) || matches!(route, Route::TagDetail { .. }) },
|
||||
NavItemConfig { href: "/search", label: "搜索", is_active: matches!(route, Route::Search {}) },
|
||||
NavItemConfig { href: "/about", label: "关于", is_active: matches!(route, Route::About {}) },
|
||||
];
|
||||
|
||||
let posts = posts_for_tag(&tag);
|
||||
|
||||
@ -3,43 +3,43 @@ use std::sync::Arc;
|
||||
|
||||
use crate::components::admin_layout::AdminLayout;
|
||||
use crate::context::UserContext;
|
||||
use crate::pages::admin::{AdminPage, WritePage};
|
||||
use crate::pages::archives::ArchivesPage;
|
||||
use crate::pages::home::HomePage;
|
||||
use crate::pages::login::LoginPage;
|
||||
use crate::pages::register::RegisterPage;
|
||||
use crate::pages::tags::{TagsPage, TagDetailPage};
|
||||
use crate::theme::{Theme, ThemePreload, use_theme_provider};
|
||||
use crate::pages::admin::{Admin, Write};
|
||||
use crate::pages::archives::Archives;
|
||||
use crate::pages::home::Home;
|
||||
use crate::pages::login::Login;
|
||||
use crate::pages::register::Register;
|
||||
use crate::pages::tags::{TagDetail, Tags};
|
||||
use crate::theme::{use_theme_provider, Theme, ThemePreload};
|
||||
|
||||
#[derive(Clone, Routable, Debug, PartialEq)]
|
||||
#[rustfmt::skip]
|
||||
pub enum Route {
|
||||
#[route("/")]
|
||||
HomePage {},
|
||||
Home {},
|
||||
#[route("/login")]
|
||||
LoginPage {},
|
||||
Login {},
|
||||
#[route("/register")]
|
||||
RegisterPage {},
|
||||
Register {},
|
||||
|
||||
#[nest("/admin")]
|
||||
#[layout(AdminLayout)]
|
||||
#[route("/")]
|
||||
AdminPage {},
|
||||
Admin {},
|
||||
#[route("/write")]
|
||||
WritePage {},
|
||||
Write {},
|
||||
#[end_layout]
|
||||
#[end_nest]
|
||||
|
||||
#[route("/archives")]
|
||||
ArchivesPage {},
|
||||
Archives {},
|
||||
#[route("/tags")]
|
||||
TagsPage {},
|
||||
Tags {},
|
||||
#[route("/tags/:tag")]
|
||||
TagDetailPage { tag: String },
|
||||
TagDetail { tag: String },
|
||||
#[route("/search")]
|
||||
SearchPage {},
|
||||
Search {},
|
||||
#[route("/about")]
|
||||
AboutPage {},
|
||||
About {},
|
||||
}
|
||||
|
||||
#[component]
|
||||
@ -64,11 +64,11 @@ pub fn AppRouter() -> Element {
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn SearchPage() -> Element {
|
||||
pub fn Search() -> Element {
|
||||
rsx! { "Search" }
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn AboutPage() -> Element {
|
||||
pub fn About() -> Element {
|
||||
rsx! { "About" }
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user