Skip to content

Commit

Permalink
Merge branch 'dev' into fix/#131-thread-main-panicked-at-trick-if-you…
Browse files Browse the repository at this point in the history
…-are-running-on-a-vm-when-machine-is-not-a-vm
  • Loading branch information
bpetit authored Jul 20, 2022
2 parents 9865e4c + f0be7fe commit 443d791
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 33 deletions.
14 changes: 14 additions & 0 deletions docs_src/tutorials/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,18 @@ Or if you downloaded or built a binary, you'd run:

scaphandre stdout -t 15

## Running scaphandre on Fedora / CentOS Stream / RHEL (or any distribution using SELinux) with podman

Running scaphandre with podman on a distribution using SELinux may fail because of access denied to `/proc` files.

To make it work you should run scaphandre in privileged mode :

podman run --privileged ...

You'll find explanation of this requirement here : [#106](https://github.com/hubblo-org/scaphandre/issues/106).

## Output

Here we are using the stdout [exporter](../explanations/internal-structure.md) to print current power consumption usage in the terminal during 15 seconds.

You should get an output like:
Expand All @@ -34,6 +46,8 @@ Then you have the 5 processes consuming the most power during the last two measu

If you don't get this output and get an error, jump to the [Troubleshooting](../troubleshooting.md) section of the documentation.

## Going further

At that point, you're ready to use scaphandre. The Stdout exporter is very basic and other exporters should allow you to use and send those metrics the way you like.

The [prometheus exporter](references/exporter-prometheus.md), for example, allows you to expose power consumption metrics as an HTTP endpoint that can be scrapped by a [prometheus](https://prometheus.io) instance:
Expand Down
26 changes: 21 additions & 5 deletions src/exporters/prometheus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use clap::{Arg, ArgMatches};
use hyper::service::{make_service_fn, service_fn};
use hyper::{Body, Request, Response, Server};
use std::convert::Infallible;
use std::fmt::Write as _;
use std::{
collections::HashMap,
net::{IpAddr, SocketAddr},
Expand Down Expand Up @@ -194,12 +195,12 @@ fn format_metric(key: &str, value: &str, labels: Option<&HashMap<String, String>
if let Some(labels) = labels {
result.push('{');
for (k, v) in labels.iter() {
result.push_str(&format!("{}=\"{}\",", k, v.replace('\"', "_")));
let _ = write!(result, "{}=\"{}\",", k, v.replace('\"', "_"));
}
result.remove(result.len() - 1);
result.push('}');
}
result.push_str(&format!(" {}\n", value));
let _ = writeln!(result, " {}", value);
result
}

Expand All @@ -210,9 +211,12 @@ fn push_metric(
metric_type: String,
metric_name: String,
metric_line: String,
add_help: bool,
) -> String {
body.push_str(&format!("# HELP {} {}", metric_name, help));
body.push_str(&format!("\n# TYPE {} {}\n", metric_name, metric_type));
if add_help {
let _ = write!(body, "# HELP {} {}", metric_name, help);
let _ = write!(body, "\n# TYPE {} {}\n", metric_name, metric_type);
}
body.push_str(&metric_line);
body
}
Expand Down Expand Up @@ -249,6 +253,8 @@ async fn show_metrics(

metric_generator.gen_all_metrics();

let mut metrics_pushed: Vec<String> = vec![];

// Send all data
for msg in metric_generator.pop_metrics() {
let mut attributes: Option<&HashMap<String, String>> = None;
Expand All @@ -263,16 +269,26 @@ async fn show_metrics(
MetricValueType::IntUnsigned(value) => value.to_string(),
MetricValueType::Text(ref value) => value.to_string(),
};

let mut should_i_add_help = true;

if metrics_pushed.contains(&msg.name) {
should_i_add_help = false;
} else {
metrics_pushed.insert(0, msg.name.clone());
}

body = push_metric(
body,
msg.description.clone(),
msg.metric_type.clone(),
msg.name.clone(),
format_metric(&msg.name, &value, attributes),
should_i_add_help,
);
}
} else {
body.push_str(&format!("<a href=\"https://github.com/hubblo-org/scaphandre/\">Scaphandre's</a> prometheus exporter here. Metrics available on <a href=\"/{}\">/{}</a>", suffix, suffix));
let _ = write!(body, "<a href=\"https://github.com/hubblo-org/scaphandre/\">Scaphandre's</a> prometheus exporter here. Metrics available on <a href=\"/{}\">/{}</a>", suffix, suffix);
}
Ok(Response::new(body.into()))
}
Expand Down
29 changes: 15 additions & 14 deletions src/exporters/stdout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::exporters::*;
use crate::sensors::Sensor;
use colored::*;
use regex::Regex;
use std::fmt::Write as _;
use std::thread;
use std::time::{Duration, Instant};

Expand Down Expand Up @@ -215,20 +216,20 @@ impl StdoutExporter {
return true;
}
}
false
}) {
to_print.push_str(&format!(
"{} W\t",
current_domain
.metric_value
.to_string()
.parse::<f32>()
.unwrap()
/ 1000000.0
));
} else {
to_print.push_str("---");
}
false
}) {
let _ = write!(
to_print,
"{} W\t",
current_domain
.metric_value
.to_string()
.parse::<f32>()
.unwrap()
/ 1000000.0
);
} else {
to_print.push_str("---");
}
}

