-
-
Notifications
You must be signed in to change notification settings - Fork 1
Add automatic status page with metrics dashboard #58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -34,6 +34,7 @@ pub struct RustApi { | |
| interceptors: InterceptorChain, | ||
| #[cfg(feature = "http3")] | ||
| http3_config: Option<crate::http3::Http3Config>, | ||
| status_config: Option<crate::status::StatusConfig>, | ||
| } | ||
|
|
||
| impl RustApi { | ||
|
|
@@ -61,6 +62,7 @@ impl RustApi { | |
| interceptors: InterceptorChain::new(), | ||
| #[cfg(feature = "http3")] | ||
| http3_config: None, | ||
| status_config: None, | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -869,6 +871,54 @@ impl RustApi { | |
| .route(path, docs_router) | ||
| } | ||
|
|
||
| /// Enable automatic status page with default configuration | ||
| pub fn status_page(self) -> Self { | ||
| self.status_page_with_config(crate::status::StatusConfig::default()) | ||
| } | ||
|
|
||
| /// Enable automatic status page with custom configuration | ||
| pub fn status_page_with_config(mut self, config: crate::status::StatusConfig) -> Self { | ||
| self.status_config = Some(config); | ||
| self | ||
| } | ||
|
Comment on lines
+874
to
+883
|
||
|
|
||
| // Helper to apply status page logic (monitor, layer, route) | ||
| fn apply_status_page(&mut self) { | ||
| if let Some(config) = &self.status_config { | ||
| let monitor = std::sync::Arc::new(crate::status::StatusMonitor::new()); | ||
|
|
||
| // 1. Add middleware layer | ||
| self.layers | ||
| .push(Box::new(crate::status::StatusLayer::new(monitor.clone()))); | ||
|
|
||
| // 2. Add status route | ||
| use crate::router::MethodRouter; | ||
| use std::collections::HashMap; | ||
|
|
||
| let monitor = monitor.clone(); | ||
| let config = config.clone(); | ||
| let path = config.path.clone(); // Clone path before moving config | ||
|
|
||
| let handler: crate::handler::BoxedHandler = std::sync::Arc::new(move |_| { | ||
| let monitor = monitor.clone(); | ||
| let config = config.clone(); | ||
| Box::pin(async move { | ||
| crate::status::status_handler(monitor, config) | ||
| .await | ||
| .into_response() | ||
| }) | ||
| }); | ||
|
|
||
| let mut handlers = HashMap::new(); | ||
| handlers.insert(http::Method::GET, handler); | ||
| let method_router = MethodRouter::from_boxed(handlers); | ||
|
|
||
| // We need to take the router out to call route() which consumes it | ||
| let router = std::mem::take(&mut self.router); | ||
| self.router = router.route(&path, method_router); | ||
| } | ||
| } | ||
|
|
||
| /// Run the server | ||
| /// | ||
| /// # Example | ||
|
|
@@ -880,6 +930,9 @@ impl RustApi { | |
| /// .await | ||
| /// ``` | ||
| pub async fn run(mut self, addr: &str) -> Result<(), Box<dyn std::error::Error + Send + Sync>> { | ||
| // Apply status page if configured | ||
| self.apply_status_page(); | ||
|
|
||
| // Apply body limit layer if configured (should be first in the chain) | ||
| if let Some(limit) = self.body_limit { | ||
| // Prepend body limit layer so it's the first to process requests | ||
|
|
@@ -899,9 +952,10 @@ impl RustApi { | |
| where | ||
| F: std::future::Future<Output = ()> + Send + 'static, | ||
| { | ||
| // Apply body limit layer if configured (should be first in the chain) | ||
| // Apply status page if configured | ||
| self.apply_status_page(); | ||
|
|
||
| if let Some(limit) = self.body_limit { | ||
| // Prepend body limit layer so it's the first to process requests | ||
| self.layers.prepend(Box::new(BodyLimitLayer::new(limit))); | ||
| } | ||
|
|
||
|
|
@@ -944,6 +998,9 @@ impl RustApi { | |
| ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> { | ||
| use std::sync::Arc; | ||
|
|
||
| // Apply status page if configured | ||
| self.apply_status_page(); | ||
|
|
||
| // Apply body limit layer if configured | ||
| if let Some(limit) = self.body_limit { | ||
| self.layers.prepend(Box::new(BodyLimitLayer::new(limit))); | ||
|
|
@@ -980,6 +1037,9 @@ impl RustApi { | |
| ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> { | ||
| use std::sync::Arc; | ||
|
|
||
| // Apply status page if configured | ||
| self.apply_status_page(); | ||
|
|
||
| // Apply body limit layer if configured | ||
| if let Some(limit) = self.body_limit { | ||
| self.layers.prepend(Box::new(BodyLimitLayer::new(limit))); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The workspace/package version here is
0.1.195, but the PR description and release notes text refer tov0.1.200. To avoid confusion when publishing and tagging, please align this version number with the version referenced in the release notes (or adjust the notes if0.1.195is the intended release).