Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 69 additions & 50 deletions receiver/k8sclusterreceiver/internal/container/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,56 +79,51 @@
}
}

rb := mb.NewResourceBuilder()
var containerID string
var imageStr string
for i := range pod.Status.ContainerStatuses {
cs := pod.Status.ContainerStatuses[i]
if cs.Name != c.Name {
continue
}
containerID = cs.ContainerID
imageStr = cs.Image
mb.RecordK8sContainerRestartsDataPoint(ts, int64(cs.RestartCount))
mb.RecordK8sContainerReadyDataPoint(ts, boolToInt64(cs.Ready))
if cs.LastTerminationState.Terminated != nil {
rb.SetK8sContainerStatusLastTerminatedReason(cs.LastTerminationState.Terminated.Reason)
}
switch {
case cs.State.Running != nil:
mb.RecordK8sContainerStatusStateDataPoint(ts, 1, metadata.AttributeK8sContainerStatusStateRunning)
mb.RecordK8sContainerStatusStateDataPoint(ts, 0, metadata.AttributeK8sContainerStatusStateWaiting)
mb.RecordK8sContainerStatusStateDataPoint(ts, 0, metadata.AttributeK8sContainerStatusStateTerminated)
case cs.State.Terminated != nil:
mb.RecordK8sContainerStatusStateDataPoint(ts, 0, metadata.AttributeK8sContainerStatusStateRunning)
mb.RecordK8sContainerStatusStateDataPoint(ts, 0, metadata.AttributeK8sContainerStatusStateWaiting)
mb.RecordK8sContainerStatusStateDataPoint(ts, 1, metadata.AttributeK8sContainerStatusStateTerminated)
case cs.State.Waiting != nil:
mb.RecordK8sContainerStatusStateDataPoint(ts, 0, metadata.AttributeK8sContainerStatusStateRunning)
mb.RecordK8sContainerStatusStateDataPoint(ts, 1, metadata.AttributeK8sContainerStatusStateWaiting)
mb.RecordK8sContainerStatusStateDataPoint(ts, 0, metadata.AttributeK8sContainerStatusStateTerminated)
}

// Record k8s.container.status.reason metric: for each known reason emit 1 for the current one, 0 otherwise.
var reason string
switch {
case cs.State.Terminated != nil:
reason = cs.State.Terminated.Reason
case cs.State.Waiting != nil:
reason = cs.State.Waiting.Reason
default:
reason = ""
}
// Emit in deterministic order for test stability.
for _, attrVal := range allContainerStatusReasons {
val := int64(0)
if reason != "" && reason == attrVal.String() {
val = 1
}
mb.RecordK8sContainerStatusReasonDataPoint(ts, val, attrVal)
}
break
}
rb := mb.NewResourceBuilder()

Check failure on line 82 in receiver/k8sclusterreceiver/internal/container/containers.go

View workflow job for this annotation

GitHub Actions / scoped-tests-matrix (ubuntu-latest)

File is not properly formatted (gci)

Check failure on line 82 in receiver/k8sclusterreceiver/internal/container/containers.go

View workflow job for this annotation

GitHub Actions / lint-matrix (windows, receiver-1)

File is not properly formatted (gci)

Check failure on line 82 in receiver/k8sclusterreceiver/internal/container/containers.go

View workflow job for this annotation

GitHub Actions / lint-matrix (linux, receiver-1)

File is not properly formatted (gci)
var containerID string
var imageStr string
if cs, ok := findContainerStatusForName(pod, c.Name); ok {
containerID = cs.ContainerID
imageStr = cs.Image
mb.RecordK8sContainerRestartsDataPoint(ts, int64(cs.RestartCount))
mb.RecordK8sContainerReadyDataPoint(ts, boolToInt64(cs.Ready))
if cs.LastTerminationState.Terminated != nil {
rb.SetK8sContainerStatusLastTerminatedReason(cs.LastTerminationState.Terminated.Reason)
}
switch {
case cs.State.Running != nil:
mb.RecordK8sContainerStatusStateDataPoint(ts, 1, metadata.AttributeK8sContainerStatusStateRunning)
mb.RecordK8sContainerStatusStateDataPoint(ts, 0, metadata.AttributeK8sContainerStatusStateWaiting)
mb.RecordK8sContainerStatusStateDataPoint(ts, 0, metadata.AttributeK8sContainerStatusStateTerminated)
case cs.State.Terminated != nil:
mb.RecordK8sContainerStatusStateDataPoint(ts, 0, metadata.AttributeK8sContainerStatusStateRunning)
mb.RecordK8sContainerStatusStateDataPoint(ts, 0, metadata.AttributeK8sContainerStatusStateWaiting)
mb.RecordK8sContainerStatusStateDataPoint(ts, 1, metadata.AttributeK8sContainerStatusStateTerminated)
case cs.State.Waiting != nil:
mb.RecordK8sContainerStatusStateDataPoint(ts, 0, metadata.AttributeK8sContainerStatusStateRunning)
mb.RecordK8sContainerStatusStateDataPoint(ts, 1, metadata.AttributeK8sContainerStatusStateWaiting)
mb.RecordK8sContainerStatusStateDataPoint(ts, 0, metadata.AttributeK8sContainerStatusStateTerminated)
}

// Record k8s.container.status.reason metric: for each known reason emit 1 for the current one, 0 otherwise.
var reason string
switch {
case cs.State.Terminated != nil:
reason = cs.State.Terminated.Reason
case cs.State.Waiting != nil:
reason = cs.State.Waiting.Reason
default:
reason = ""
}
// Emit in deterministic order for test stability.
for _, attrVal := range allContainerStatusReasons {
val := int64(0)
if reason != "" && reason == attrVal.String() {
val = 1
}
mb.RecordK8sContainerStatusReasonDataPoint(ts, val, attrVal)
}
}

