From 56932bbf4ebd24ad870f3dd5256195f613fb7356 Mon Sep 17 00:00:00 2001 From: Povilas Versockas Date: Thu, 15 Feb 2024 14:21:37 +0200 Subject: [PATCH] [k8sclusterreceiver] add k8s.container.status_last_terminated_reason metric --- .../k8scluster_add-last-terminated-state.yaml | 27 ++ receiver/k8sclusterreceiver/documentation.md | 14 + .../internal/container/containers.go | 3 + .../internal/metadata/generated_config.go | 92 +++---- .../metadata/generated_config_test.go | 178 ++++++------- .../internal/metadata/generated_metrics.go | 239 +++++++++++------- .../metadata/generated_metrics_test.go | 18 ++ .../internal/metadata/testdata/config.yaml | 4 + .../internal/pod/pods_test.go | 1 + .../pod/testdata/expected_evicted.yaml | 12 + .../internal/testutils/objects.go | 5 + receiver/k8sclusterreceiver/metadata.yaml | 12 + 12 files changed, 383 insertions(+), 222 deletions(-) create mode 100755 .chloggen/k8scluster_add-last-terminated-state.yaml diff --git a/.chloggen/k8scluster_add-last-terminated-state.yaml b/.chloggen/k8scluster_add-last-terminated-state.yaml new file mode 100755 index 000000000000..c0235fa4d68b --- /dev/null +++ b/.chloggen/k8scluster_add-last-terminated-state.yaml @@ -0,0 +1,27 @@ +# Use this changelog template to create an entry for release notes. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) +component: "k8sclusterreceiver" + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: "add optional k8s.container.status_last_terminated_reason metric" + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [31282] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: + +# If your change doesn't affect end users or the exported elements of any package, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [user] diff --git a/receiver/k8sclusterreceiver/documentation.md b/receiver/k8sclusterreceiver/documentation.md index 78d0339742a1..23e56c4d7f42 100644 --- a/receiver/k8sclusterreceiver/documentation.md +++ b/receiver/k8sclusterreceiver/documentation.md @@ -396,6 +396,20 @@ metrics: enabled: true ``` +### k8s.container.status_last_terminated_reason + +Last terminated reason of container. The unit is always 1. + +| Unit | Metric Type | Value Type | +| ---- | ----------- | ---------- | +| | Gauge | Int | + +#### Attributes + +| Name | Description | Values | +| ---- | ----------- | ------ | +| reason | the container status terminated reason | Any Str | + ### k8s.node.condition The condition of a particular Node. diff --git a/receiver/k8sclusterreceiver/internal/container/containers.go b/receiver/k8sclusterreceiver/internal/container/containers.go index 9879d9ca71a6..06446a45cdaa 100644 --- a/receiver/k8sclusterreceiver/internal/container/containers.go +++ b/receiver/k8sclusterreceiver/internal/container/containers.go @@ -68,6 +68,9 @@ func RecordSpecMetrics(logger *zap.Logger, mb *imetadata.MetricsBuilder, c corev imageStr = cs.Image mb.RecordK8sContainerRestartsDataPoint(ts, int64(cs.RestartCount)) mb.RecordK8sContainerReadyDataPoint(ts, boolToInt64(cs.Ready)) + if cs.LastTerminationState.Terminated != nil { + mb.RecordK8sContainerStatusLastTerminatedReasonDataPoint(ts, 1, cs.LastTerminationState.Terminated.Reason) + } break } } diff --git a/receiver/k8sclusterreceiver/internal/metadata/generated_config.go b/receiver/k8sclusterreceiver/internal/metadata/generated_config.go index 0ce3c13724b4..6cd31bf98aec 100644 --- a/receiver/k8sclusterreceiver/internal/metadata/generated_config.go +++ b/receiver/k8sclusterreceiver/internal/metadata/generated_config.go @@ -25,50 +25,51 @@ func (ms *MetricConfig) Unmarshal(parser *confmap.Conf) error { // MetricsConfig provides config for k8s_cluster metrics. type MetricsConfig struct { - K8sContainerCPULimit MetricConfig `mapstructure:"k8s.container.cpu_limit"` - K8sContainerCPURequest MetricConfig `mapstructure:"k8s.container.cpu_request"` - K8sContainerEphemeralstorageLimit MetricConfig `mapstructure:"k8s.container.ephemeralstorage_limit"` - K8sContainerEphemeralstorageRequest MetricConfig `mapstructure:"k8s.container.ephemeralstorage_request"` - K8sContainerMemoryLimit MetricConfig `mapstructure:"k8s.container.memory_limit"` - K8sContainerMemoryRequest MetricConfig `mapstructure:"k8s.container.memory_request"` - K8sContainerReady MetricConfig `mapstructure:"k8s.container.ready"` - K8sContainerRestarts MetricConfig `mapstructure:"k8s.container.restarts"` - K8sContainerStorageLimit MetricConfig `mapstructure:"k8s.container.storage_limit"` - K8sContainerStorageRequest MetricConfig `mapstructure:"k8s.container.storage_request"` - K8sCronjobActiveJobs MetricConfig `mapstructure:"k8s.cronjob.active_jobs"` - K8sDaemonsetCurrentScheduledNodes MetricConfig `mapstructure:"k8s.daemonset.current_scheduled_nodes"` - K8sDaemonsetDesiredScheduledNodes MetricConfig `mapstructure:"k8s.daemonset.desired_scheduled_nodes"` - K8sDaemonsetMisscheduledNodes MetricConfig `mapstructure:"k8s.daemonset.misscheduled_nodes"` - K8sDaemonsetReadyNodes MetricConfig `mapstructure:"k8s.daemonset.ready_nodes"` - K8sDeploymentAvailable MetricConfig `mapstructure:"k8s.deployment.available"` - K8sDeploymentDesired MetricConfig `mapstructure:"k8s.deployment.desired"` - K8sHpaCurrentReplicas MetricConfig `mapstructure:"k8s.hpa.current_replicas"` - K8sHpaDesiredReplicas MetricConfig `mapstructure:"k8s.hpa.desired_replicas"` - K8sHpaMaxReplicas MetricConfig `mapstructure:"k8s.hpa.max_replicas"` - K8sHpaMinReplicas MetricConfig `mapstructure:"k8s.hpa.min_replicas"` - K8sJobActivePods MetricConfig `mapstructure:"k8s.job.active_pods"` - K8sJobDesiredSuccessfulPods MetricConfig `mapstructure:"k8s.job.desired_successful_pods"` - K8sJobFailedPods MetricConfig `mapstructure:"k8s.job.failed_pods"` - K8sJobMaxParallelPods MetricConfig `mapstructure:"k8s.job.max_parallel_pods"` - K8sJobSuccessfulPods MetricConfig `mapstructure:"k8s.job.successful_pods"` - K8sNamespacePhase MetricConfig `mapstructure:"k8s.namespace.phase"` - K8sNodeCondition MetricConfig `mapstructure:"k8s.node.condition"` - K8sPodPhase MetricConfig `mapstructure:"k8s.pod.phase"` - K8sPodStatusReason MetricConfig `mapstructure:"k8s.pod.status_reason"` - K8sReplicasetAvailable MetricConfig `mapstructure:"k8s.replicaset.available"` - K8sReplicasetDesired MetricConfig `mapstructure:"k8s.replicaset.desired"` - K8sReplicationControllerAvailable MetricConfig `mapstructure:"k8s.replication_controller.available"` - K8sReplicationControllerDesired MetricConfig `mapstructure:"k8s.replication_controller.desired"` - K8sResourceQuotaHardLimit MetricConfig `mapstructure:"k8s.resource_quota.hard_limit"` - K8sResourceQuotaUsed MetricConfig `mapstructure:"k8s.resource_quota.used"` - K8sStatefulsetCurrentPods MetricConfig `mapstructure:"k8s.statefulset.current_pods"` - K8sStatefulsetDesiredPods MetricConfig `mapstructure:"k8s.statefulset.desired_pods"` - K8sStatefulsetReadyPods MetricConfig `mapstructure:"k8s.statefulset.ready_pods"` - K8sStatefulsetUpdatedPods MetricConfig `mapstructure:"k8s.statefulset.updated_pods"` - OpenshiftAppliedclusterquotaLimit MetricConfig `mapstructure:"openshift.appliedclusterquota.limit"` - OpenshiftAppliedclusterquotaUsed MetricConfig `mapstructure:"openshift.appliedclusterquota.used"` - OpenshiftClusterquotaLimit MetricConfig `mapstructure:"openshift.clusterquota.limit"` - OpenshiftClusterquotaUsed MetricConfig `mapstructure:"openshift.clusterquota.used"` + K8sContainerCPULimit MetricConfig `mapstructure:"k8s.container.cpu_limit"` + K8sContainerCPURequest MetricConfig `mapstructure:"k8s.container.cpu_request"` + K8sContainerEphemeralstorageLimit MetricConfig `mapstructure:"k8s.container.ephemeralstorage_limit"` + K8sContainerEphemeralstorageRequest MetricConfig `mapstructure:"k8s.container.ephemeralstorage_request"` + K8sContainerMemoryLimit MetricConfig `mapstructure:"k8s.container.memory_limit"` + K8sContainerMemoryRequest MetricConfig `mapstructure:"k8s.container.memory_request"` + K8sContainerReady MetricConfig `mapstructure:"k8s.container.ready"` + K8sContainerRestarts MetricConfig `mapstructure:"k8s.container.restarts"` + K8sContainerStatusLastTerminatedReason MetricConfig `mapstructure:"k8s.container.status_last_terminated_reason"` + K8sContainerStorageLimit MetricConfig `mapstructure:"k8s.container.storage_limit"` + K8sContainerStorageRequest MetricConfig `mapstructure:"k8s.container.storage_request"` + K8sCronjobActiveJobs MetricConfig `mapstructure:"k8s.cronjob.active_jobs"` + K8sDaemonsetCurrentScheduledNodes MetricConfig `mapstructure:"k8s.daemonset.current_scheduled_nodes"` + K8sDaemonsetDesiredScheduledNodes MetricConfig `mapstructure:"k8s.daemonset.desired_scheduled_nodes"` + K8sDaemonsetMisscheduledNodes MetricConfig `mapstructure:"k8s.daemonset.misscheduled_nodes"` + K8sDaemonsetReadyNodes MetricConfig `mapstructure:"k8s.daemonset.ready_nodes"` + K8sDeploymentAvailable MetricConfig `mapstructure:"k8s.deployment.available"` + K8sDeploymentDesired MetricConfig `mapstructure:"k8s.deployment.desired"` + K8sHpaCurrentReplicas MetricConfig `mapstructure:"k8s.hpa.current_replicas"` + K8sHpaDesiredReplicas MetricConfig `mapstructure:"k8s.hpa.desired_replicas"` + K8sHpaMaxReplicas MetricConfig `mapstructure:"k8s.hpa.max_replicas"` + K8sHpaMinReplicas MetricConfig `mapstructure:"k8s.hpa.min_replicas"` + K8sJobActivePods MetricConfig `mapstructure:"k8s.job.active_pods"` + K8sJobDesiredSuccessfulPods MetricConfig `mapstructure:"k8s.job.desired_successful_pods"` + K8sJobFailedPods MetricConfig `mapstructure:"k8s.job.failed_pods"` + K8sJobMaxParallelPods MetricConfig `mapstructure:"k8s.job.max_parallel_pods"` + K8sJobSuccessfulPods MetricConfig `mapstructure:"k8s.job.successful_pods"` + K8sNamespacePhase MetricConfig `mapstructure:"k8s.namespace.phase"` + K8sNodeCondition MetricConfig `mapstructure:"k8s.node.condition"` + K8sPodPhase MetricConfig `mapstructure:"k8s.pod.phase"` + K8sPodStatusReason MetricConfig `mapstructure:"k8s.pod.status_reason"` + K8sReplicasetAvailable MetricConfig `mapstructure:"k8s.replicaset.available"` + K8sReplicasetDesired MetricConfig `mapstructure:"k8s.replicaset.desired"` + K8sReplicationControllerAvailable MetricConfig `mapstructure:"k8s.replication_controller.available"` + K8sReplicationControllerDesired MetricConfig `mapstructure:"k8s.replication_controller.desired"` + K8sResourceQuotaHardLimit MetricConfig `mapstructure:"k8s.resource_quota.hard_limit"` + K8sResourceQuotaUsed MetricConfig `mapstructure:"k8s.resource_quota.used"` + K8sStatefulsetCurrentPods MetricConfig `mapstructure:"k8s.statefulset.current_pods"` + K8sStatefulsetDesiredPods MetricConfig `mapstructure:"k8s.statefulset.desired_pods"` + K8sStatefulsetReadyPods MetricConfig `mapstructure:"k8s.statefulset.ready_pods"` + K8sStatefulsetUpdatedPods MetricConfig `mapstructure:"k8s.statefulset.updated_pods"` + OpenshiftAppliedclusterquotaLimit MetricConfig `mapstructure:"openshift.appliedclusterquota.limit"` + OpenshiftAppliedclusterquotaUsed MetricConfig `mapstructure:"openshift.appliedclusterquota.used"` + OpenshiftClusterquotaLimit MetricConfig `mapstructure:"openshift.clusterquota.limit"` + OpenshiftClusterquotaUsed MetricConfig `mapstructure:"openshift.clusterquota.used"` } func DefaultMetricsConfig() MetricsConfig { @@ -97,6 +98,9 @@ func DefaultMetricsConfig() MetricsConfig { K8sContainerRestarts: MetricConfig{ Enabled: true, }, + K8sContainerStatusLastTerminatedReason: MetricConfig{ + Enabled: false, + }, K8sContainerStorageLimit: MetricConfig{ Enabled: true, }, diff --git a/receiver/k8sclusterreceiver/internal/metadata/generated_config_test.go b/receiver/k8sclusterreceiver/internal/metadata/generated_config_test.go index 15e165e2ce75..a8f84745932c 100644 --- a/receiver/k8sclusterreceiver/internal/metadata/generated_config_test.go +++ b/receiver/k8sclusterreceiver/internal/metadata/generated_config_test.go @@ -26,50 +26,51 @@ func TestMetricsBuilderConfig(t *testing.T) { name: "all_set", want: MetricsBuilderConfig{ Metrics: MetricsConfig{ - K8sContainerCPULimit: MetricConfig{Enabled: true}, - K8sContainerCPURequest: MetricConfig{Enabled: true}, - K8sContainerEphemeralstorageLimit: MetricConfig{Enabled: true}, - K8sContainerEphemeralstorageRequest: MetricConfig{Enabled: true}, - K8sContainerMemoryLimit: MetricConfig{Enabled: true}, - K8sContainerMemoryRequest: MetricConfig{Enabled: true}, - K8sContainerReady: MetricConfig{Enabled: true}, - K8sContainerRestarts: MetricConfig{Enabled: true}, - K8sContainerStorageLimit: MetricConfig{Enabled: true}, - K8sContainerStorageRequest: MetricConfig{Enabled: true}, - K8sCronjobActiveJobs: MetricConfig{Enabled: true}, - K8sDaemonsetCurrentScheduledNodes: MetricConfig{Enabled: true}, - K8sDaemonsetDesiredScheduledNodes: MetricConfig{Enabled: true}, - K8sDaemonsetMisscheduledNodes: MetricConfig{Enabled: true}, - K8sDaemonsetReadyNodes: MetricConfig{Enabled: true}, - K8sDeploymentAvailable: MetricConfig{Enabled: true}, - K8sDeploymentDesired: MetricConfig{Enabled: true}, - K8sHpaCurrentReplicas: MetricConfig{Enabled: true}, - K8sHpaDesiredReplicas: MetricConfig{Enabled: true}, - K8sHpaMaxReplicas: MetricConfig{Enabled: true}, - K8sHpaMinReplicas: MetricConfig{Enabled: true}, - K8sJobActivePods: MetricConfig{Enabled: true}, - K8sJobDesiredSuccessfulPods: MetricConfig{Enabled: true}, - K8sJobFailedPods: MetricConfig{Enabled: true}, - K8sJobMaxParallelPods: MetricConfig{Enabled: true}, - K8sJobSuccessfulPods: MetricConfig{Enabled: true}, - K8sNamespacePhase: MetricConfig{Enabled: true}, - K8sNodeCondition: MetricConfig{Enabled: true}, - K8sPodPhase: MetricConfig{Enabled: true}, - K8sPodStatusReason: MetricConfig{Enabled: true}, - K8sReplicasetAvailable: MetricConfig{Enabled: true}, - K8sReplicasetDesired: MetricConfig{Enabled: true}, - K8sReplicationControllerAvailable: MetricConfig{Enabled: true}, - K8sReplicationControllerDesired: MetricConfig{Enabled: true}, - K8sResourceQuotaHardLimit: MetricConfig{Enabled: true}, - K8sResourceQuotaUsed: MetricConfig{Enabled: true}, - K8sStatefulsetCurrentPods: MetricConfig{Enabled: true}, - K8sStatefulsetDesiredPods: MetricConfig{Enabled: true}, - K8sStatefulsetReadyPods: MetricConfig{Enabled: true}, - K8sStatefulsetUpdatedPods: MetricConfig{Enabled: true}, - OpenshiftAppliedclusterquotaLimit: MetricConfig{Enabled: true}, - OpenshiftAppliedclusterquotaUsed: MetricConfig{Enabled: true}, - OpenshiftClusterquotaLimit: MetricConfig{Enabled: true}, - OpenshiftClusterquotaUsed: MetricConfig{Enabled: true}, + K8sContainerCPULimit: MetricConfig{Enabled: true}, + K8sContainerCPURequest: MetricConfig{Enabled: true}, + K8sContainerEphemeralstorageLimit: MetricConfig{Enabled: true}, + K8sContainerEphemeralstorageRequest: MetricConfig{Enabled: true}, + K8sContainerMemoryLimit: MetricConfig{Enabled: true}, + K8sContainerMemoryRequest: MetricConfig{Enabled: true}, + K8sContainerReady: MetricConfig{Enabled: true}, + K8sContainerRestarts: MetricConfig{Enabled: true}, + K8sContainerStatusLastTerminatedReason: MetricConfig{Enabled: true}, + K8sContainerStorageLimit: MetricConfig{Enabled: true}, + K8sContainerStorageRequest: MetricConfig{Enabled: true}, + K8sCronjobActiveJobs: MetricConfig{Enabled: true}, + K8sDaemonsetCurrentScheduledNodes: MetricConfig{Enabled: true}, + K8sDaemonsetDesiredScheduledNodes: MetricConfig{Enabled: true}, + K8sDaemonsetMisscheduledNodes: MetricConfig{Enabled: true}, + K8sDaemonsetReadyNodes: MetricConfig{Enabled: true}, + K8sDeploymentAvailable: MetricConfig{Enabled: true}, + K8sDeploymentDesired: MetricConfig{Enabled: true}, + K8sHpaCurrentReplicas: MetricConfig{Enabled: true}, + K8sHpaDesiredReplicas: MetricConfig{Enabled: true}, + K8sHpaMaxReplicas: MetricConfig{Enabled: true}, + K8sHpaMinReplicas: MetricConfig{Enabled: true}, + K8sJobActivePods: MetricConfig{Enabled: true}, + K8sJobDesiredSuccessfulPods: MetricConfig{Enabled: true}, + K8sJobFailedPods: MetricConfig{Enabled: true}, + K8sJobMaxParallelPods: MetricConfig{Enabled: true}, + K8sJobSuccessfulPods: MetricConfig{Enabled: true}, + K8sNamespacePhase: MetricConfig{Enabled: true}, + K8sNodeCondition: MetricConfig{Enabled: true}, + K8sPodPhase: MetricConfig{Enabled: true}, + K8sPodStatusReason: MetricConfig{Enabled: true}, + K8sReplicasetAvailable: MetricConfig{Enabled: true}, + K8sReplicasetDesired: MetricConfig{Enabled: true}, + K8sReplicationControllerAvailable: MetricConfig{Enabled: true}, + K8sReplicationControllerDesired: MetricConfig{Enabled: true}, + K8sResourceQuotaHardLimit: MetricConfig{Enabled: true}, + K8sResourceQuotaUsed: MetricConfig{Enabled: true}, + K8sStatefulsetCurrentPods: MetricConfig{Enabled: true}, + K8sStatefulsetDesiredPods: MetricConfig{Enabled: true}, + K8sStatefulsetReadyPods: MetricConfig{Enabled: true}, + K8sStatefulsetUpdatedPods: MetricConfig{Enabled: true}, + OpenshiftAppliedclusterquotaLimit: MetricConfig{Enabled: true}, + OpenshiftAppliedclusterquotaUsed: MetricConfig{Enabled: true}, + OpenshiftClusterquotaLimit: MetricConfig{Enabled: true}, + OpenshiftClusterquotaUsed: MetricConfig{Enabled: true}, }, ResourceAttributes: ResourceAttributesConfig{ ContainerID: ResourceAttributeConfig{Enabled: true}, @@ -116,50 +117,51 @@ func TestMetricsBuilderConfig(t *testing.T) { name: "none_set", want: MetricsBuilderConfig{ Metrics: MetricsConfig{ - K8sContainerCPULimit: MetricConfig{Enabled: false}, - K8sContainerCPURequest: MetricConfig{Enabled: false}, - K8sContainerEphemeralstorageLimit: MetricConfig{Enabled: false}, - K8sContainerEphemeralstorageRequest: MetricConfig{Enabled: false}, - K8sContainerMemoryLimit: MetricConfig{Enabled: false}, - K8sContainerMemoryRequest: MetricConfig{Enabled: false}, - K8sContainerReady: MetricConfig{Enabled: false}, - K8sContainerRestarts: MetricConfig{Enabled: false}, - K8sContainerStorageLimit: MetricConfig{Enabled: false}, - K8sContainerStorageRequest: MetricConfig{Enabled: false}, - K8sCronjobActiveJobs: MetricConfig{Enabled: false}, - K8sDaemonsetCurrentScheduledNodes: MetricConfig{Enabled: false}, - K8sDaemonsetDesiredScheduledNodes: MetricConfig{Enabled: false}, - K8sDaemonsetMisscheduledNodes: MetricConfig{Enabled: false}, - K8sDaemonsetReadyNodes: MetricConfig{Enabled: false}, - K8sDeploymentAvailable: MetricConfig{Enabled: false}, - K8sDeploymentDesired: MetricConfig{Enabled: false}, - K8sHpaCurrentReplicas: MetricConfig{Enabled: false}, - K8sHpaDesiredReplicas: MetricConfig{Enabled: false}, - K8sHpaMaxReplicas: MetricConfig{Enabled: false}, - K8sHpaMinReplicas: MetricConfig{Enabled: false}, - K8sJobActivePods: MetricConfig{Enabled: false}, - K8sJobDesiredSuccessfulPods: MetricConfig{Enabled: false}, - K8sJobFailedPods: MetricConfig{Enabled: false}, - K8sJobMaxParallelPods: MetricConfig{Enabled: false}, - K8sJobSuccessfulPods: MetricConfig{Enabled: false}, - K8sNamespacePhase: MetricConfig{Enabled: false}, - K8sNodeCondition: MetricConfig{Enabled: false}, - K8sPodPhase: MetricConfig{Enabled: false}, - K8sPodStatusReason: MetricConfig{Enabled: false}, - K8sReplicasetAvailable: MetricConfig{Enabled: false}, - K8sReplicasetDesired: MetricConfig{Enabled: false}, - K8sReplicationControllerAvailable: MetricConfig{Enabled: false}, - K8sReplicationControllerDesired: MetricConfig{Enabled: false}, - K8sResourceQuotaHardLimit: MetricConfig{Enabled: false}, - K8sResourceQuotaUsed: MetricConfig{Enabled: false}, - K8sStatefulsetCurrentPods: MetricConfig{Enabled: false}, - K8sStatefulsetDesiredPods: MetricConfig{Enabled: false}, - K8sStatefulsetReadyPods: MetricConfig{Enabled: false}, - K8sStatefulsetUpdatedPods: MetricConfig{Enabled: false}, - OpenshiftAppliedclusterquotaLimit: MetricConfig{Enabled: false}, - OpenshiftAppliedclusterquotaUsed: MetricConfig{Enabled: false}, - OpenshiftClusterquotaLimit: MetricConfig{Enabled: false}, - OpenshiftClusterquotaUsed: MetricConfig{Enabled: false}, + K8sContainerCPULimit: MetricConfig{Enabled: false}, + K8sContainerCPURequest: MetricConfig{Enabled: false}, + K8sContainerEphemeralstorageLimit: MetricConfig{Enabled: false}, + K8sContainerEphemeralstorageRequest: MetricConfig{Enabled: false}, + K8sContainerMemoryLimit: MetricConfig{Enabled: false}, + K8sContainerMemoryRequest: MetricConfig{Enabled: false}, + K8sContainerReady: MetricConfig{Enabled: false}, + K8sContainerRestarts: MetricConfig{Enabled: false}, + K8sContainerStatusLastTerminatedReason: MetricConfig{Enabled: false}, + K8sContainerStorageLimit: MetricConfig{Enabled: false}, + K8sContainerStorageRequest: MetricConfig{Enabled: false}, + K8sCronjobActiveJobs: MetricConfig{Enabled: false}, + K8sDaemonsetCurrentScheduledNodes: MetricConfig{Enabled: false}, + K8sDaemonsetDesiredScheduledNodes: MetricConfig{Enabled: false}, + K8sDaemonsetMisscheduledNodes: MetricConfig{Enabled: false}, + K8sDaemonsetReadyNodes: MetricConfig{Enabled: false}, + K8sDeploymentAvailable: MetricConfig{Enabled: false}, + K8sDeploymentDesired: MetricConfig{Enabled: false}, + K8sHpaCurrentReplicas: MetricConfig{Enabled: false}, + K8sHpaDesiredReplicas: MetricConfig{Enabled: false}, + K8sHpaMaxReplicas: MetricConfig{Enabled: false}, + K8sHpaMinReplicas: MetricConfig{Enabled: false}, + K8sJobActivePods: MetricConfig{Enabled: false}, + K8sJobDesiredSuccessfulPods: MetricConfig{Enabled: false}, + K8sJobFailedPods: MetricConfig{Enabled: false}, + K8sJobMaxParallelPods: MetricConfig{Enabled: false}, + K8sJobSuccessfulPods: MetricConfig{Enabled: false}, + K8sNamespacePhase: MetricConfig{Enabled: false}, + K8sNodeCondition: MetricConfig{Enabled: false}, + K8sPodPhase: MetricConfig{Enabled: false}, + K8sPodStatusReason: MetricConfig{Enabled: false}, + K8sReplicasetAvailable: MetricConfig{Enabled: false}, + K8sReplicasetDesired: MetricConfig{Enabled: false}, + K8sReplicationControllerAvailable: MetricConfig{Enabled: false}, + K8sReplicationControllerDesired: MetricConfig{Enabled: false}, + K8sResourceQuotaHardLimit: MetricConfig{Enabled: false}, + K8sResourceQuotaUsed: MetricConfig{Enabled: false}, + K8sStatefulsetCurrentPods: MetricConfig{Enabled: false}, + K8sStatefulsetDesiredPods: MetricConfig{Enabled: false}, + K8sStatefulsetReadyPods: MetricConfig{Enabled: false}, + K8sStatefulsetUpdatedPods: MetricConfig{Enabled: false}, + OpenshiftAppliedclusterquotaLimit: MetricConfig{Enabled: false}, + OpenshiftAppliedclusterquotaUsed: MetricConfig{Enabled: false}, + OpenshiftClusterquotaLimit: MetricConfig{Enabled: false}, + OpenshiftClusterquotaUsed: MetricConfig{Enabled: false}, }, ResourceAttributes: ResourceAttributesConfig{ ContainerID: ResourceAttributeConfig{Enabled: false}, diff --git a/receiver/k8sclusterreceiver/internal/metadata/generated_metrics.go b/receiver/k8sclusterreceiver/internal/metadata/generated_metrics.go index c4a7d7c735fb..d1d4d0882030 100644 --- a/receiver/k8sclusterreceiver/internal/metadata/generated_metrics.go +++ b/receiver/k8sclusterreceiver/internal/metadata/generated_metrics.go @@ -404,6 +404,57 @@ func newMetricK8sContainerRestarts(cfg MetricConfig) metricK8sContainerRestarts return m } +type metricK8sContainerStatusLastTerminatedReason struct { + data pmetric.Metric // data buffer for generated metric. + config MetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills k8s.container.status_last_terminated_reason metric with initial data. +func (m *metricK8sContainerStatusLastTerminatedReason) init() { + m.data.SetName("k8s.container.status_last_terminated_reason") + m.data.SetDescription("Last terminated reason of container. The unit is always 1.") + m.data.SetUnit("") + m.data.SetEmptyGauge() + m.data.Gauge().DataPoints().EnsureCapacity(m.capacity) +} + +func (m *metricK8sContainerStatusLastTerminatedReason) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, reasonAttributeValue string) { + if !m.config.Enabled { + return + } + dp := m.data.Gauge().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntValue(val) + dp.Attributes().PutStr("reason", reasonAttributeValue) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricK8sContainerStatusLastTerminatedReason) updateCapacity() { + if m.data.Gauge().DataPoints().Len() > m.capacity { + m.capacity = m.data.Gauge().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricK8sContainerStatusLastTerminatedReason) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricK8sContainerStatusLastTerminatedReason(cfg MetricConfig) metricK8sContainerStatusLastTerminatedReason { + m := metricK8sContainerStatusLastTerminatedReason{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + type metricK8sContainerStorageLimit struct { data pmetric.Metric // data buffer for generated metric. config MetricConfig // metric config provided by user. @@ -2187,55 +2238,56 @@ func newMetricOpenshiftClusterquotaUsed(cfg MetricConfig) metricOpenshiftCluster // MetricsBuilder provides an interface for scrapers to report metrics while taking care of all the transformations // required to produce metric representation defined in metadata and user config. type MetricsBuilder struct { - config MetricsBuilderConfig // config of the metrics builder. - startTime pcommon.Timestamp // start time that will be applied to all recorded data points. - metricsCapacity int // maximum observed number of metrics per resource. - metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. - buildInfo component.BuildInfo // contains version information. - metricK8sContainerCPULimit metricK8sContainerCPULimit - metricK8sContainerCPURequest metricK8sContainerCPURequest - metricK8sContainerEphemeralstorageLimit metricK8sContainerEphemeralstorageLimit - metricK8sContainerEphemeralstorageRequest metricK8sContainerEphemeralstorageRequest - metricK8sContainerMemoryLimit metricK8sContainerMemoryLimit - metricK8sContainerMemoryRequest metricK8sContainerMemoryRequest - metricK8sContainerReady metricK8sContainerReady - metricK8sContainerRestarts metricK8sContainerRestarts - metricK8sContainerStorageLimit metricK8sContainerStorageLimit - metricK8sContainerStorageRequest metricK8sContainerStorageRequest - metricK8sCronjobActiveJobs metricK8sCronjobActiveJobs - metricK8sDaemonsetCurrentScheduledNodes metricK8sDaemonsetCurrentScheduledNodes - metricK8sDaemonsetDesiredScheduledNodes metricK8sDaemonsetDesiredScheduledNodes - metricK8sDaemonsetMisscheduledNodes metricK8sDaemonsetMisscheduledNodes - metricK8sDaemonsetReadyNodes metricK8sDaemonsetReadyNodes - metricK8sDeploymentAvailable metricK8sDeploymentAvailable - metricK8sDeploymentDesired metricK8sDeploymentDesired - metricK8sHpaCurrentReplicas metricK8sHpaCurrentReplicas - metricK8sHpaDesiredReplicas metricK8sHpaDesiredReplicas - metricK8sHpaMaxReplicas metricK8sHpaMaxReplicas - metricK8sHpaMinReplicas metricK8sHpaMinReplicas - metricK8sJobActivePods metricK8sJobActivePods - metricK8sJobDesiredSuccessfulPods metricK8sJobDesiredSuccessfulPods - metricK8sJobFailedPods metricK8sJobFailedPods - metricK8sJobMaxParallelPods metricK8sJobMaxParallelPods - metricK8sJobSuccessfulPods metricK8sJobSuccessfulPods - metricK8sNamespacePhase metricK8sNamespacePhase - metricK8sNodeCondition metricK8sNodeCondition - metricK8sPodPhase metricK8sPodPhase - metricK8sPodStatusReason metricK8sPodStatusReason - metricK8sReplicasetAvailable metricK8sReplicasetAvailable - metricK8sReplicasetDesired metricK8sReplicasetDesired - metricK8sReplicationControllerAvailable metricK8sReplicationControllerAvailable - metricK8sReplicationControllerDesired metricK8sReplicationControllerDesired - metricK8sResourceQuotaHardLimit metricK8sResourceQuotaHardLimit - metricK8sResourceQuotaUsed metricK8sResourceQuotaUsed - metricK8sStatefulsetCurrentPods metricK8sStatefulsetCurrentPods - metricK8sStatefulsetDesiredPods metricK8sStatefulsetDesiredPods - metricK8sStatefulsetReadyPods metricK8sStatefulsetReadyPods - metricK8sStatefulsetUpdatedPods metricK8sStatefulsetUpdatedPods - metricOpenshiftAppliedclusterquotaLimit metricOpenshiftAppliedclusterquotaLimit - metricOpenshiftAppliedclusterquotaUsed metricOpenshiftAppliedclusterquotaUsed - metricOpenshiftClusterquotaLimit metricOpenshiftClusterquotaLimit - metricOpenshiftClusterquotaUsed metricOpenshiftClusterquotaUsed + config MetricsBuilderConfig // config of the metrics builder. + startTime pcommon.Timestamp // start time that will be applied to all recorded data points. + metricsCapacity int // maximum observed number of metrics per resource. + metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. + buildInfo component.BuildInfo // contains version information. + metricK8sContainerCPULimit metricK8sContainerCPULimit + metricK8sContainerCPURequest metricK8sContainerCPURequest + metricK8sContainerEphemeralstorageLimit metricK8sContainerEphemeralstorageLimit + metricK8sContainerEphemeralstorageRequest metricK8sContainerEphemeralstorageRequest + metricK8sContainerMemoryLimit metricK8sContainerMemoryLimit + metricK8sContainerMemoryRequest metricK8sContainerMemoryRequest + metricK8sContainerReady metricK8sContainerReady + metricK8sContainerRestarts metricK8sContainerRestarts + metricK8sContainerStatusLastTerminatedReason metricK8sContainerStatusLastTerminatedReason + metricK8sContainerStorageLimit metricK8sContainerStorageLimit + metricK8sContainerStorageRequest metricK8sContainerStorageRequest + metricK8sCronjobActiveJobs metricK8sCronjobActiveJobs + metricK8sDaemonsetCurrentScheduledNodes metricK8sDaemonsetCurrentScheduledNodes + metricK8sDaemonsetDesiredScheduledNodes metricK8sDaemonsetDesiredScheduledNodes + metricK8sDaemonsetMisscheduledNodes metricK8sDaemonsetMisscheduledNodes + metricK8sDaemonsetReadyNodes metricK8sDaemonsetReadyNodes + metricK8sDeploymentAvailable metricK8sDeploymentAvailable + metricK8sDeploymentDesired metricK8sDeploymentDesired + metricK8sHpaCurrentReplicas metricK8sHpaCurrentReplicas + metricK8sHpaDesiredReplicas metricK8sHpaDesiredReplicas + metricK8sHpaMaxReplicas metricK8sHpaMaxReplicas + metricK8sHpaMinReplicas metricK8sHpaMinReplicas + metricK8sJobActivePods metricK8sJobActivePods + metricK8sJobDesiredSuccessfulPods metricK8sJobDesiredSuccessfulPods + metricK8sJobFailedPods metricK8sJobFailedPods + metricK8sJobMaxParallelPods metricK8sJobMaxParallelPods + metricK8sJobSuccessfulPods metricK8sJobSuccessfulPods + metricK8sNamespacePhase metricK8sNamespacePhase + metricK8sNodeCondition metricK8sNodeCondition + metricK8sPodPhase metricK8sPodPhase + metricK8sPodStatusReason metricK8sPodStatusReason + metricK8sReplicasetAvailable metricK8sReplicasetAvailable + metricK8sReplicasetDesired metricK8sReplicasetDesired + metricK8sReplicationControllerAvailable metricK8sReplicationControllerAvailable + metricK8sReplicationControllerDesired metricK8sReplicationControllerDesired + metricK8sResourceQuotaHardLimit metricK8sResourceQuotaHardLimit + metricK8sResourceQuotaUsed metricK8sResourceQuotaUsed + metricK8sStatefulsetCurrentPods metricK8sStatefulsetCurrentPods + metricK8sStatefulsetDesiredPods metricK8sStatefulsetDesiredPods + metricK8sStatefulsetReadyPods metricK8sStatefulsetReadyPods + metricK8sStatefulsetUpdatedPods metricK8sStatefulsetUpdatedPods + metricOpenshiftAppliedclusterquotaLimit metricOpenshiftAppliedclusterquotaLimit + metricOpenshiftAppliedclusterquotaUsed metricOpenshiftAppliedclusterquotaUsed + metricOpenshiftClusterquotaLimit metricOpenshiftClusterquotaLimit + metricOpenshiftClusterquotaUsed metricOpenshiftClusterquotaUsed } // metricBuilderOption applies changes to default metrics builder. @@ -2260,47 +2312,48 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting metricK8sContainerCPULimit: newMetricK8sContainerCPULimit(mbc.Metrics.K8sContainerCPULimit), metricK8sContainerCPURequest: newMetricK8sContainerCPURequest(mbc.Metrics.K8sContainerCPURequest), metricK8sContainerEphemeralstorageLimit: newMetricK8sContainerEphemeralstorageLimit(mbc.Metrics.K8sContainerEphemeralstorageLimit), - metricK8sContainerEphemeralstorageRequest: newMetricK8sContainerEphemeralstorageRequest(mbc.Metrics.K8sContainerEphemeralstorageRequest), - metricK8sContainerMemoryLimit: newMetricK8sContainerMemoryLimit(mbc.Metrics.K8sContainerMemoryLimit), - metricK8sContainerMemoryRequest: newMetricK8sContainerMemoryRequest(mbc.Metrics.K8sContainerMemoryRequest), - metricK8sContainerReady: newMetricK8sContainerReady(mbc.Metrics.K8sContainerReady), - metricK8sContainerRestarts: newMetricK8sContainerRestarts(mbc.Metrics.K8sContainerRestarts), - metricK8sContainerStorageLimit: newMetricK8sContainerStorageLimit(mbc.Metrics.K8sContainerStorageLimit), - metricK8sContainerStorageRequest: newMetricK8sContainerStorageRequest(mbc.Metrics.K8sContainerStorageRequest), - metricK8sCronjobActiveJobs: newMetricK8sCronjobActiveJobs(mbc.Metrics.K8sCronjobActiveJobs), - metricK8sDaemonsetCurrentScheduledNodes: newMetricK8sDaemonsetCurrentScheduledNodes(mbc.Metrics.K8sDaemonsetCurrentScheduledNodes), - metricK8sDaemonsetDesiredScheduledNodes: newMetricK8sDaemonsetDesiredScheduledNodes(mbc.Metrics.K8sDaemonsetDesiredScheduledNodes), - metricK8sDaemonsetMisscheduledNodes: newMetricK8sDaemonsetMisscheduledNodes(mbc.Metrics.K8sDaemonsetMisscheduledNodes), - metricK8sDaemonsetReadyNodes: newMetricK8sDaemonsetReadyNodes(mbc.Metrics.K8sDaemonsetReadyNodes), - metricK8sDeploymentAvailable: newMetricK8sDeploymentAvailable(mbc.Metrics.K8sDeploymentAvailable), - metricK8sDeploymentDesired: newMetricK8sDeploymentDesired(mbc.Metrics.K8sDeploymentDesired), - metricK8sHpaCurrentReplicas: newMetricK8sHpaCurrentReplicas(mbc.Metrics.K8sHpaCurrentReplicas), - metricK8sHpaDesiredReplicas: newMetricK8sHpaDesiredReplicas(mbc.Metrics.K8sHpaDesiredReplicas), - metricK8sHpaMaxReplicas: newMetricK8sHpaMaxReplicas(mbc.Metrics.K8sHpaMaxReplicas), - metricK8sHpaMinReplicas: newMetricK8sHpaMinReplicas(mbc.Metrics.K8sHpaMinReplicas), - metricK8sJobActivePods: newMetricK8sJobActivePods(mbc.Metrics.K8sJobActivePods), - metricK8sJobDesiredSuccessfulPods: newMetricK8sJobDesiredSuccessfulPods(mbc.Metrics.K8sJobDesiredSuccessfulPods), - metricK8sJobFailedPods: newMetricK8sJobFailedPods(mbc.Metrics.K8sJobFailedPods), - metricK8sJobMaxParallelPods: newMetricK8sJobMaxParallelPods(mbc.Metrics.K8sJobMaxParallelPods), - metricK8sJobSuccessfulPods: newMetricK8sJobSuccessfulPods(mbc.Metrics.K8sJobSuccessfulPods), - metricK8sNamespacePhase: newMetricK8sNamespacePhase(mbc.Metrics.K8sNamespacePhase), - metricK8sNodeCondition: newMetricK8sNodeCondition(mbc.Metrics.K8sNodeCondition), - metricK8sPodPhase: newMetricK8sPodPhase(mbc.Metrics.K8sPodPhase), - metricK8sPodStatusReason: newMetricK8sPodStatusReason(mbc.Metrics.K8sPodStatusReason), - metricK8sReplicasetAvailable: newMetricK8sReplicasetAvailable(mbc.Metrics.K8sReplicasetAvailable), - metricK8sReplicasetDesired: newMetricK8sReplicasetDesired(mbc.Metrics.K8sReplicasetDesired), - metricK8sReplicationControllerAvailable: newMetricK8sReplicationControllerAvailable(mbc.Metrics.K8sReplicationControllerAvailable), - metricK8sReplicationControllerDesired: newMetricK8sReplicationControllerDesired(mbc.Metrics.K8sReplicationControllerDesired), - metricK8sResourceQuotaHardLimit: newMetricK8sResourceQuotaHardLimit(mbc.Metrics.K8sResourceQuotaHardLimit), - metricK8sResourceQuotaUsed: newMetricK8sResourceQuotaUsed(mbc.Metrics.K8sResourceQuotaUsed), - metricK8sStatefulsetCurrentPods: newMetricK8sStatefulsetCurrentPods(mbc.Metrics.K8sStatefulsetCurrentPods), - metricK8sStatefulsetDesiredPods: newMetricK8sStatefulsetDesiredPods(mbc.Metrics.K8sStatefulsetDesiredPods), - metricK8sStatefulsetReadyPods: newMetricK8sStatefulsetReadyPods(mbc.Metrics.K8sStatefulsetReadyPods), - metricK8sStatefulsetUpdatedPods: newMetricK8sStatefulsetUpdatedPods(mbc.Metrics.K8sStatefulsetUpdatedPods), - metricOpenshiftAppliedclusterquotaLimit: newMetricOpenshiftAppliedclusterquotaLimit(mbc.Metrics.OpenshiftAppliedclusterquotaLimit), - metricOpenshiftAppliedclusterquotaUsed: newMetricOpenshiftAppliedclusterquotaUsed(mbc.Metrics.OpenshiftAppliedclusterquotaUsed), - metricOpenshiftClusterquotaLimit: newMetricOpenshiftClusterquotaLimit(mbc.Metrics.OpenshiftClusterquotaLimit), - metricOpenshiftClusterquotaUsed: newMetricOpenshiftClusterquotaUsed(mbc.Metrics.OpenshiftClusterquotaUsed), + metricK8sContainerEphemeralstorageRequest: newMetricK8sContainerEphemeralstorageRequest(mbc.Metrics.K8sContainerEphemeralstorageRequest), + metricK8sContainerMemoryLimit: newMetricK8sContainerMemoryLimit(mbc.Metrics.K8sContainerMemoryLimit), + metricK8sContainerMemoryRequest: newMetricK8sContainerMemoryRequest(mbc.Metrics.K8sContainerMemoryRequest), + metricK8sContainerReady: newMetricK8sContainerReady(mbc.Metrics.K8sContainerReady), + metricK8sContainerRestarts: newMetricK8sContainerRestarts(mbc.Metrics.K8sContainerRestarts), + metricK8sContainerStatusLastTerminatedReason: newMetricK8sContainerStatusLastTerminatedReason(mbc.Metrics.K8sContainerStatusLastTerminatedReason), + metricK8sContainerStorageLimit: newMetricK8sContainerStorageLimit(mbc.Metrics.K8sContainerStorageLimit), + metricK8sContainerStorageRequest: newMetricK8sContainerStorageRequest(mbc.Metrics.K8sContainerStorageRequest), + metricK8sCronjobActiveJobs: newMetricK8sCronjobActiveJobs(mbc.Metrics.K8sCronjobActiveJobs), + metricK8sDaemonsetCurrentScheduledNodes: newMetricK8sDaemonsetCurrentScheduledNodes(mbc.Metrics.K8sDaemonsetCurrentScheduledNodes), + metricK8sDaemonsetDesiredScheduledNodes: newMetricK8sDaemonsetDesiredScheduledNodes(mbc.Metrics.K8sDaemonsetDesiredScheduledNodes), + metricK8sDaemonsetMisscheduledNodes: newMetricK8sDaemonsetMisscheduledNodes(mbc.Metrics.K8sDaemonsetMisscheduledNodes), + metricK8sDaemonsetReadyNodes: newMetricK8sDaemonsetReadyNodes(mbc.Metrics.K8sDaemonsetReadyNodes), + metricK8sDeploymentAvailable: newMetricK8sDeploymentAvailable(mbc.Metrics.K8sDeploymentAvailable), + metricK8sDeploymentDesired: newMetricK8sDeploymentDesired(mbc.Metrics.K8sDeploymentDesired), + metricK8sHpaCurrentReplicas: newMetricK8sHpaCurrentReplicas(mbc.Metrics.K8sHpaCurrentReplicas), + metricK8sHpaDesiredReplicas: newMetricK8sHpaDesiredReplicas(mbc.Metrics.K8sHpaDesiredReplicas), + metricK8sHpaMaxReplicas: newMetricK8sHpaMaxReplicas(mbc.Metrics.K8sHpaMaxReplicas), + metricK8sHpaMinReplicas: newMetricK8sHpaMinReplicas(mbc.Metrics.K8sHpaMinReplicas), + metricK8sJobActivePods: newMetricK8sJobActivePods(mbc.Metrics.K8sJobActivePods), + metricK8sJobDesiredSuccessfulPods: newMetricK8sJobDesiredSuccessfulPods(mbc.Metrics.K8sJobDesiredSuccessfulPods), + metricK8sJobFailedPods: newMetricK8sJobFailedPods(mbc.Metrics.K8sJobFailedPods), + metricK8sJobMaxParallelPods: newMetricK8sJobMaxParallelPods(mbc.Metrics.K8sJobMaxParallelPods), + metricK8sJobSuccessfulPods: newMetricK8sJobSuccessfulPods(mbc.Metrics.K8sJobSuccessfulPods), + metricK8sNamespacePhase: newMetricK8sNamespacePhase(mbc.Metrics.K8sNamespacePhase), + metricK8sNodeCondition: newMetricK8sNodeCondition(mbc.Metrics.K8sNodeCondition), + metricK8sPodPhase: newMetricK8sPodPhase(mbc.Metrics.K8sPodPhase), + metricK8sPodStatusReason: newMetricK8sPodStatusReason(mbc.Metrics.K8sPodStatusReason), + metricK8sReplicasetAvailable: newMetricK8sReplicasetAvailable(mbc.Metrics.K8sReplicasetAvailable), + metricK8sReplicasetDesired: newMetricK8sReplicasetDesired(mbc.Metrics.K8sReplicasetDesired), + metricK8sReplicationControllerAvailable: newMetricK8sReplicationControllerAvailable(mbc.Metrics.K8sReplicationControllerAvailable), + metricK8sReplicationControllerDesired: newMetricK8sReplicationControllerDesired(mbc.Metrics.K8sReplicationControllerDesired), + metricK8sResourceQuotaHardLimit: newMetricK8sResourceQuotaHardLimit(mbc.Metrics.K8sResourceQuotaHardLimit), + metricK8sResourceQuotaUsed: newMetricK8sResourceQuotaUsed(mbc.Metrics.K8sResourceQuotaUsed), + metricK8sStatefulsetCurrentPods: newMetricK8sStatefulsetCurrentPods(mbc.Metrics.K8sStatefulsetCurrentPods), + metricK8sStatefulsetDesiredPods: newMetricK8sStatefulsetDesiredPods(mbc.Metrics.K8sStatefulsetDesiredPods), + metricK8sStatefulsetReadyPods: newMetricK8sStatefulsetReadyPods(mbc.Metrics.K8sStatefulsetReadyPods), + metricK8sStatefulsetUpdatedPods: newMetricK8sStatefulsetUpdatedPods(mbc.Metrics.K8sStatefulsetUpdatedPods), + metricOpenshiftAppliedclusterquotaLimit: newMetricOpenshiftAppliedclusterquotaLimit(mbc.Metrics.OpenshiftAppliedclusterquotaLimit), + metricOpenshiftAppliedclusterquotaUsed: newMetricOpenshiftAppliedclusterquotaUsed(mbc.Metrics.OpenshiftAppliedclusterquotaUsed), + metricOpenshiftClusterquotaLimit: newMetricOpenshiftClusterquotaLimit(mbc.Metrics.OpenshiftClusterquotaLimit), + metricOpenshiftClusterquotaUsed: newMetricOpenshiftClusterquotaUsed(mbc.Metrics.OpenshiftClusterquotaUsed), } for _, op := range options { op(mb) @@ -2371,6 +2424,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricK8sContainerMemoryRequest.emit(ils.Metrics()) mb.metricK8sContainerReady.emit(ils.Metrics()) mb.metricK8sContainerRestarts.emit(ils.Metrics()) + mb.metricK8sContainerStatusLastTerminatedReason.emit(ils.Metrics()) mb.metricK8sContainerStorageLimit.emit(ils.Metrics()) mb.metricK8sContainerStorageRequest.emit(ils.Metrics()) mb.metricK8sCronjobActiveJobs.emit(ils.Metrics()) @@ -2467,6 +2521,11 @@ func (mb *MetricsBuilder) RecordK8sContainerRestartsDataPoint(ts pcommon.Timesta mb.metricK8sContainerRestarts.recordDataPoint(mb.startTime, ts, val) } +// RecordK8sContainerStatusLastTerminatedReasonDataPoint adds a data point to k8s.container.status_last_terminated_reason metric. +func (mb *MetricsBuilder) RecordK8sContainerStatusLastTerminatedReasonDataPoint(ts pcommon.Timestamp, val int64, reasonAttributeValue string) { + mb.metricK8sContainerStatusLastTerminatedReason.recordDataPoint(mb.startTime, ts, val, reasonAttributeValue) +} + // RecordK8sContainerStorageLimitDataPoint adds a data point to k8s.container.storage_limit metric. func (mb *MetricsBuilder) RecordK8sContainerStorageLimitDataPoint(ts pcommon.Timestamp, val int64) { mb.metricK8sContainerStorageLimit.recordDataPoint(mb.startTime, ts, val) diff --git a/receiver/k8sclusterreceiver/internal/metadata/generated_metrics_test.go b/receiver/k8sclusterreceiver/internal/metadata/generated_metrics_test.go index 18b67c686dbd..d68a02afc851 100644 --- a/receiver/k8sclusterreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/k8sclusterreceiver/internal/metadata/generated_metrics_test.go @@ -91,6 +91,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordK8sContainerRestartsDataPoint(ts, 1) + allMetricsCount++ + mb.RecordK8sContainerStatusLastTerminatedReasonDataPoint(ts, 1, "reason-val") + defaultMetricsCount++ allMetricsCount++ mb.RecordK8sContainerStorageLimitDataPoint(ts, 1) @@ -389,6 +392,21 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, ts, dp.Timestamp()) assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) assert.Equal(t, int64(1), dp.IntValue()) + case "k8s.container.status_last_terminated_reason": + assert.False(t, validatedMetrics["k8s.container.status_last_terminated_reason"], "Found a duplicate in the metrics slice: k8s.container.status_last_terminated_reason") + validatedMetrics["k8s.container.status_last_terminated_reason"] = true + assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) + assert.Equal(t, "Last terminated reason of container. The unit is always 1.", ms.At(i).Description()) + assert.Equal(t, "", ms.At(i).Unit()) + dp := ms.At(i).Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + assert.Equal(t, int64(1), dp.IntValue()) + attrVal, ok := dp.Attributes().Get("reason") + assert.True(t, ok) + assert.EqualValues(t, "reason-val", attrVal.Str()) case "k8s.container.storage_limit": assert.False(t, validatedMetrics["k8s.container.storage_limit"], "Found a duplicate in the metrics slice: k8s.container.storage_limit") validatedMetrics["k8s.container.storage_limit"] = true diff --git a/receiver/k8sclusterreceiver/internal/metadata/testdata/config.yaml b/receiver/k8sclusterreceiver/internal/metadata/testdata/config.yaml index bd8704d966e3..2f2d96eb61fe 100644 --- a/receiver/k8sclusterreceiver/internal/metadata/testdata/config.yaml +++ b/receiver/k8sclusterreceiver/internal/metadata/testdata/config.yaml @@ -17,6 +17,8 @@ all_set: enabled: true k8s.container.restarts: enabled: true + k8s.container.status_last_terminated_reason: + enabled: true k8s.container.storage_limit: enabled: true k8s.container.storage_request: @@ -182,6 +184,8 @@ none_set: enabled: false k8s.container.restarts: enabled: false + k8s.container.status_last_terminated_reason: + enabled: false k8s.container.storage_limit: enabled: false k8s.container.storage_request: diff --git a/receiver/k8sclusterreceiver/internal/pod/pods_test.go b/receiver/k8sclusterreceiver/internal/pod/pods_test.go index e9ec03ab0ef1..7894f0439d95 100644 --- a/receiver/k8sclusterreceiver/internal/pod/pods_test.go +++ b/receiver/k8sclusterreceiver/internal/pod/pods_test.go @@ -68,6 +68,7 @@ func TestPodStatusReasonAndContainerMetricsReportCPUMetrics(t *testing.T) { mbc := metadata.DefaultMetricsBuilderConfig() mbc.Metrics.K8sPodStatusReason.Enabled = true + mbc.Metrics.K8sContainerStatusLastTerminatedReason.Enabled = true mbc.ResourceAttributes.K8sPodQosClass.Enabled = true ts := pcommon.Timestamp(time.Now().UnixNano()) mb := metadata.NewMetricsBuilder(mbc, receivertest.NewNopCreateSettings()) diff --git a/receiver/k8sclusterreceiver/internal/pod/testdata/expected_evicted.yaml b/receiver/k8sclusterreceiver/internal/pod/testdata/expected_evicted.yaml index 2da3f591fcd7..f8c71816bd9e 100644 --- a/receiver/k8sclusterreceiver/internal/pod/testdata/expected_evicted.yaml +++ b/receiver/k8sclusterreceiver/internal/pod/testdata/expected_evicted.yaml @@ -31,6 +31,7 @@ resourceMetrics: - asInt: "1" name: k8s.pod.status_reason unit: "" + scope: name: otelcol/k8sclusterreceiver version: latest @@ -87,6 +88,17 @@ resourceMetrics: - asDouble: 20 name: k8s.container.cpu_limit unit: "{cpu}" + - description: "Last terminated reason of container. The unit is always 1." + gauge: + dataPoints: + - asInt: "1" + attributes: + - key: reason + value: + stringValue: Evicted + name: k8s.container.status_last_terminated_reason + unit: "" + scope: name: otelcol/k8sclusterreceiver version: latest diff --git a/receiver/k8sclusterreceiver/internal/testutils/objects.go b/receiver/k8sclusterreceiver/internal/testutils/objects.go index 84bd3983bd24..e7fbf67680ba 100644 --- a/receiver/k8sclusterreceiver/internal/testutils/objects.go +++ b/receiver/k8sclusterreceiver/internal/testutils/objects.go @@ -280,6 +280,11 @@ func NewEvictedTerminatedPodStatusWithContainer(containerName, containerID strin State: corev1.ContainerState{ Terminated: &corev1.ContainerStateTerminated{}, }, + LastTerminationState: corev1.ContainerState{ + Terminated: &corev1.ContainerStateTerminated{ + Reason: "Evicted", + }, + }, }, }, } diff --git a/receiver/k8sclusterreceiver/metadata.yaml b/receiver/k8sclusterreceiver/metadata.yaml index 70fe006ff7c6..163a27bc8f83 100644 --- a/receiver/k8sclusterreceiver/metadata.yaml +++ b/receiver/k8sclusterreceiver/metadata.yaml @@ -212,6 +212,10 @@ attributes: description: "the name of Kubernetes Node condition. Example: Ready, Memory, PID, DiskPressure" type: string enabled: true + reason: + description: "the container status terminated reason" + type: string + enabled: true metrics: k8s.container.cpu_request: @@ -274,6 +278,14 @@ metrics: unit: "" gauge: value_type: int + k8s.container.status_last_terminated_reason: + enabled: false + description: Last terminated reason of container. The unit is always 1. + unit: "" + attributes: + - reason + gauge: + value_type: int k8s.pod.phase: enabled: true