Expand Down
36 changes: 22 additions & 14 deletions src/sensors/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ impl ProcessTracker {
pub fn new(max_records_per_process: u16) -> ProcessTracker {
let regex_cgroup_docker = Regex::new(r"^/docker/.*$").unwrap();
let regex_cgroup_kubernetes = Regex::new(r"^/kubepods.*$").unwrap();
let regex_cgroup_containerd = Regex::new("/system.slice/containerd.service").unwrap();
let regex_cgroup_containerd = Regex::new("/system.slice/containerd.service/.*$").unwrap();
ProcessTracker {
procs: vec![],
max_records_per_process,
Expand Down Expand Up @@ -165,6 +165,9 @@ impl ProcessTracker {
if container_id.ends_with(".scope") {
container_id = container_id.strip_suffix(".scope").unwrap().to_string();
}
if container_id.contains("cri-containerd") {
container_id = container_id.split(':').last().unwrap().to_string();
}
Ok(container_id)
}

Expand Down Expand Up @@ -225,12 +228,20 @@ impl ProcessTracker {
}
}
found = true;
} else if self.regex_cgroup_kubernetes.is_match(&cg.pathname) {
// kubernetes
description.insert(
String::from("container_scheduler"),
String::from("kubernetes"),
);
} else {
// containerd
if self.regex_cgroup_containerd.is_match(&cg.pathname) {
description.insert(
String::from("container_runtime"),
String::from("containerd"),
);
} else if self.regex_cgroup_kubernetes.is_match(&cg.pathname) {
// kubernetes not using containerd but we can get the container id
} else {
// cgroup not related to a container technology
continue;
}

let container_id =
match self.extract_pod_id_from_cgroup_path(cg.pathname.clone()) {
Ok(id) => id,
Expand Down Expand Up @@ -273,6 +284,10 @@ impl ProcessTracker {
}
None => false,
}) {
description.insert(
String::from("container_scheduler"),
String::from("kubernetes"),
);
if let Some(pod_name) = &pod.metadata.name {
description
.insert(String::from("kubernetes_pod_name"), pod_name.clone());
Expand All @@ -293,13 +308,6 @@ impl ProcessTracker {
}
}
found = true;
} else if self.regex_cgroup_containerd.is_match(&cg.pathname) {
// containerd
description.insert(
String::from("container_runtime"),
String::from("containerd"),
);
found = true;
} //else {
// debug!("Cgroup not identified as related to a container technology : {}", &cg.pathname);
//}
Expand Down

0 comments on commit 443d791

Please sign in to comment.