rb.SetK8sPodUID(string(pod.UID))
rb.SetK8sPodName(pod.Name)
Expand All @@ -146,6 +141,30 @@
mb.EmitForResource(metadata.WithResource(rb.Emit()))
}

// findContainerStatusForName returns the ContainerStatus matching the given name from
// any of container, init container, or ephemeral container statuses.
func findContainerStatusForName(pod *corev1.Pod, name string) (*corev1.ContainerStatus, bool) {
for i := range pod.Status.ContainerStatuses {
cs := &pod.Status.ContainerStatuses[i]
if cs.Name == name {
return cs, true
}
}
for i := range pod.Status.InitContainerStatuses {
cs := &pod.Status.InitContainerStatuses[i]
if cs.Name == name {
return cs, true
}
}
for i := range pod.Status.EphemeralContainerStatuses {
cs := &pod.Status.EphemeralContainerStatuses[i]
if cs.Name == name {
return cs, true
}
}
return nil, false
}

func GetMetadata(pod *corev1.Pod, cs corev1.ContainerStatus, logger *zap.Logger) *metadata.KubernetesMetadata {
mdata := map[string]string{}

Expand Down
70 changes: 70 additions & 0 deletions receiver/k8sclusterreceiver/internal/pod/pods.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,30 @@
LastTerminationState: cs.LastTerminationState,
})
}
for i := range pod.Status.InitContainerStatuses {

Check failure on line 63 in receiver/k8sclusterreceiver/internal/pod/pods.go

View workflow job for this annotation

GitHub Actions / scoped-tests-matrix (ubuntu-latest)

File is not properly formatted (gci)

Check failure on line 63 in receiver/k8sclusterreceiver/internal/pod/pods.go

View workflow job for this annotation

GitHub Actions / lint-matrix (windows, receiver-1)

File is not properly formatted (gci)

Check failure on line 63 in receiver/k8sclusterreceiver/internal/pod/pods.go

View workflow job for this annotation

GitHub Actions / lint-matrix (linux, receiver-1)

File is not properly formatted (gci)
cs := &pod.Status.InitContainerStatuses[i]
newPod.Status.InitContainerStatuses = append(newPod.Status.InitContainerStatuses, corev1.ContainerStatus{
Name: cs.Name,
Image: cs.Image,
ContainerID: cs.ContainerID,
RestartCount: cs.RestartCount,
Ready: cs.Ready,
State: cs.State,
LastTerminationState: cs.LastTerminationState,
})
}
for i := range pod.Status.EphemeralContainerStatuses {
cs := &pod.Status.EphemeralContainerStatuses[i]
newPod.Status.EphemeralContainerStatuses = append(newPod.Status.EphemeralContainerStatuses, corev1.ContainerStatus{
Name: cs.Name,
Image: cs.Image,
ContainerID: cs.ContainerID,
RestartCount: cs.RestartCount,
Ready: cs.Ready,
State: cs.State,
LastTerminationState: cs.LastTerminationState,
})
}
for i := range pod.Spec.Containers {
c := &pod.Spec.Containers[i]
newPod.Spec.Containers = append(newPod.Spec.Containers, corev1.Container{
Expand All @@ -70,6 +94,28 @@
},
})
}
for i := range pod.Spec.InitContainers {
c := &pod.Spec.InitContainers[i]
newPod.Spec.InitContainers = append(newPod.Spec.InitContainers, corev1.Container{
Name: c.Name,
Resources: corev1.ResourceRequirements{
Requests: c.Resources.Requests,
Limits: c.Resources.Limits,
},
})
}
for i := range pod.Spec.EphemeralContainers {
c := &pod.Spec.EphemeralContainers[i]
newPod.Spec.EphemeralContainers = append(newPod.Spec.EphemeralContainers, corev1.EphemeralContainer{
EphemeralContainerCommon: corev1.EphemeralContainerCommon{
Name: c.Name,
Resources: corev1.ResourceRequirements{
Requests: c.Resources.Requests,
Limits: c.Resources.Limits,
},
},
})
}
return newPod
}

