| 330 | } |
| 331 | |
| 332 | async fn get_metrics( |
| 333 | &self, |
| 334 | request: Request<api::GetGatewayMetricsRequest>, |
| 335 | ) -> Result<Response<api::GetGatewayMetricsResponse>, Status> { |
| 336 | let req = request.get_ref(); |
| 337 | let gateway_id = EUI64::from_str(&req.gateway_id).map_err(|e| e.status())?; |
| 338 | |
| 339 | self.validator |
| 340 | .validate( |
| 341 | request.extensions(), |
| 342 | validator::ValidateGatewayAccess::new(validator::Flag::Read, gateway_id), |
| 343 | ) |
| 344 | .await?; |
| 345 | |
| 346 | let start = SystemTime::try_from( |
| 347 | *req.start |
| 348 | .as_ref() |
| 349 | .ok_or_else(|| anyhow!("start is None")) |
| 350 | .map_err(|e| e.status())?, |
| 351 | ) |
| 352 | .map_err(|e| e.status())?; |
| 353 | |
| 354 | let end = SystemTime::try_from( |
| 355 | *req.end |
| 356 | .as_ref() |
| 357 | .ok_or_else(|| anyhow!("end is None")) |
| 358 | .map_err(|e| e.status())?, |
| 359 | ) |
| 360 | .map_err(|e| e.status())?; |
| 361 | |
| 362 | let start: DateTime<Local> = start.into(); |
| 363 | let end: DateTime<Local> = end.into(); |
| 364 | let aggregation = req.aggregation().from_proto(); |
| 365 | |
| 366 | let gw_metrics = metrics::get( |
| 367 | &format!("gw:{}", gateway_id), |
| 368 | metrics::Kind::ABSOLUTE, |
| 369 | aggregation, |
| 370 | start, |
| 371 | end, |
| 372 | ) |
| 373 | .await |
| 374 | .map_err(|e| e.status())?; |
| 375 | |
| 376 | let out = api::GetGatewayMetricsResponse { |
| 377 | rx_packets: Some(common::Metric { |
| 378 | name: "Received".to_string(), |
| 379 | timestamps: gw_metrics |
| 380 | .iter() |
| 381 | .map(|row| { |
| 382 | let ts: DateTime<Utc> = row.time.into(); |
| 383 | let ts: pbjson_types::Timestamp = ts.into(); |
| 384 | ts |
| 385 | }) |
| 386 | .collect(), |
| 387 | datasets: vec![common::MetricDataset { |
| 388 | label: "rx_count".to_string(), |
| 389 | data: gw_metrics |