Skip to content

Commit

Permalink
[receiver/k8s_cluster] Switch k8s.deployment metrics to use pdata. (o…
Browse files Browse the repository at this point in the history
  • Loading branch information
atoulme authored Jun 16, 2023
1 parent 0ae07ba commit 195ef43
Show file tree
Hide file tree
Showing 16 changed files with 823 additions and 49 deletions.
11 changes: 11 additions & 0 deletions .chloggen/switchk8sdeployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# 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: Switch k8s.deployment metrics to use pdata.

# One or more tracking issues related to the change
issues: [23416]
18 changes: 18 additions & 0 deletions pkg/pdatatest/pmetrictest/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,24 @@ func sortResourceMetricsSlice(rms pmetric.ResourceMetricsSlice) {
})
}

func IgnoreScopeVersion() CompareMetricsOption {
return compareMetricsOptionFunc(func(expected, actual pmetric.Metrics) {
maskScopeVersion(expected)
maskScopeVersion(actual)
})
}

func maskScopeVersion(metrics pmetric.Metrics) {
rms := metrics.ResourceMetrics()
for i := 0; i < rms.Len(); i++ {
rm := rms.At(i)
for j := 0; j < rm.ScopeMetrics().Len(); j++ {
sm := rm.ScopeMetrics().At(j)
sm.Scope().SetVersion("")
}
}
}

