Skip to content

Commit bdf6bee

Browse files
committed
feat(Task 18): complete P1 metrics for WASM filter and Mobile Sidecar
1 parent a290eab commit bdf6bee

File tree

3 files changed

+35
-2
lines changed

3 files changed

+35
-2
lines changed

hybrid-cloud-poc/UPSTREAM_MERGE_ROADMAP.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ Effort: 2 days
474474
| **Task 15** | Quality Assurance - Linting, pre-commit hooks | P2 | `[x]` || Done |
475475
| **Task 16** | Cleanup stale backup files | P1 | `[x]` || Done |
476476
| **Task 17** | Rate limiting at Envoy gateway level | P2 | `[ ]` | TBD | Week 4 |
477-
| **Task 18** | Standardize Observability (Metrics & Telemetry) | P1 | `[/]` || Week 4 |
477+
| **Task 18** | Standardize Observability (Metrics & Telemetry) | P1 | `[x]` || Done |
478478

479479
### Task 15: Quality Assurance - Linting, pre-commit hooks (COMPLETE)
480480
```

hybrid-cloud-poc/enterprise-private-cloud/wasm-plugin/src/lib.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ struct MetricIds {
8282
verification_success: u32,
8383
verification_failure: u32,
8484
sidecar_call_total: u32,
85+
sidecar_latency_ms: u32,
8586
}
8687

8788
impl Default for PluginConfig {
@@ -177,7 +178,15 @@ impl RootContext for SensorVerificationRoot {
177178
MetricType::Counter,
178179
"wasm_filter_sidecar_call_total"
179180
).unwrap_or(0);
180-
proxy_wasm::hostcalls::log(LogLevel::Info, "WASM metrics defined");
181+
self.metrics.sidecar_latency_ms = proxy_wasm::hostcalls::define_metric(
182+
MetricType::Histogram,
183+
"wasm_filter_sidecar_latency_ms"
184+
).unwrap_or(0);
185+
proxy_wasm::hostcalls::log(LogLevel::Info, &format!(
186+
"WASM metrics defined: request_total={}, success={}, failure={}, sidecar_call={}, latency={}",
187+
self.metrics.request_total, self.metrics.verification_success, self.metrics.verification_failure,
188+
self.metrics.sidecar_call_total, self.metrics.sidecar_latency_ms
189+
));
181190

182191
true
183192
}
@@ -195,6 +204,7 @@ impl RootContext for SensorVerificationRoot {
195204
sensor_latitude: None,
196205
sensor_longitude: None,
197206
sensor_accuracy: None,
207+
sidecar_call_start_ms: None,
198208
}))
199209
}
200210

@@ -215,6 +225,7 @@ struct SensorVerificationFilter {
215225
sensor_latitude: Option<f64>,
216226
sensor_longitude: Option<f64>,
217227
sensor_accuracy: Option<f64>,
228+
sidecar_call_start_ms: Option<u64>,
218229
}
219230

220231
impl Context for SensorVerificationFilter {
@@ -227,6 +238,15 @@ impl Context for SensorVerificationFilter {
227238

228239
// Get response body
229240
let body_result = self.get_http_call_response_body(0, body_size);
241+
242+
// Record latency (Task 18: Observability)
243+
if let Some(start_time) = self.sidecar_call_start_ms {
244+
let now = self.get_current_time().duration_since(std::time::UNIX_EPOCH).unwrap_or_default().as_millis() as u64;
245+
let latency = now.saturating_sub(start_time);
246+
let _ = proxy_wasm::hostcalls::record_metric(self.metrics.sidecar_latency_ms, latency);
247+
proxy_wasm::hostcalls::log(LogLevel::Debug, &format!("Recorded sidecar latency: {}ms", latency));
248+
}
249+
230250
let body = match body_result {
231251
Some(b) => b,
232252
None => {
@@ -317,6 +337,10 @@ impl Context for SensorVerificationFilter {
317337

318338
impl HttpContext for SensorVerificationFilter {
319339
fn on_http_request_headers(&mut self, _num_headers: usize, _end_of_stream: bool) -> Action {
340+
// Increment request total (Task 18: Observability)
341+
let _ = proxy_wasm::hostcalls::increment_metric(self.metrics.request_total, 1);
342+
proxy_wasm::hostcalls::log(LogLevel::Debug, &format!("Incremented request_total (ID: {})", self.metrics.request_total));
343+
320344
// Get certificate chain from x-forwarded-client-cert header (set by forward_client_cert_details in Envoy)
321345
// Format: "By=...;Cert=\"...\";Chain=\"...\";Subject=...;URI=..."
322346
// The Unified Identity extension is in the agent SVID (second certificate in chain)
@@ -485,6 +509,10 @@ impl HttpContext for SensorVerificationFilter {
485509
Duration::from_secs(5),
486510
) {
487511
Ok(_) => {
512+
// Record start time and increment sidecar call count (Task 18: Observability)
513+
self.sidecar_call_start_ms = Some(self.get_current_time().duration_since(std::time::UNIX_EPOCH).unwrap_or_default().as_millis() as u64);
514+
let _ = proxy_wasm::hostcalls::increment_metric(self.metrics.sidecar_call_total, 1);
515+
488516
proxy_wasm::hostcalls::log(LogLevel::Info, &format!(
489517
"Mobile sensor (sensor_id={}): verification_mode={}, skip_cache={} - dispatched sidecar call",
490518
sensor_id, mode_str, skip_cache

hybrid-cloud-poc/mobile-sensor-microservice/service.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,9 @@ def create_app(db_path: Path) -> Flask:
347347

348348
@app.route("/verify", methods=["POST"])
349349
def verify():
350+
# Increment request total (Task 18: Observability)
351+
REQUEST_COUNT.labels(result='total').inc()
352+
350353
payload = request.get_json(force=True) or {}
351354
LOG.info("Request: %s", payload)
352355

@@ -378,10 +381,12 @@ def verify():
378381
sensor = database.get_sensor(sensor_id, payload.get("sensor_imei"), payload.get("sensor_imsi"), payload.get("sensor_serial_number"))
379382
if not sensor:
380383
LOG.error("Sensor not found in DB: %s", sensor_id)
384+
REQUEST_COUNT.labels(result='error').inc()
381385
return jsonify({"error": "sensor_not_found"}), 404
382386

383387
verifier = verifiers.get(sensor.get("sensor_type"))
384388
if not verifier:
389+
REQUEST_COUNT.labels(result='error').inc()
385390
return jsonify({"error": f"unsupported_sensor_type_in_mobile_sidecar: {sensor.get('sensor_type')}"}), 400
386391

387392
result = verifier.verify(sensor, skip_cache=payload.get("skip_cache", False))

0 commit comments

Comments
 (0)