Skip to content

Commit dba3f27

Browse files
committed
add interval to experimental entity events
1 parent 91dce71 commit dba3f27

File tree

8 files changed

+63
-4
lines changed

8 files changed

+63
-4
lines changed

.chloggen/entity-interval.yaml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
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: hostmetricsreceiver
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: "add reporting interval to entity event"
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: [34240]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext:
19+
20+
# If your change doesn't affect end users or the exported elements of any package,
21+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
22+
# Optional: The change log or logs in which this entry should be included.
23+
# e.g. '[user]' or '[user, api]'
24+
# Include 'user' if the change is relevant to end users.
25+
# Include 'api' if there is a change to a library API.
26+
# Default: '[user]'
27+
change_logs: [user]

pkg/experimentalmetricmetadata/entity_events.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
package experimentalmetricmetadata // import "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/experimentalmetricmetadata"
55

66
import (
7+
"time"
8+
79
"go.opentelemetry.io/collector/pdata/pcommon"
810
"go.opentelemetry.io/collector/pdata/plog"
911
)
@@ -18,6 +20,7 @@ const (
1820

1921
semconvOtelEntityID = "otel.entity.id"
2022
semconvOtelEntityType = "otel.entity.type"
23+
semconvOtelEntityInterval = "otel.entity.interval"
2124
semconvOtelEntityAttributes = "otel.entity.attributes"
2225

2326
semconvOtelEntityEventAsScope = "otel.entity.event_as_log"
@@ -173,6 +176,21 @@ func (s EntityStateDetails) SetEntityType(t string) {
173176
s.orig.Attributes().PutStr(semconvOtelEntityType, t)
174177
}
175178

179+
// SetInterval sets the reporting period
180+
// i.e. how frequently the information about this entity is reported via EntityState events even if the entity does not change.
181+
func (s EntityStateDetails) SetInterval(t time.Duration) {
182+
s.orig.Attributes().PutInt(semconvOtelEntityInterval, t.Milliseconds())
183+
}
184+
185+
// Interval returns the reporting period
186+
func (s EntityStateDetails) Interval() time.Duration {
187+
t, ok := s.orig.Attributes().Get(semconvOtelEntityInterval)
188+
if !ok {
189+
return 0
190+
}
191+
return time.Duration(t.Int()) * time.Millisecond
192+
}
193+
176194
// EntityDeleteDetails represents the details of an EntityDelete event.
177195
type EntityDeleteDetails struct {
178196
orig plog.LogRecord

pkg/experimentalmetricmetadata/entity_events_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ func Test_Entity_State(t *testing.T) {
1919
event.ID().PutStr("k8s.pod.uid", "123")
2020
state := event.SetEntityState()
2121
state.SetEntityType("k8s.pod")
22+
state.SetInterval(1 * time.Hour)
2223
state.Attributes().PutStr("label1", "value1")
2324

2425
actual := slice.At(0)
@@ -34,6 +35,8 @@ func Test_Entity_State(t *testing.T) {
3435
assert.Equal(t, "value1", v.Str())
3536

3637
assert.Equal(t, "k8s.pod", actual.EntityStateDetails().EntityType())
38+
39+
assert.Equal(t, 1*time.Hour, actual.EntityStateDetails().Interval())
3740
}
3841

3942
func Test_Entity_Delete(t *testing.T) {

receiver/hostmetricsreceiver/receiver.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ func (hmr *hostEntitiesReceiver) sendEntityEvent(ctx context.Context) {
6666
state := entityEvent.SetEntityState()
6767
state.SetEntityType(entityType)
6868

69+
if hmr.cfg.MetadataCollectionInterval != 0 {
70+
state.SetInterval(hmr.cfg.MetadataCollectionInterval)
71+
}
72+
6973
logs := out.ConvertAndMoveToLogs()
7074

7175
err := hmr.nextLogs.ConsumeLogs(ctx, logs)

receiver/k8sclusterreceiver/internal/metadata/entities.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44
package metadata // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/metadata"
55

66
import (
7+
"time"
8+
79
"go.opentelemetry.io/collector/pdata/pcommon"
810

911
metadataPkg "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/experimentalmetricmetadata"
1012
)
1113

1214
// GetEntityEvents processes metadata updates and returns entity events that describe the metadata changes.
13-
func GetEntityEvents(oldMetadata, newMetadata map[metadataPkg.ResourceID]*KubernetesMetadata, timestamp pcommon.Timestamp) metadataPkg.EntityEventsSlice {
15+
func GetEntityEvents(oldMetadata, newMetadata map[metadataPkg.ResourceID]*KubernetesMetadata, timestamp pcommon.Timestamp, reportingInterval time.Duration) metadataPkg.EntityEventsSlice {
1416
out := metadataPkg.NewEntityEventsSlice()
1517

1618
for id, oldObj := range oldMetadata {
@@ -30,6 +32,9 @@ func GetEntityEvents(oldMetadata, newMetadata map[metadataPkg.ResourceID]*Kubern
3032
entityEvent.ID().PutStr(newObj.ResourceIDKey, string(newObj.ResourceID))
3133
state := entityEvent.SetEntityState()
3234
state.SetEntityType(newObj.EntityType)
35+
if reportingInterval != 0 {
36+
state.SetInterval(reportingInterval)
37+
}
3338

3439
attrs := state.Attributes()
3540
for k, v := range newObj.Metadata {

receiver/k8sclusterreceiver/internal/metadata/entities_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ func Test_GetEntityEvents(t *testing.T) {
190190

191191
// Convert and test expected events.
192192
timestamp := pcommon.NewTimestampFromTime(time.Now())
193-
events := GetEntityEvents(tt.old, tt.new, timestamp)
193+
events := GetEntityEvents(tt.old, tt.new, timestamp, 1*time.Hour)
194194
require.Equal(t, tt.events.Len(), events.Len())
195195
for i := 0; i < events.Len(); i++ {
196196
actual := events.At(i)
@@ -202,6 +202,7 @@ func Test_GetEntityEvents(t *testing.T) {
202202
estate := expected.EntityStateDetails()
203203
astate := actual.EntityStateDetails()
204204
assert.EqualValues(t, estate.EntityType(), astate.EntityType())
205+
assert.EqualValues(t, 1*time.Hour, astate.Interval())
205206
assert.EqualValues(t, estate.Attributes().AsRaw(), astate.Attributes().AsRaw())
206207
}
207208
}

receiver/k8sclusterreceiver/watcher.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ func (rw *resourceWatcher) syncMetadataUpdate(oldMetadata, newMetadata map[exper
366366

367367
if rw.entityLogConsumer != nil {
368368
// Represent metadata update as entity events.
369-
entityEvents := metadata.GetEntityEvents(oldMetadata, newMetadata, timestamp)
369+
entityEvents := metadata.GetEntityEvents(oldMetadata, newMetadata, timestamp, rw.config.MetadataCollectionInterval)
370370

371371
// Convert entity events to log representation.
372372
logs := entityEvents.ConvertAndMoveToLogs()

receiver/k8sclusterreceiver/watcher_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ func TestSyncMetadataAndEmitEntityEvents(t *testing.T) {
229229
origPod := pods[0]
230230
updatedPod := getUpdatedPod(origPod)
231231

232-
rw := newResourceWatcher(receivertest.NewNopSettings(), &Config{}, metadata.NewStore())
232+
rw := newResourceWatcher(receivertest.NewNopSettings(), &Config{MetadataCollectionInterval: 2 * time.Hour}, metadata.NewStore())
233233
rw.entityLogConsumer = logsConsumer
234234

235235
step1 := time.Now()
@@ -266,6 +266,7 @@ func TestSyncMetadataAndEmitEntityEvents(t *testing.T) {
266266
lr := logsConsumer.AllLogs()[0].ResourceLogs().At(0).ScopeLogs().At(0).LogRecords().At(0)
267267
expected := map[string]any{
268268
"otel.entity.event.type": "entity_state",
269+
"otel.entity.interval": int64(7200000), // 2h in milliseconds
269270
"otel.entity.type": "k8s.pod",
270271
"otel.entity.id": map[string]any{"k8s.pod.uid": "pod0"},
271272
"otel.entity.attributes": map[string]any{"pod.creation_timestamp": "0001-01-01T00:00:00Z"},

0 commit comments

Comments
 (0)