Skip to content

Commit c249bde

Browse files
authored
Merge pull request #449 from sophieliu15/new_api_1
Support k8s.io/api/events/v1 API in Event Exporter.
2 parents 1cec107 + 6172190 commit c249bde

File tree

2 files changed

+157
-4
lines changed

2 files changed

+157
-4
lines changed

event-exporter/sinks/stackdriver/log_entry_factory.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222

2323
"github.com/golang/glog"
2424
sd "google.golang.org/api/logging/v2"
25-
2625
corev1 "k8s.io/api/core/v1"
2726
"k8s.io/apimachinery/pkg/runtime"
2827
"k8s.io/apimachinery/pkg/runtime/serializer/json"
@@ -36,8 +35,6 @@ var (
3635
fieldBlacklist = []string{
3736
// Is unnecessary, because it's demuxed already
3837
"count",
39-
// Timestamp is in the logEntry's metadata
40-
"lastTimestamp",
4138
// Not relevant because of demuxing
4239
"firstTimestamp",
4340
}
@@ -66,10 +63,25 @@ func (f *sdLogEntryFactory) FromEvent(event *corev1.Event) *sd.LogEntry {
6663

6764
resource := f.resourceFactory.resourceFromEvent(event)
6865

66+
var timestamp string
67+
if !event.LastTimestamp.IsZero() {
68+
// The event was emitted using k8s.io/api/core/v1 library.
69+
timestamp = event.LastTimestamp.Format(time.RFC3339Nano)
70+
} else if event.Series != nil && !event.Series.LastObservedTime.IsZero() {
71+
// The event was emitted using k8s.io/api/events/v1 library.
72+
timestamp = event.Series.LastObservedTime.Format(time.RFC3339Nano)
73+
} else if !event.EventTime.IsZero() {
74+
// It is possible that either LastTimestamp or LastObservedTime is not set.
75+
// In this case, EventTime is the next best choice if a log entry timestamp.
76+
timestamp = event.EventTime.Format(time.RFC3339Nano)
77+
} else {
78+
timestamp = f.clock.Now().Format(time.RFC3339Nano)
79+
}
80+
6981
return &sd.LogEntry{
7082
JsonPayload: payload,
7183
Severity: f.detectSeverity(event),
72-
Timestamp: event.LastTimestamp.Format(time.RFC3339Nano),
84+
Timestamp: timestamp,
7385
Resource: resource,
7486
}
7587
}
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
package stackdriver
2+
3+
import (
4+
"testing"
5+
"time"
6+
7+
"github.com/google/go-cmp/cmp"
8+
sd "google.golang.org/api/logging/v2"
9+
corev1 "k8s.io/api/core/v1"
10+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
11+
"k8s.io/apimachinery/pkg/util/clock"
12+
)
13+
14+
func TestFromEvent(t *testing.T) {
15+
newTypesConfig := factoryConfig(newTypes)
16+
monitoredResourceFactory := newMonitoredResourceFactory(newTypesConfig)
17+
involvedObject := corev1.ObjectReference{Kind: node, Name: "test_node_name"}
18+
wantedMonitoredResource := &sd.MonitoredResource{
19+
Type: k8sNode,
20+
Labels: map[string]string{
21+
clusterName: newTypesConfig.clusterName,
22+
location: newTypesConfig.location,
23+
projectID: newTypesConfig.projectID,
24+
nodeName: "test_node_name",
25+
},
26+
}
27+
28+
time1 := time.Now()
29+
time2 := time.Now()
30+
time3 := time.Now()
31+
time4 := time.Now()
32+
lastTimestamp := metav1.NewTime(time1)
33+
lastObservedTime := metav1.NewMicroTime(time2)
34+
eventTime := metav1.NewMicroTime(time3)
35+
36+
tests := []struct {
37+
desc string
38+
event *corev1.Event
39+
wanted *sd.LogEntry
40+
}{
41+
{
42+
desc: "core/v1 event API",
43+
event: &corev1.Event{
44+
Type: "Warning",
45+
InvolvedObject: involvedObject,
46+
LastTimestamp: lastTimestamp,
47+
},
48+
wanted: &sd.LogEntry{
49+
Timestamp: lastTimestamp.Format(time.RFC3339Nano),
50+
Resource: wantedMonitoredResource,
51+
Severity: "WARNING",
52+
},
53+
},
54+
{
55+
desc: "events/v1 event API",
56+
event: &corev1.Event{
57+
Type: "Warning",
58+
InvolvedObject: involvedObject,
59+
Series: &corev1.EventSeries{
60+
Count: 1,
61+
LastObservedTime: lastObservedTime,
62+
},
63+
},
64+
wanted: &sd.LogEntry{
65+
Timestamp: lastObservedTime.Format(time.RFC3339Nano),
66+
Resource: wantedMonitoredResource,
67+
Severity: "WARNING",
68+
},
69+
},
70+
{
71+
desc: "Only EventTime is set",
72+
event: &corev1.Event{
73+
Type: "Warning",
74+
InvolvedObject: involvedObject,
75+
EventTime: eventTime,
76+
},
77+
wanted: &sd.LogEntry{
78+
Timestamp: eventTime.Format(time.RFC3339Nano),
79+
Resource: wantedMonitoredResource,
80+
Severity: "WARNING",
81+
},
82+
},
83+
{
84+
desc: "Timestamp not set",
85+
event: &corev1.Event{
86+
Type: "Warning",
87+
InvolvedObject: involvedObject,
88+
},
89+
wanted: &sd.LogEntry{
90+
Timestamp: time4.Format(time.RFC3339Nano),
91+
Resource: wantedMonitoredResource,
92+
Severity: "WARNING",
93+
},
94+
},
95+
{
96+
desc: "Event type is not set",
97+
event: &corev1.Event{
98+
InvolvedObject: involvedObject,
99+
LastTimestamp: lastTimestamp,
100+
},
101+
wanted: &sd.LogEntry{
102+
Timestamp: lastTimestamp.Format(time.RFC3339Nano),
103+
Resource: wantedMonitoredResource,
104+
Severity: "INFO",
105+
},
106+
},
107+
{
108+
desc: "Event type is not warning",
109+
event: &corev1.Event{
110+
Type: "Normal",
111+
InvolvedObject: involvedObject,
112+
LastTimestamp: lastTimestamp,
113+
},
114+
wanted: &sd.LogEntry{
115+
Timestamp: lastTimestamp.Format(time.RFC3339Nano),
116+
Resource: wantedMonitoredResource,
117+
Severity: "INFO",
118+
},
119+
},
120+
}
121+
122+
for _, test := range tests {
123+
factory := newSdLogEntryFactory(clock.NewFakeClock(time4), monitoredResourceFactory)
124+
got:= factory.FromEvent(test.event)
125+
if diff := compareLogEntries(got, test.wanted); diff != "" {
126+
t.Errorf("Unexpected log entry from event %v, (-want +got): %s", test.event, diff)
127+
}
128+
}
129+
}
130+
131+
func compareLogEntries(got, want *sd.LogEntry) string {
132+
var ignore = map[string]bool{
133+
"JsonPayload": true,
134+
}
135+
cmpIgnoreSomeFields := cmp.FilterPath(
136+
func(p cmp.Path) bool {
137+
return ignore[p.String()]
138+
},
139+
cmp.Ignore())
140+
return cmp.Diff(got, want, cmpIgnoreSomeFields)
141+
}

0 commit comments

Comments
 (0)