diff --git a/.chloggen/k8seventsreceiver-update-severity-map.yaml b/.chloggen/k8seventsreceiver-update-severity-map.yaml new file mode 100644 index 0000000000000..e5fcaef3a0cbf --- /dev/null +++ b/.chloggen/k8seventsreceiver-update-severity-map.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: receiver/k8s_events + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Allow more event types like Error and Critical which are typically used by applications when creating events. + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [43401] + +# (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: k8seventsreceiver allows event types Error and Critical in addition to the current Normal and Warning event types. + +# 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/k8seventsreceiver/k8s_event_to_logdata.go b/receiver/k8seventsreceiver/k8s_event_to_logdata.go index 2f1ac96bf4685..b1a9baf73e77d 100644 --- a/receiver/k8seventsreceiver/k8s_event_to_logdata.go +++ b/receiver/k8seventsreceiver/k8s_event_to_logdata.go @@ -23,11 +23,13 @@ const ( totalResourceAttributes = 6 ) -// Only two types of events are created as of now. -// For more info: https://docs.openshift.com/container-platform/4.9/rest_api/metadata_apis/event-core-v1.html +// By default k8s event has only two types of events (Normal, Warning), here are we allowing other types as well. +// For more info: https://github.com/kubernetes/api/blob/release-1.34/events/v1/types_swagger_doc_generated.go#L42 var severityMap = map[string]plog.SeverityNumber{ "normal": plog.SeverityNumberInfo, "warning": plog.SeverityNumberWarn, + "error": plog.SeverityNumberError, + "critical": plog.SeverityNumberFatal, } // k8sEventToLogRecord converts Kubernetes event to plog.LogRecordSlice and adds the resource attributes. diff --git a/receiver/k8seventsreceiver/k8s_event_to_logdata_test.go b/receiver/k8seventsreceiver/k8s_event_to_logdata_test.go index d32a89f28df8f..98f369c58320a 100644 --- a/receiver/k8seventsreceiver/k8s_event_to_logdata_test.go +++ b/receiver/k8seventsreceiver/k8s_event_to_logdata_test.go @@ -13,8 +13,50 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8seventsreceiver/internal/metadata" ) +func TestK8sEventToLogDataWithDifferentEventTypes(t *testing.T) { + tests := []struct { + name string + eventType string + expectedLog plog.SeverityNumber + }{ + { + name: "Normal", + eventType: "Normal", + expectedLog: plog.SeverityNumberInfo, + }, + { + name: "Warning", + eventType: "Warning", + expectedLog: plog.SeverityNumberWarn, + }, + { + name: "Error", + eventType: "Error", + expectedLog: plog.SeverityNumberError, + }, + { + name: "Critical", + eventType: "Critical", + expectedLog: plog.SeverityNumberFatal, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + k8sEvent := getEvent(test.eventType) + + ld := k8sEventToLogData(zap.NewNop(), k8sEvent, "latest") + rl := ld.ResourceLogs().At(0) + lr := rl.ScopeLogs().At(0) + logRecord := lr.LogRecords().At(0) + + assert.Equal(t, test.expectedLog, logRecord.SeverityNumber()) + }) + } +} + func TestK8sEventToLogData(t *testing.T) { - k8sEvent := getEvent() + k8sEvent := getEvent("Normal") ld := k8sEventToLogData(zap.NewNop(), k8sEvent, "latest") rl := ld.ResourceLogs().At(0) @@ -32,7 +74,7 @@ func TestK8sEventToLogData(t *testing.T) { } func TestK8sEventToLogDataWithApiAndResourceVersion(t *testing.T) { - k8sEvent := getEvent() + k8sEvent := getEvent("Normal") ld := k8sEventToLogData(zap.NewNop(), k8sEvent, "latest") attrs := ld.ResourceLogs().At(0).Resource().Attributes() @@ -54,8 +96,7 @@ func TestK8sEventToLogDataWithApiAndResourceVersion(t *testing.T) { } func TestUnknownSeverity(t *testing.T) { - k8sEvent := getEvent() - k8sEvent.Type = "Unknown" + k8sEvent := getEvent("Unknown") ld := k8sEventToLogData(zap.NewNop(), k8sEvent, "latest") rl := ld.ResourceLogs().At(0) @@ -66,7 +107,7 @@ func TestUnknownSeverity(t *testing.T) { } func TestScopeNameAndVersion(t *testing.T) { - k8sEvent := getEvent() + k8sEvent := getEvent("Normal") version := "latest" ld := k8sEventToLogData(zap.NewNop(), k8sEvent, version) diff --git a/receiver/k8seventsreceiver/receiver_test.go b/receiver/k8seventsreceiver/receiver_test.go index 79915b82d337f..6654871277a26 100644 --- a/receiver/k8seventsreceiver/receiver_test.go +++ b/receiver/k8seventsreceiver/receiver_test.go @@ -65,7 +65,7 @@ func TestHandleEvent(t *testing.T) { require.NotNil(t, r) recv := r.(*k8seventsReceiver) recv.ctx = t.Context() - k8sEvent := getEvent() + k8sEvent := getEvent("Normal") recv.handleEvent(k8sEvent) assert.Equal(t, 1, sink.LogRecordCount()) @@ -83,7 +83,7 @@ func TestDropEventsOlderThanStartupTime(t *testing.T) { require.NotNil(t, r) recv := r.(*k8seventsReceiver) recv.ctx = t.Context() - k8sEvent := getEvent() + k8sEvent := getEvent("Normal") k8sEvent.FirstTimestamp = v1.Time{Time: time.Now().Add(-time.Hour)} recv.handleEvent(k8sEvent) @@ -91,7 +91,7 @@ func TestDropEventsOlderThanStartupTime(t *testing.T) { } func TestGetEventTimestamp(t *testing.T) { - k8sEvent := getEvent() + k8sEvent := getEvent("Normal") eventTimestamp := getEventTimestamp(k8sEvent) assert.Equal(t, k8sEvent.FirstTimestamp.Time, eventTimestamp) @@ -117,7 +117,7 @@ func TestAllowEvent(t *testing.T) { require.NoError(t, err) require.NotNil(t, r) recv := r.(*k8seventsReceiver) - k8sEvent := getEvent() + k8sEvent := getEvent("Normal") shouldAllowEvent := recv.allowEvent(k8sEvent) assert.True(t, shouldAllowEvent) @@ -158,7 +158,7 @@ func TestReceiverWithLeaderElection(t *testing.T) { // Become leader: start processing events le.InvokeOnLeading() - recv.handleEvent(getEvent()) + recv.handleEvent(getEvent("Normal")) require.Eventually(t, func() bool { return sink.LogRecordCount() == 1 @@ -174,14 +174,14 @@ func TestReceiverWithLeaderElection(t *testing.T) { // regain leadership and inject again le.InvokeOnLeading() - recv.handleEvent(getEvent()) + recv.handleEvent(getEvent("Normal")) require.Eventually(t, func() bool { return sink.LogRecordCount() == 2 }, 5*time.Second, 100*time.Millisecond, "logs not collected after regaining leadership") } -func getEvent() *corev1.Event { +func getEvent(eventType string) *corev1.Event { return &corev1.Event{ InvolvedObject: corev1.ObjectReference{ APIVersion: "v1", @@ -193,7 +193,7 @@ func getEvent() *corev1.Event { Reason: "testing_event_1", Count: 2, FirstTimestamp: v1.Now(), - Type: "Normal", + Type: eventType, Message: "testing event message", ObjectMeta: v1.ObjectMeta{ UID: types.UID("289686f9-a5c0"),