-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[receiver/k8sclusterreceiver] Implement conversion from Metadata to t…
…he new entity model (#24396) Resolves #24394 This is part 2 of the work to move to entity events-as-log-records in K8s cluster receiver: #19741 This also adds the notion of entity type to the KubernetesMetadata definition since it is required in the new data model. Overall design document: https://docs.google.com/document/d/1Tg18sIck3Nakxtd3TFFcIjrmRO_0GLMdHXylVqBQmJA/
- Loading branch information
1 parent
806c303
commit 603d3a7
Showing
10 changed files
with
268 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package metadata // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/metadata" | ||
|
||
import ( | ||
metadataPkg "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/experimentalmetricmetadata" | ||
) | ||
|
||
// GetEntityEvents processes metadata updates and returns entity events that describe the metadata changes. | ||
func GetEntityEvents(old, new map[metadataPkg.ResourceID]*KubernetesMetadata) metadataPkg.EntityEventsSlice { | ||
out := metadataPkg.NewEntityEventsSlice() | ||
|
||
for id, oldObj := range old { | ||
if _, ok := new[id]; !ok { | ||
// An object was present, but no longer is. Create a "delete" event. | ||
entityEvent := out.AppendEmpty() | ||
entityEvent.ID().PutStr(oldObj.ResourceIDKey, string(oldObj.ResourceID)) | ||
entityEvent.SetEntityDelete() | ||
} | ||
} | ||
|
||
// All "new" are current objects. Create "state" events. "old" state does not matter. | ||
for _, newObj := range new { | ||
entityEvent := out.AppendEmpty() | ||
entityEvent.ID().PutStr(newObj.ResourceIDKey, string(newObj.ResourceID)) | ||
state := entityEvent.SetEntityState() | ||
state.SetEntityType(newObj.EntityType) | ||
|
||
attrs := state.Attributes() | ||
for k, v := range newObj.Metadata { | ||
attrs.PutStr(k, v) | ||
} | ||
} | ||
|
||
return out | ||
} |
207 changes: 207 additions & 0 deletions
207
receiver/k8sclusterreceiver/internal/metadata/entities_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,207 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package metadata // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/metadata" | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
|
||
metadataPkg "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/experimentalmetricmetadata" | ||
) | ||
|
||
func Test_GetEntityEvents(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
old, new map[metadataPkg.ResourceID]*KubernetesMetadata | ||
events metadataPkg.EntityEventsSlice | ||
}{ | ||
{ | ||
name: "new entity", | ||
new: map[metadataPkg.ResourceID]*KubernetesMetadata{ | ||
"123": { | ||
EntityType: "k8s.pod", | ||
ResourceIDKey: "k8s.pod.uid", | ||
ResourceID: "123", | ||
Metadata: map[string]string{ | ||
"label1": "value1", | ||
}, | ||
}, | ||
}, | ||
events: func() metadataPkg.EntityEventsSlice { | ||
out := metadataPkg.NewEntityEventsSlice() | ||
event := out.AppendEmpty() | ||
_ = event.ID().FromRaw(map[string]any{"k8s.pod.uid": "123"}) | ||
state := event.SetEntityState() | ||
state.SetEntityType("k8s.pod") | ||
_ = state.Attributes().FromRaw(map[string]any{"label1": "value1"}) | ||
return out | ||
}(), | ||
}, | ||
{ | ||
name: "deleted entity", | ||
old: map[metadataPkg.ResourceID]*KubernetesMetadata{ | ||
"123": { | ||
EntityType: "k8s.pod", | ||
ResourceIDKey: "k8s.pod.uid", | ||
ResourceID: "123", | ||
Metadata: map[string]string{ | ||
"label1": "value1", | ||
}, | ||
}, | ||
}, | ||
events: func() metadataPkg.EntityEventsSlice { | ||
out := metadataPkg.NewEntityEventsSlice() | ||
event := out.AppendEmpty() | ||
_ = event.ID().FromRaw(map[string]any{"k8s.pod.uid": "123"}) | ||
event.SetEntityDelete() | ||
return out | ||
}(), | ||
}, | ||
{ | ||
name: "changed entity", | ||
old: map[metadataPkg.ResourceID]*KubernetesMetadata{ | ||
"123": { | ||
EntityType: "k8s.pod", | ||
ResourceIDKey: "k8s.pod.uid", | ||
ResourceID: "123", | ||
Metadata: map[string]string{ | ||
"label1": "value1", | ||
"label2": "value2", | ||
"label3": "value3", | ||
}, | ||
}, | ||
}, | ||
new: map[metadataPkg.ResourceID]*KubernetesMetadata{ | ||
"123": { | ||
EntityType: "k8s.pod", | ||
ResourceIDKey: "k8s.pod.uid", | ||
ResourceID: "123", | ||
Metadata: map[string]string{ | ||
"label1": "value1", | ||
"label2": "foo", | ||
"new": "bar", | ||
}, | ||
}, | ||
}, | ||
events: func() metadataPkg.EntityEventsSlice { | ||
out := metadataPkg.NewEntityEventsSlice() | ||
event := out.AppendEmpty() | ||
_ = event.ID().FromRaw(map[string]any{"k8s.pod.uid": "123"}) | ||
state := event.SetEntityState() | ||
state.SetEntityType("k8s.pod") | ||
_ = state.Attributes().FromRaw(map[string]any{"label1": "value1", "label2": "foo", "new": "bar"}) | ||
return out | ||
}(), | ||
}, | ||
{ | ||
name: "unchanged entity", | ||
old: map[metadataPkg.ResourceID]*KubernetesMetadata{ | ||
"123": { | ||
EntityType: "k8s.pod", | ||
ResourceIDKey: "k8s.pod.uid", | ||
ResourceID: "123", | ||
Metadata: map[string]string{ | ||
"label1": "value1", | ||
"label2": "value2", | ||
"label3": "value3", | ||
}, | ||
}, | ||
}, | ||
new: map[metadataPkg.ResourceID]*KubernetesMetadata{ | ||
"123": { | ||
EntityType: "k8s.pod", | ||
ResourceIDKey: "k8s.pod.uid", | ||
ResourceID: "123", | ||
Metadata: map[string]string{ | ||
"label1": "value1", | ||
"label2": "value2", | ||
"label3": "value3", | ||
}, | ||
}, | ||
}, | ||
events: func() metadataPkg.EntityEventsSlice { | ||
out := metadataPkg.NewEntityEventsSlice() | ||
event := out.AppendEmpty() | ||
_ = event.ID().FromRaw(map[string]any{"k8s.pod.uid": "123"}) | ||
state := event.SetEntityState() | ||
state.SetEntityType("k8s.pod") | ||
_ = state.Attributes().FromRaw( | ||
map[string]any{ | ||
"label1": "value1", "label2": "value2", "label3": "value3", | ||
}, | ||
) | ||
return out | ||
}(), | ||
}, | ||
{ | ||
name: "new and deleted entity", | ||
old: map[metadataPkg.ResourceID]*KubernetesMetadata{ | ||
"123": { | ||
EntityType: "k8s.pod", | ||
ResourceIDKey: "k8s.pod.uid", | ||
ResourceID: "123", | ||
Metadata: map[string]string{ | ||
"label1": "value1", | ||
}, | ||
}, | ||
}, | ||
new: map[metadataPkg.ResourceID]*KubernetesMetadata{ | ||
"234": { | ||
EntityType: "k8s.pod", | ||
ResourceIDKey: "k8s.pod.uid", | ||
ResourceID: "234", | ||
Metadata: map[string]string{ | ||
"label2": "value2", | ||
}, | ||
}, | ||
}, | ||
events: func() metadataPkg.EntityEventsSlice { | ||
out := metadataPkg.NewEntityEventsSlice() | ||
|
||
event := out.AppendEmpty() | ||
_ = event.ID().FromRaw(map[string]any{"k8s.pod.uid": "123"}) | ||
event.SetEntityDelete() | ||
|
||
event = out.AppendEmpty() | ||
_ = event.ID().FromRaw(map[string]any{"k8s.pod.uid": "234"}) | ||
state := event.SetEntityState() | ||
state.SetEntityType("k8s.pod") | ||
_ = state.Attributes().FromRaw(map[string]any{"label2": "value2"}) | ||
return out | ||
}(), | ||
}, | ||
} | ||
for _, test := range tests { | ||
tt := test | ||
t.Run( | ||
tt.name, func(t *testing.T) { | ||
// Make sure test data is correct. | ||
for k, v := range tt.old { | ||
assert.EqualValues(t, k, v.ResourceID) | ||
} | ||
for k, v := range tt.new { | ||
assert.EqualValues(t, k, v.ResourceID) | ||
} | ||
|
||
// Convert and test expected events. | ||
events := GetEntityEvents(tt.old, tt.new) | ||
require.Equal(t, tt.events.Len(), events.Len()) | ||
for i := 0; i < events.Len(); i++ { | ||
actual := events.At(i) | ||
expected := tt.events.At(i) | ||
assert.EqualValues(t, expected.EventType(), actual.EventType()) | ||
assert.EqualValues(t, expected.ID().AsRaw(), actual.ID().AsRaw()) | ||
if expected.EventType() == metadataPkg.EventTypeState { | ||
estate := expected.EntityStateDetails() | ||
astate := actual.EntityStateDetails() | ||
assert.EqualValues(t, estate.EntityType(), astate.EntityType()) | ||
assert.EqualValues(t, estate.Attributes().AsRaw(), astate.Attributes().AsRaw()) | ||
} | ||
} | ||
}, | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.