Expand All @@ -88,7 +134,21 @@
c := pod.Spec.Containers[i]
container.RecordSpecMetrics(logger, mb, c, pod, ts)
}
for i := range pod.Spec.InitContainers {
c := pod.Spec.InitContainers[i]
container.RecordSpecMetrics(logger, mb, c, pod, ts)
}
for i := range pod.Spec.EphemeralContainers {
ec := pod.Spec.EphemeralContainers[i]
// Convert EphemeralContainer to a minimal Container for metrics (name/resources)
c := corev1.Container{
Name: ec.Name,
Resources: ec.Resources,
}
container.RecordSpecMetrics(logger, mb, c, pod, ts)
}

}

Check failure on line 151 in receiver/k8sclusterreceiver/internal/pod/pods.go

View workflow job for this annotation

GitHub Actions / scoped-tests-matrix (ubuntu-latest)

unnecessary trailing newline (whitespace)

Check failure on line 151 in receiver/k8sclusterreceiver/internal/pod/pods.go

View workflow job for this annotation

GitHub Actions / lint-matrix (windows, receiver-1)

unnecessary trailing newline (whitespace)

Check failure on line 151 in receiver/k8sclusterreceiver/internal/pod/pods.go

View workflow job for this annotation

GitHub Actions / lint-matrix (linux, receiver-1)

unnecessary trailing newline (whitespace)

func reasonToInt(reason string) int32 {
switch reason {
Expand Down Expand Up @@ -277,6 +337,16 @@
md := container.GetMetadata(pod, cs, logger)
km[md.ResourceID] = md
}
for i := range pod.Status.InitContainerStatuses {
cs := pod.Status.InitContainerStatuses[i]
md := container.GetMetadata(pod, cs, logger)
km[md.ResourceID] = md
}
for i := range pod.Status.EphemeralContainerStatuses {
cs := pod.Status.EphemeralContainerStatuses[i]
md := container.GetMetadata(pod, cs, logger)
km[md.ResourceID] = md
}
return km
}

Expand Down
9 changes: 4 additions & 5 deletions receiver/k8sclusterreceiver/receiver.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@
return errors.New("unable to get exporters")
}
exporters := ge.GetExporters()

if err := kr.resourceWatcher.setupMetadataExporters(
exporters[pipeline.SignalMetrics], kr.config.MetadataExporters); err != nil {
return err
Expand Down Expand Up @@ -167,7 +166,7 @@
kr.obsrecv.EndMetricsOp(c, metadata.Type.String(), numPoints, err)
}

// newMetricsReceiver creates the Kubernetes cluster receiver with the given configuration.
// newMetricsReceiver creates the Kubernetes cluster metrics receiver with the given configuration.
func newMetricsReceiver(
ctx context.Context, set receiver.Settings, cfg component.Config, consumer consumer.Metrics,
) (receiver.Metrics, error) {
Expand All @@ -186,7 +185,7 @@
return r, nil
}

// newMetricsReceiver creates the Kubernetes cluster receiver with the given configuration.
// newLogsReceiver creates the Kubernetes cluster logs receiver with the given configuration.
func newLogsReceiver(
ctx context.Context, set receiver.Settings, cfg component.Config, consumer consumer.Logs,
) (receiver.Logs, error) {
Expand All @@ -205,7 +204,7 @@
return r, nil
}

// newMetricsReceiver creates the Kubernetes cluster receiver with the given configuration.
// newReceiver creates the Kubernetes cluster receiver with the given configuration.
func newReceiver(_ context.Context, set receiver.Settings, cfg component.Config) (component.Component, error) {
rCfg := cfg.(*Config)
obsrecv, err := receiverhelper.NewObsReport(
Expand All @@ -227,4 +226,4 @@
config: rCfg,
obsrecv: obsrecv,
}, nil
}
}

Check failure on line 229 in receiver/k8sclusterreceiver/receiver.go

View workflow job for this annotation

GitHub Actions / scoped-tests-matrix (ubuntu-latest)

File is not properly formatted (gci)

Check failure on line 229 in receiver/k8sclusterreceiver/receiver.go

View workflow job for this annotation

GitHub Actions / lint-matrix (windows, receiver-1)

File is not properly formatted (gci)

Check failure on line 229 in receiver/k8sclusterreceiver/receiver.go

View workflow job for this annotation

GitHub Actions / lint-matrix (linux, receiver-1)

File is not properly formatted (gci)
Loading