Skip to content

brokkr-agent::diagnostics

Rust

Diagnostics handler for on-demand diagnostic collection.

This module provides functionality to collect detailed diagnostic information about Kubernetes resources, including pod statuses, events, and log tails.

pub

Derives: Debug, Clone, Serialize, Deserialize

Diagnostic request received from the broker.

Name Type Description
id Uuid Unique identifier for the diagnostic request.
agent_id Uuid The agent that should handle this request.
deployment_object_id Uuid The deployment object to gather diagnostics for.
status String Status: pending, claimed, completed, failed, expired.
requested_by Option<String> Who requested the diagnostics.
created_at DateTime<Utc> When the request was created.
claimed_at Option<DateTime<Utc>> When the agent claimed the request.
completed_at Option<DateTime<Utc>> When the request was completed.
expires_at DateTime<Utc> When the request expires.

pub

Derives: Debug, Clone, Serialize, Deserialize

Result to submit back to the broker.

Name Type Description
pod_statuses String JSON-encoded pod statuses.
events String JSON-encoded Kubernetes events.
log_tails Option<String> JSON-encoded log tails (optional).
collected_at DateTime<Utc> When the diagnostics were collected.

pub

Derives: Debug, Clone, Serialize, Deserialize

Pod status information for diagnostics.

Name Type Description
name String Pod name.
namespace String Pod namespace.
phase String Pod phase (Pending, Running, Succeeded, Failed, Unknown).
conditions Vec<PodCondition> Pod conditions.
containers Vec<ContainerStatus> Container statuses.

pub

Derives: Debug, Clone, Serialize, Deserialize

Pod condition information.

Name Type Description
condition_type String Condition type.
status String Condition status (True, False, Unknown).
reason Option<String> Reason for the condition.
message Option<String> Human-readable message.

pub

Derives: Debug, Clone, Serialize, Deserialize

Container status information.

Name Type Description
name String Container name.
ready bool Whether the container is ready.
restart_count i32 Number of restarts.
state String Current state of the container.
state_reason Option<String> Reason for current state.
state_message Option<String> Message for current state.

pub

Derives: Debug, Clone, Serialize, Deserialize

Kubernetes event information.

Name Type Description
event_type Option<String> Event type (Normal, Warning).
reason Option<String> Event reason.
message Option<String> Event message.
involved_object String Name of the object the event refers to, or "unknown" when the source event carries no name.
involved_object_kind Option<String> Kind of the object the event refers to (Pod, ReplicaSet, …). None when the source event omits it. Without this a bare name is ambiguous — several kinds in a namespace routinely share one.
first_timestamp Option<DateTime<Utc>> First timestamp.
last_timestamp Option<DateTime<Utc>> Last timestamp.
count Option<i32> Event count.

pub

Diagnostics handler for collecting Kubernetes diagnostics.

pub

fn new(client: Client) -> Self

Creates a new DiagnosticsHandler.

Source
pub fn new(client: Client) -> Self {
Self { client }
}

pub async

async fn collect_diagnostics(
&self,
namespace: &str,
deployment_object_id: Uuid,
) -> Result<SubmitDiagnosticResult, Box<dyn std::error::Error + Send + Sync>>

Collects diagnostics for one deployment object within a single namespace.

Parameters:

Name Type Description
namespace &str The Kubernetes namespace
deployment_object_id Uuid The deployment object to attribute pods to

Returns:

A SubmitDiagnosticResult containing collected diagnostics

Source
pub async fn collect_diagnostics(
&self,
namespace: &str,
deployment_object_id: Uuid,
) -> Result<SubmitDiagnosticResult, Box<dyn std::error::Error + Send + Sync>> {
self.collect_diagnostics_in(&[namespace.to_string()], deployment_object_id)
.await
}

pub async

async fn collect_diagnostics_in(
&self,
namespaces: &[String],
deployment_object_id: Uuid,
) -> Result<SubmitDiagnosticResult, Box<dyn std::error::Error + Send + Sync>>

Collects diagnostics across multiple namespaces and merges the results.

Namespaces are derived from the deployment object’s manifests so diagnostics work for workloads outside default (BROKKR-T-0190).

Pods are attributed to deployment_object_id with the shared PodAttributor strategy rather than a label selector: Brokkr stamps brokkr.io/deployment-object-id as an annotation on the top-level applied object and never injects it into pod templates, so selecting pods by that label matched nothing for controller-managed workloads (BROKKR-T-0299).

Parameters:

Name Type Description
namespaces &[String] The Kubernetes namespaces to search
deployment_object_id Uuid The deployment object to attribute pods to

Returns:

A SubmitDiagnosticResult containing the merged diagnostics

Source
pub async fn collect_diagnostics_in(
&self,
namespaces: &[String],
deployment_object_id: Uuid,
) -> Result<SubmitDiagnosticResult, Box<dyn std::error::Error + Send + Sync>> {
info!(
"Collecting diagnostics for namespaces={:?}, deployment_object={}",
namespaces, deployment_object_id
);
let mut pod_statuses = Vec::new();
let mut events = Vec::new();
let mut log_tails: HashMap<String, String> = HashMap::new();
// One attributor for the whole request so API discovery and
// owner-chain lookups are shared across namespaces.
let mut attributor = PodAttributor::new(self.client.clone());
for namespace in namespaces {
let pods = self
.resolve_pods(&mut attributor, namespace, deployment_object_id)
.await?;
pod_statuses.extend(pods.iter().map(pod_status_of));
events.extend(self.collect_events(namespace).await?);
log_tails.extend(self.collect_log_tails(namespace, &pods).await);
}
Ok(SubmitDiagnosticResult {
pod_statuses: serde_json::to_string(&pod_statuses)?,
events: serde_json::to_string(&events)?,
// With no namespace to search, `{}` would claim "looked, found no
// containers"; `null` correctly says logs were never collected.
log_tails: if namespaces.is_empty() {
None
} else {
Some(serde_json::to_string(&log_tails)?)
},
collected_at: Utc::now(),
})
}