Skip to content

Commit f7d5c1b

Browse files
authored
[receiver/k8s_cluster] Send entity delete events (#40278)
- Add onDelete handler on the k8s watcher to emit the experimental entity delete events - Add missing otel.entity.type field to the generated delete events
1 parent 40fd06a commit f7d5c1b

File tree

5 files changed

+40
-5
lines changed

5 files changed

+40
-5
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: "enhancement"
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
7+
component: "receiver/k8s_cluster"
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Add onDelete handler to emit the experimental entity delete events
11+
12+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
13+
issues: [40278]
14+
15+
# If your change doesn't affect end users or the exported elements of any package,
16+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
17+
# Optional: The change log or logs in which this entry should be included.
18+
# e.g. '[user]' or '[user, api]'
19+
# Include 'user' if the change is relevant to end users.
20+
# Include 'api' if there is a change to a library API.
21+
# Default: '[user]'
22+
change_logs: [user]

receiver/k8sclusterreceiver/internal/metadata/entities.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ func GetEntityEvents(oldMetadata, newMetadata map[metadataPkg.ResourceID]*Kubern
2121
entityEvent := out.AppendEmpty()
2222
entityEvent.SetTimestamp(timestamp)
2323
entityEvent.ID().PutStr(oldObj.ResourceIDKey, string(oldObj.ResourceID))
24-
entityEvent.SetEntityDelete()
24+
deleteEvent := entityEvent.SetEntityDelete()
25+
deleteEvent.SetEntityType(oldObj.EntityType)
2526
}
2627
}
2728

receiver/k8sclusterreceiver/receiver_test.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -280,11 +280,10 @@ func TestReceiverWithMetadata(t *testing.T) {
280280
}, 10*time.Second, 100*time.Millisecond,
281281
"metadata not collected")
282282

283-
// Must have 3 entity events: once for the add, followed by an update and
284-
// then another update, which unlike metadata calls actually happens since
285-
// even unchanged entities trigger an event.
283+
// Must have 4 entity events: once for the add, followed by an update and
284+
// then another update, and then a delete.
286285
require.Eventually(t, func() bool {
287-
return logsConsumer.LogRecordCount() == 3
286+
return logsConsumer.LogRecordCount() == 4
288287
}, 10*time.Second, 100*time.Millisecond,
289288
"entity events not collected")
290289

receiver/k8sclusterreceiver/watcher.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ func (rw *resourceWatcher) setupInformer(gvk schema.GroupVersionKind, informer c
259259
_, err = informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
260260
AddFunc: rw.onAdd,
261261
UpdateFunc: rw.onUpdate,
262+
DeleteFunc: rw.onDelete,
262263
})
263264
if err != nil {
264265
rw.logger.Error("error adding event handler to informer", zap.Error(err))
@@ -292,6 +293,17 @@ func (rw *resourceWatcher) onUpdate(oldObj, newObj any) {
292293
rw.syncMetadataUpdate(rw.objMetadata(oldObj), rw.objMetadata(newObj))
293294
}
294295

296+
func (rw *resourceWatcher) onDelete(oldObj any) {
297+
rw.waitForInitialInformerSync()
298+
299+
// Sync metadata only if there's at least one destination for it to sent.
300+
if !rw.hasDestination() {
301+
return
302+
}
303+
304+
rw.syncMetadataUpdate(rw.objMetadata(oldObj), map[experimentalmetricmetadata.ResourceID]*metadata.KubernetesMetadata{})
305+
}
306+
295307
// objMetadata returns the metadata for the given object.
296308
func (rw *resourceWatcher) objMetadata(obj any) map[experimentalmetricmetadata.ResourceID]*metadata.KubernetesMetadata {
297309
switch o := obj.(type) {

receiver/k8sclusterreceiver/watcher_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,7 @@ func TestSyncMetadataAndEmitEntityEvents(t *testing.T) {
299299
lr = logsConsumer.AllLogs()[4].ResourceLogs().At(0).ScopeLogs().At(0).LogRecords().At(0)
300300
expected = map[string]any{
301301
"otel.entity.event.type": "entity_delete",
302+
"otel.entity.type": "k8s.pod",
302303
"otel.entity.id": map[string]any{"k8s.pod.uid": "pod0"},
303304
}
304305
assert.Equal(t, expected, lr.Attributes().AsRaw())

0 commit comments

Comments
 (0)