// IgnoreScopeMetricsOrder is a CompareMetricsOption that ignores the order of instrumentation scope traces/metrics/logs.
func IgnoreScopeMetricsOrder() CompareMetricsOption {
return compareMetricsOptionFunc(func(expected, actual pmetric.Metrics) {
Expand Down
1 change: 1 addition & 0 deletions receiver/k8sclusterreceiver/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ func TestE2E(t *testing.T) {
pmetrictest.ChangeResourceAttributeValue("k8s.namespace.uid", replaceWithStar),
pmetrictest.ChangeResourceAttributeValue("k8s.daemonset.uid", replaceWithStar),
pmetrictest.ChangeResourceAttributeValue("container.image.name", containerImageShorten),
pmetrictest.IgnoreScopeVersion(),
pmetrictest.IgnoreResourceMetricsOrder(),
pmetrictest.IgnoreMetricsOrder(),
pmetrictest.IgnoreScopeMetricsOrder(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ func (dc *DataCollector) SyncMetrics(obj interface{}) {
case *corev1.ResourceQuota:
md = resourcequota.GetMetrics(dc.settings, o)
case *appsv1.Deployment:
md = ocsToMetrics(deployment.GetMetrics(o))
md = deployment.GetMetrics(dc.settings, o)
case *appsv1.ReplicaSet:
md = ocsToMetrics(replicaset.GetMetrics(o))
case *appsv1.DaemonSet:
Expand Down
41 changes: 12 additions & 29 deletions receiver/k8sclusterreceiver/internal/deployment/deployments.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,26 @@
package deployment // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/deployment"

import (
agentmetricspb "github.com/census-instrumentation/opencensus-proto/gen-go/agent/metrics/v1"
resourcepb "github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1"
"time"

"go.opentelemetry.io/collector/pdata/pcommon"
"go.opentelemetry.io/collector/pdata/pmetric"
"go.opentelemetry.io/collector/receiver"
conventions "go.opentelemetry.io/collector/semconv/v1.6.1"
appsv1 "k8s.io/api/apps/v1"

"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/experimentalmetricmetadata"
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/constants"
imetadata "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/deployment/internal/metadata"
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/metadata"
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/replica"
)

func GetMetrics(dep *appsv1.Deployment) []*agentmetricspb.ExportMetricsServiceRequest {
if dep.Spec.Replicas == nil {
return nil
}

return []*agentmetricspb.ExportMetricsServiceRequest{
{
Resource: getResource(dep),
Metrics: replica.GetMetrics(
"deployment",
*dep.Spec.Replicas,
dep.Status.AvailableReplicas,
),
},
}
}

func getResource(dep *appsv1.Deployment) *resourcepb.Resource {
return &resourcepb.Resource{
Type: constants.K8sType,
Labels: map[string]string{
conventions.AttributeK8SDeploymentUID: string(dep.UID),
conventions.AttributeK8SDeploymentName: dep.Name,
conventions.AttributeK8SNamespaceName: dep.Namespace,
},
}
func GetMetrics(set receiver.CreateSettings, dep *appsv1.Deployment) pmetric.Metrics {
mb := imetadata.NewMetricsBuilder(imetadata.DefaultMetricsBuilderConfig(), set)
ts := pcommon.NewTimestampFromTime(time.Now())
mb.RecordK8sDeploymentDesiredDataPoint(ts, int64(*dep.Spec.Replicas))
mb.RecordK8sDeploymentAvailableDataPoint(ts, int64(dep.Status.AvailableReplicas))
return mb.Emit(imetadata.WithK8sDeploymentName(dep.Name), imetadata.WithK8sDeploymentUID(string(dep.UID)), imetadata.WithK8sNamespaceName(dep.Namespace), imetadata.WithOpencensusResourcetype("k8s"))
}

func GetMetadata(dep *appsv1.Deployment) map[experimentalmetricmetadata.ResourceID]*metadata.KubernetesMetadata {
Expand Down
57 changes: 41 additions & 16 deletions receiver/k8sclusterreceiver/internal/deployment/deployments_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,60 @@
package deployment

import (
"path/filepath"
"testing"

metricspb "github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.opentelemetry.io/collector/pdata/pmetric"
"go.opentelemetry.io/collector/receiver/receivertest"

"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/constants"
"github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal/golden"
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest/pmetrictest"
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/testutils"
)

func TestDeploymentMetrics(t *testing.T) {
dep := testutils.NewDeployment("1")

actualResourceMetrics := GetMetrics(dep)
m := GetMetrics(receivertest.NewNopCreateSettings(), dep)

require.Equal(t, 1, len(actualResourceMetrics))
require.Equal(t, 2, len(actualResourceMetrics[0].Metrics))
require.Equal(t, 1, m.ResourceMetrics().Len())
require.Equal(t, 2, m.MetricCount())

rm := actualResourceMetrics[0]
testutils.AssertResource(t, rm.Resource, constants.K8sType,
map[string]string{
"k8s.deployment.uid": "test-deployment-1-uid",
"k8s.deployment.name": "test-deployment-1",
"k8s.namespace.name": "test-namespace",
rm := m.ResourceMetrics().At(0)
assert.Equal(t,
map[string]interface{}{
"k8s.deployment.uid": "test-deployment-1-uid",
"k8s.deployment.name": "test-deployment-1",
"k8s.namespace.name": "test-namespace",
"opencensus.resourcetype": "k8s",
},
rm.Resource().Attributes().AsRaw(),
)
require.Equal(t, 1, rm.ScopeMetrics().Len())
sms := rm.ScopeMetrics().At(0)
require.Equal(t, 2, sms.Metrics().Len())
sms.Metrics().Sort(func(a, b pmetric.Metric) bool {
return a.Name() < b.Name()
})
testutils.AssertMetricInt(t, sms.Metrics().At(0), "k8s.deployment.available", pmetric.MetricTypeGauge, int64(3))
testutils.AssertMetricInt(t, sms.Metrics().At(1), "k8s.deployment.desired", pmetric.MetricTypeGauge, int64(10))
}

testutils.AssertMetricsInt(t, rm.Metrics[0], "k8s.deployment.desired",
metricspb.MetricDescriptor_GAUGE_INT64, 10)

testutils.AssertMetricsInt(t, rm.Metrics[1], "k8s.deployment.available",
metricspb.MetricDescriptor_GAUGE_INT64, 3)
func TestGoldenFile(t *testing.T) {
dep := testutils.NewDeployment("1")
m := GetMetrics(receivertest.NewNopCreateSettings(), dep)
expectedFile := filepath.Join("testdata", "expected.yaml")
expected, err := golden.ReadMetrics(expectedFile)
require.NoError(t, err)
require.NoError(t, pmetrictest.CompareMetrics(expected, m,
pmetrictest.IgnoreTimestamp(),
pmetrictest.IgnoreStartTimestamp(),
pmetrictest.IgnoreResourceMetricsOrder(),
pmetrictest.IgnoreMetricsOrder(),
pmetrictest.IgnoreScopeMetricsOrder(),
pmetrictest.IgnoreMetricDataPointsOrder(),
),
)
}
6 changes: 6 additions & 0 deletions receiver/k8sclusterreceiver/internal/deployment/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

//go:generate mdatagen metadata.yaml

package deployment // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/deployment"
38 changes: 38 additions & 0 deletions receiver/k8sclusterreceiver/internal/deployment/documentation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[comment]: <> (Code generated by mdatagen. DO NOT EDIT.)

# k8s/deployment

## Default Metrics

The following metrics are emitted by default. Each of them can be disabled by applying the following configuration:

```yaml
metrics:
<metric_name>:
enabled: false
```
### k8s.deployment.available
Total number of available pods (ready for at least minReadySeconds) targeted by this deployment
| Unit | Metric Type | Value Type |
| ---- | ----------- | ---------- |
| 1 | Gauge | Int |
### k8s.deployment.desired
Number of desired pods in this deployment
| Unit | Metric Type | Value Type |
| ---- | ----------- | ---------- |
| 1 | Gauge | Int |
## Resource Attributes
| Name | Description | Values | Enabled |
| ---- | ----------- | ------ | ------- |
| k8s.deployment.name | The name of the Deployment. | Any Str | true |
| k8s.deployment.uid | The UID of the Deployment. | Any Str | true |
| k8s.namespace.name | The name of the namespace that the pod is running in. | Any Str | true |
| opencensus.resourcetype | The OpenCensus resource type. | Any Str | true |

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 195ef43

Please sign in to comment.