Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,14 @@ jobs:
toolchain: stable
- name: Install Protoc
uses: arduino/setup-protoc@v1
- run: cargo build --features static-files
- run: cargo build --features static-files
build-with-metrics:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Install Protoc
uses: arduino/setup-protoc@v1
- run: cargo build --features metrics
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ members = [
"my-http-server-signal-r-middleware",
"static-files-middleware",
"signal-r-macros",
"my-http-server-test",
"my-http-server-test", "my-http-metrics",
]
12 changes: 12 additions & 0 deletions my-http-metrics/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "my-http-metrics"
version = "0.1.0"
edition = "2021"

[dependencies]
my-http-server-core = { path = "../my-http-server-core" }
metrics = "*"
tokio = { version = "*", features = ["full"] }
async-trait = "*"
stopwatch = "*"
prometheus = "*"
3 changes: 3 additions & 0 deletions my-http-metrics/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod middleware;

pub use middleware::*;
79 changes: 79 additions & 0 deletions my-http-metrics/src/middleware/metrics_middleware.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use async_trait::async_trait;
use my_http_server_core::{
HttpContext, HttpFailResult, HttpOkResult, HttpOutput, HttpServerMiddleware,
HttpServerRequestFlow,
};
use stopwatch::Stopwatch;

pub struct MetricsMiddleware;

impl MetricsMiddleware {
pub fn new() -> Self {
Self {}
}
}

#[async_trait]
impl HttpServerMiddleware for MetricsMiddleware {
async fn handle_request(
&self,
ctx: &mut HttpContext,
get_next: &mut HttpServerRequestFlow,
) -> Result<HttpOkResult, HttpFailResult> {
let path = ctx.request.http_path.as_str().to_string();

if path == "/metrics" {
let report = prometheus::TextEncoder::new()
.encode_to_string(&prometheus::default_registry().gather());

match report {
Ok(report) => {
let response = HttpOutput::as_text(report).into_ok_result(false);
return response;
}
Err(err) => {
let response =
HttpOutput::as_text(err.to_string()).into_fail_result(502, false);
return response;
}
}
}

let mut sw = Stopwatch::start_new();
let result = get_next.next(ctx).await;
sw.stop();

let duration = sw.elapsed();
let method = ctx.request.method.as_str().to_string();
let path = ctx.request.http_path.as_str().to_string();
let common_labels = &[("method", method.clone()), ("path", path.clone())];

let mut has_to_write_metrics = false;

if let Err(result) = &result {
if result.status_code == 404 {
has_to_write_metrics = true
} else {
let failed_labels = &[
("method", method.clone()),
("path", path.clone()),
("status_code", result.status_code.to_string()),
];

metrics::counter!("failed_request_count", failed_labels).increment(1);
metrics::counter!("failed_request_duration_sum", failed_labels).increment(duration.as_millis() as u64);
metrics::histogram!("failed_request_duration_nanos", failed_labels).record(duration.as_millis() as f64);
}
}

if has_to_write_metrics {
return result;
}

metrics::histogram!("request_duration_nanos", common_labels).record(duration.as_millis() as f64);
metrics::counter!("request_duration_sum", common_labels).increment(duration.as_millis() as u64);
metrics::counter!("request_count", common_labels).increment(1);

return result;
}
}
3 changes: 3 additions & 0 deletions my-http-metrics/src/middleware/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod metrics_middleware;

pub use metrics_middleware::*;
2 changes: 1 addition & 1 deletion my-http-server-core/src/http_fail_result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ impl HttpFailResult {
pub fn as_not_found(text: String, write_telemetry: bool) -> Self {
Self::new(
WebContentType::Text,
400,
404,
text.into_bytes(),
write_telemetry,
false,
Expand Down
3 changes: 3 additions & 0 deletions my-http-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ full = [
"signal-r",
"with-telemetry",
"static-files",
"metrics",
]
controllers = ["my-http-server-controllers"]
macros = ["my-http-server-macros", "my-http-server-controllers"]
Expand All @@ -25,6 +26,7 @@ with-telemetry = [
]

static-files = ["static-files-middleware"]
metrics = ["my-http-metrics"]


[dependencies]
Expand All @@ -35,3 +37,4 @@ my-http-server-controllers = { optional = true, path = "../my-http-server-contro
my-http-server-core = { path = "../my-http-server-core" }
signal-r-macros = { optional = true, path = "../signal-r-macros" }
static-files-middleware = { path = "../static-files-middleware", optional = true }
my-http-metrics = { path = "../my-http-metrics", optional = true }
3 changes: 3 additions & 0 deletions my-http-server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ pub mod signal_r {
pub use static_files_middleware::*;

pub use my_http_server_core::*;

#[cfg(feature = "metrics")]
pub use my_http_metrics as metrics;