use opentelemetry::KeyValue;
use opentelemetry_sdk::Resource;
use opentelemetry_semantic_conventions::attribute as semco;
use super::imds::ImdsClient;
pub fn eks_resource() -> Option<Resource> {
if !running_in_k8s() {
return None;
}
let imds = ImdsClient::new();
let attribute_options = [
Some(KeyValue::new(semco::CLOUD_PROVIDER, "aws")),
Some(KeyValue::new(semco::CLOUD_PLATFORM, "aws_eks")),
std::fs::read_to_string("/var/run/secrets/kubernetes.io/serviceaccount/namespace")
.ok()
.map(|s| s.trim().to_owned())
.filter(|s| !s.is_empty())
.map(|s| KeyValue::new(semco::K8S_NAMESPACE_NAME, s)),
std::env::var("HOSTNAME")
.ok()
.map(|s| s.trim().to_owned())
.filter(|s| !s.is_empty())
.map(|s| KeyValue::new(semco::K8S_POD_NAME, s)),
std::env::var("AWS_CLUSTER_NAME")
.ok()
.filter(|s| !s.is_empty())
.map(|s| KeyValue::new(semco::K8S_CLUSTER_NAME, s)),
get_container_id().map(|id| KeyValue::new(semco::CONTAINER_ID, id)),
imds.as_ref()
.and_then(|c| c.get("placement/region"))
.or_else(|| std::env::var("AWS_REGION").ok())
.map(|r| KeyValue::new(semco::CLOUD_REGION, r)),
imds.as_ref()
.and_then(|c| c.get_json::<Ec2IdentityCredentials>("identity-credentials/ec2/info"))
.and_then(|c| c.account_id)
.or_else(|| std::env::var("AWS_ACCOUNT_ID").ok())
.map(|a| KeyValue::new(semco::CLOUD_ACCOUNT_ID, a)),
];
Some(
Resource::builder()
.with_attributes(attribute_options.into_iter().flatten())
.build(),
)
}
fn running_in_k8s() -> bool {
std::path::Path::new("/var/run/secrets/kubernetes.io/serviceaccount/namespace").exists()
}
fn get_container_id() -> Option<String> {
if let Ok(content) = std::fs::read_to_string("/proc/1/cgroup") {
for line in content.lines() {
if let Some(id) = line.split(':').next_back() {
if id.contains("docker/") {
return id.split('/').next_back().map(String::from);
}
}
}
}
None
}
#[derive(serde::Deserialize)]
struct Ec2IdentityCredentials {
#[serde(rename = "AccountId")]
account_id: Option<String>,
}