diff --git a/README.md b/README.md index 45614ad..1ddbfa7 100644 --- a/README.md +++ b/README.md @@ -16,10 +16,12 @@ AppSignal for Kubernetes will start sending Kubernetes automatically. ## Metrics -AppSignal for Kubernetes extracts metrics for all nodes running in a cluster every minute. +AppSignal for Kubernetes extracts metrics for all nodes and pods running in a cluster every minute. It extracts the following metrics from the `/api/v1/nodes//proxy/stats/summary` endpoint: +### Node metrics + - node_cpu_usage_nano_cores - node_cpu_usage_core_nano_seconds - node_memory_usage_bytes @@ -41,6 +43,14 @@ It extracts the following metrics from the `/api/v1/nodes//proxy/stats/sum - node_swap_available_bytes - node_swap_usage_bytes +### Pod metrics + +- pod_cpu_usage_nano_cores +- pod_cpu_usage_core_nano_seconds +- pod_memory_working_set_bytes +- pod_swap_available_bytes +- pod_swap_usage_bytes + ## Automated Dashboard After installing AppSignal for Kubernetes into a cluster, an Automated Dashboard automatically appears on AppSignal showing you an overview of the nodes in your Kubernetes cluster. diff --git a/src/main.rs b/src/main.rs index 5014359..6cf807e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -69,6 +69,18 @@ async fn run() -> Result<(), Error> { .request::(kube_request) .await?; + if let Some(pods) = kube_response["pods"].as_array() { + for pod in pods { + extract_pod_metrics( + pod, + pod["podRef"]["name"] + .as_str() + .expect("Could not extract pod name"), + &mut out, + ); + } + }; + extract_node_metrics(kube_response, &name, &mut out); } @@ -94,6 +106,32 @@ async fn run() -> Result<(), Error> { Ok(()) } +fn extract_pod_metrics(results: &Value, pod_name: &str, out: &mut Vec) { + for (metric_name, metric_value) in [ + ( + "pod_cpu_usage_nano_cores", + &results["cpu"]["usageNanoCores"], + ), + ( + "pod_cpu_usage_core_nano_seconds", + &results["cpu"]["usageCoreNanoSeconds"], + ), + ( + "pod_memory_working_set_bytes", + &results["memory"]["workingSetBytes"], + ), + ( + "pod_swap_available_bytes", + &results["swap"]["swapAvailableBytes"], + ), + ("pod_swap_usage_bytes", &results["swap"]["swapUsageBytes"]), + ] { + let mut tags = HashMap::with_capacity(1); + tags.insert("pod".to_owned(), pod_name.to_owned()); + out.push(AppsignalMetric::new(metric_name, tags, metric_value)); + } +} + fn extract_node_metrics(results: Value, node_name: &str, out: &mut Vec) { for (metric_name, metric_value) in [ ( @@ -176,6 +214,7 @@ fn extract_node_metrics(results: Value, node_name: &str, out: &mut Vec