mirror of
https://github.com/juspay/hyperswitch.git
synced 2026-03-13 09:02:06 +08:00
feat(metrics): add injector service metrics and observability (#9945)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
@@ -17,6 +17,7 @@ pub mod core {
|
||||
|
||||
use crate as injector_types;
|
||||
use crate::{
|
||||
metrics,
|
||||
types::{ContentType, InjectorRequest, InjectorResponse, IntoInjectorResponse},
|
||||
vault_metadata::VaultMetadataExtractorExt,
|
||||
};
|
||||
@@ -332,9 +333,46 @@ pub mod core {
|
||||
pub async fn injector_core(
|
||||
request: InjectorRequest,
|
||||
) -> error_stack::Result<InjectorResponse, InjectorError> {
|
||||
let start_time = std::time::Instant::now();
|
||||
logger::info!("Starting injector_core processing");
|
||||
|
||||
// Extract values for metrics before moving request
|
||||
let vault_connector_str = format!("{:?}", request.token_data.vault_connector);
|
||||
let http_method_str = format!("{:?}", request.connection_config.http_method);
|
||||
|
||||
// Track total number of invocations with vault connector dimension
|
||||
metrics::INJECTOR_INVOCATIONS_COUNT.add(
|
||||
1,
|
||||
router_env::metric_attributes!(("vault_connector", vault_connector_str.clone())),
|
||||
);
|
||||
|
||||
// Extract endpoint host for dimension (privacy-friendly)
|
||||
let endpoint_host = request
|
||||
.connection_config
|
||||
.endpoint
|
||||
.parse::<url::Url>()
|
||||
.map(|url| url.host_str().unwrap_or("unknown").to_string())
|
||||
.unwrap_or_else(|_| "invalid_url".to_string());
|
||||
|
||||
let injector = Injector::new();
|
||||
injector.injector_core(request).await
|
||||
let result = injector.injector_core(request).await;
|
||||
|
||||
// Record total request time and track success/failure
|
||||
let request_duration = start_time.elapsed();
|
||||
|
||||
let base_attributes = router_env::metric_attributes!(
|
||||
("vault_connector", vault_connector_str.clone()),
|
||||
("http_method", http_method_str.clone()),
|
||||
("endpoint_host", endpoint_host.clone())
|
||||
);
|
||||
|
||||
metrics::INJECTOR_REQUEST_TIME.record(request_duration.as_secs_f64(), base_attributes);
|
||||
|
||||
// Track success/failure metrics
|
||||
result.inspect_err(|e| {
|
||||
logger::error!("Injector core failed: {:?}", e);
|
||||
metrics::INJECTOR_FAILED_TOKEN_REPLACEMENTS_COUNT.add(1, base_attributes);
|
||||
})
|
||||
}
|
||||
|
||||
/// Represents a token reference found in a template string
|
||||
@@ -440,6 +478,7 @@ pub mod core {
|
||||
vault_data: &Value,
|
||||
vault_connector: &injector_types::VaultConnectors,
|
||||
) -> error_stack::Result<String, InjectorError> {
|
||||
let token_replacement_start = std::time::Instant::now();
|
||||
// Find all tokens using nom parser
|
||||
let tokens = find_all_tokens(&template);
|
||||
let mut result = template;
|
||||
@@ -460,6 +499,14 @@ pub mod core {
|
||||
result = result.replace(&token_pattern, &token_str);
|
||||
}
|
||||
|
||||
// Record token replacement time with vault connector dimension
|
||||
let token_replacement_duration = token_replacement_start.elapsed();
|
||||
let vault_connector_str = format!("{:?}", vault_connector);
|
||||
metrics::INJECTOR_TOKEN_REPLACEMENT_TIME.record(
|
||||
token_replacement_duration.as_secs_f64(),
|
||||
router_env::metric_attributes!(("vault_connector", vault_connector_str)),
|
||||
);
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
@@ -692,6 +739,21 @@ pub mod core {
|
||||
Proxy::default()
|
||||
};
|
||||
|
||||
// Track outgoing HTTP calls with dimensions
|
||||
let endpoint_host = config
|
||||
.endpoint
|
||||
.parse::<url::Url>()
|
||||
.map(|url| url.host_str().unwrap_or("unknown").to_string())
|
||||
.unwrap_or_else(|_| "invalid_url".to_string());
|
||||
|
||||
metrics::INJECTOR_OUTGOING_CALLS_COUNT.add(
|
||||
1,
|
||||
router_env::metric_attributes!(
|
||||
("http_method", format!("{:?}", config.http_method)),
|
||||
("endpoint_host", endpoint_host)
|
||||
),
|
||||
);
|
||||
|
||||
// Send request using local standalone http client
|
||||
let response = send_request(&proxy, request, None).await?;
|
||||
|
||||
@@ -776,6 +838,27 @@ pub mod core {
|
||||
"Token injection completed successfully"
|
||||
);
|
||||
|
||||
// Track successful token replacements with comprehensive dimensions
|
||||
let endpoint_host = request
|
||||
.connection_config
|
||||
.endpoint
|
||||
.parse::<url::Url>()
|
||||
.map(|url| url.host_str().unwrap_or("unknown").to_string())
|
||||
.unwrap_or_else(|_| "invalid_url".to_string());
|
||||
|
||||
let vault_connector_str = format!("{:?}", request.token_data.vault_connector);
|
||||
let http_method_str = format!("{:?}", request.connection_config.http_method);
|
||||
|
||||
metrics::INJECTOR_SUCCESSFUL_TOKEN_REPLACEMENTS_COUNT.add(
|
||||
1,
|
||||
router_env::metric_attributes!(
|
||||
("status_code", response.status_code.to_string()),
|
||||
("vault_connector", vault_connector_str),
|
||||
("http_method", http_method_str),
|
||||
("endpoint_host", endpoint_host)
|
||||
),
|
||||
);
|
||||
|
||||
Ok(response)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
pub mod consts;
|
||||
pub mod injector;
|
||||
pub mod metrics;
|
||||
pub mod types;
|
||||
pub mod vault_metadata;
|
||||
|
||||
|
||||
34
crates/injector/src/metrics.rs
Normal file
34
crates/injector/src/metrics.rs
Normal file
@@ -0,0 +1,34 @@
|
||||
use router_env::{counter_metric, global_meter, histogram_metric_f64};
|
||||
|
||||
global_meter!(GLOBAL_METER, "INJECTOR");
|
||||
|
||||
// Invocation metrics
|
||||
counter_metric!(INJECTOR_INVOCATIONS_COUNT, GLOBAL_METER); // Total number of invocations
|
||||
counter_metric!(INJECTOR_OUTGOING_CALLS_COUNT, GLOBAL_METER); // Total number of outgoing calls
|
||||
counter_metric!(INJECTOR_SUCCESSFUL_TOKEN_REPLACEMENTS_COUNT, GLOBAL_METER); // Successful token replacements with status code dimensions
|
||||
counter_metric!(INJECTOR_FAILED_TOKEN_REPLACEMENTS_COUNT, GLOBAL_METER); // Failed token replacements
|
||||
|
||||
// Performance metrics
|
||||
histogram_metric_f64!(INJECTOR_REQUEST_TIME, GLOBAL_METER); // Time taken for complete injector operation
|
||||
histogram_metric_f64!(INJECTOR_TOKEN_REPLACEMENT_TIME, GLOBAL_METER); // Time taken for token replacement operation
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_metrics_are_defined() {
|
||||
// This test ensures that all metrics are properly defined and accessible
|
||||
// The actual functionality will be tested through integration tests
|
||||
|
||||
// Test that we can access the counters (this will compile-fail if metrics aren't properly defined)
|
||||
let _ = &INJECTOR_INVOCATIONS_COUNT;
|
||||
let _ = &INJECTOR_OUTGOING_CALLS_COUNT;
|
||||
let _ = &INJECTOR_SUCCESSFUL_TOKEN_REPLACEMENTS_COUNT;
|
||||
let _ = &INJECTOR_FAILED_TOKEN_REPLACEMENTS_COUNT;
|
||||
|
||||
// Test that we can access the histograms
|
||||
let _ = &INJECTOR_REQUEST_TIME;
|
||||
let _ = &INJECTOR_TOKEN_REPLACEMENT_TIME;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user