-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
20 changed files
with
247 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
use std::time::Duration; | ||
|
||
use rust_extensions::date_time::DateTimeAsMicroseconds; | ||
use tokio::sync::Mutex; | ||
|
||
#[derive(Debug, Clone)] | ||
pub struct RequestMetric { | ||
pub moment: DateTimeAsMicroseconds, | ||
pub name: String, | ||
pub duration: Duration, | ||
pub status_code: u16, | ||
pub result_size: usize, | ||
} | ||
|
||
pub struct RequestMetrics { | ||
data: Mutex<Vec<RequestMetric>>, | ||
} | ||
|
||
impl RequestMetrics { | ||
pub fn new() -> Self { | ||
Self { | ||
data: Mutex::new(Vec::new()), | ||
} | ||
} | ||
|
||
pub async fn add_metric( | ||
&self, | ||
name: String, | ||
duration: Duration, | ||
status_code: u16, | ||
result_size: usize, | ||
) { | ||
let metric = RequestMetric { | ||
moment: DateTimeAsMicroseconds::now(), | ||
name: name, | ||
duration, | ||
status_code, | ||
result_size, | ||
}; | ||
|
||
let mut data = self.data.lock().await; | ||
data.push(metric); | ||
|
||
while data.len() > 100 { | ||
data.remove(0); | ||
} | ||
} | ||
|
||
pub async fn get_metrics(&self) -> Vec<RequestMetric> { | ||
let data = self.data.lock().await; | ||
data.clone() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
use std::sync::Arc; | ||
|
||
use my_http_server::{ | ||
HttpContext, HttpFailResult, HttpOkResult, HttpOutput, HttpServerMiddleware, | ||
HttpServerRequestFlow, | ||
}; | ||
use rust_extensions::StopWatch; | ||
|
||
use crate::{app::AppContext, db::DbTable}; | ||
|
||
pub struct WriteMetricContext { | ||
db_table: Arc<DbTable>, | ||
stop_watch: StopWatch, | ||
} | ||
|
||
pub struct RequestMetricsWriter { | ||
app: Arc<AppContext>, | ||
} | ||
|
||
impl RequestMetricsWriter { | ||
pub fn new(app: Arc<AppContext>) -> Self { | ||
Self { app } | ||
} | ||
|
||
async fn get_metrics_context(&self, ctx: &mut HttpContext) -> Option<WriteMetricContext> { | ||
if let Ok(qs) = ctx.request.get_query_string() { | ||
if let Some(table_name) = qs.get_optional("tableName") { | ||
if let Ok(table_name) = table_name.as_string() { | ||
if let Some(db_table) = self.app.db.get_table(table_name.as_str()).await { | ||
let mut result = WriteMetricContext { | ||
db_table, | ||
stop_watch: StopWatch::new(), | ||
}; | ||
|
||
result.stop_watch.start(); | ||
return result.into(); | ||
} | ||
} | ||
} | ||
} | ||
|
||
None | ||
} | ||
} | ||
|
||
#[async_trait::async_trait] | ||
impl HttpServerMiddleware for RequestMetricsWriter { | ||
async fn handle_request( | ||
&self, | ||
ctx: &mut HttpContext, | ||
get_next: &mut HttpServerRequestFlow, | ||
) -> Result<HttpOkResult, HttpFailResult> { | ||
let metrics_context = self.get_metrics_context(ctx).await; | ||
let result = get_next.next(ctx).await; | ||
|
||
if let Some(mut metrics_context) = metrics_context { | ||
metrics_context.stop_watch.pause(); | ||
|
||
let (result_code, result_size) = match &result { | ||
Ok(result) => ( | ||
result.output.get_status_code(), | ||
get_content_size(&result.output), | ||
), | ||
Err(err) => (err.status_code, 0), | ||
}; | ||
|
||
metrics_context | ||
.db_table | ||
.request_metrics | ||
.add_metric( | ||
format!("[{}]{}", ctx.request.get_method(), ctx.request.get_path(),), | ||
metrics_context.stop_watch.duration(), | ||
result_code, | ||
result_size, | ||
) | ||
.await; | ||
} | ||
|
||
result | ||
} | ||
} | ||
|
||
fn get_content_size(src: &HttpOutput) -> usize { | ||
match src { | ||
HttpOutput::Empty => 0, | ||
HttpOutput::Content { | ||
headers: _, | ||
content_type: _, | ||
content, | ||
} => content.len(), | ||
HttpOutput::Redirect { url: _ } => 0, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
mod models; | ||
mod non_initialized; | ||
mod requests_action; | ||
mod status; | ||
pub use status::StatusController; | ||
mod status_bar_model; | ||
pub use requests_action::RequestsAction; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
use std::sync::Arc; | ||
|
||
use my_http_server::{HttpContext, HttpFailResult, HttpOkResult, HttpOutput}; | ||
|
||
use crate::app::AppContext; | ||
|
||
use super::models::{RequestActionInputContract, RequestContract}; | ||
|
||
#[my_http_server_swagger::http_route( | ||
method: "GET", | ||
route: "/Monitoring/Requests", | ||
input_data: "RequestActionInputContract", | ||
description: "Get Requests statistic", | ||
controller: "Monitoring", | ||
)] | ||
pub struct RequestsAction { | ||
app: Arc<AppContext>, | ||
} | ||
|
||
impl RequestsAction { | ||
pub fn new(app: Arc<AppContext>) -> Self { | ||
Self { app } | ||
} | ||
} | ||
|
||
async fn handle_request( | ||
action: &RequestsAction, | ||
input_data: RequestActionInputContract, | ||
_ctx: &mut HttpContext, | ||
) -> Result<HttpOkResult, HttpFailResult> { | ||
let db_table = | ||
crate::db_operations::read::table::get(action.app.as_ref(), input_data.table_name.as_str()) | ||
.await?; | ||
|
||
let src = db_table.request_metrics.get_metrics().await; | ||
|
||
let mut result = Vec::with_capacity(src.len()); | ||
|
||
for metric in db_table.request_metrics.get_metrics().await { | ||
result.push(RequestContract::from(metric)); | ||
} | ||
|
||
return Ok(HttpOutput::as_json(result).into_ok_result(true)); | ||
} |
Oops, something went wrong.