diff --git a/pkg/metrics/events.go b/pkg/metrics/events.go new file mode 100644 index 0000000000..f2d47ab86f --- /dev/null +++ b/pkg/metrics/events.go @@ -0,0 +1,77 @@ +package metrics + +import ( + "sync" + "time" + + "github.com/sirupsen/logrus" +) + +const ( + EventsPluginName = "events" +) + +type EventLevel string + +const ( + EventLevelInfo EventLevel = "Info" + EventLevelWarning EventLevel = "Warning" + EventLevelError EventLevel = "Error" +) + +type Event struct { + Level EventLevel `json:"level"` + Source string `json:"source"` + Locator EventLocator `json:"locator"` + Message EventMessage `json:"message"` + From time.Time `json:"from"` + To time.Time `json:"to"` + Timestamp time.Time `json:"timestamp"` +} + +type EventLocator struct { + Type string `json:"type"` + Name string `json:"name"` + Container *string `json:"container,omitempty"` + Keys map[string]any `json:"keys,omitempty"` +} + +type EventMessage struct { + Reason string `json:"reason"` + Cause string `json:"cause"` + HumanMessage string `json:"humanMessage"` + Annotations map[string]any `json:"annotations,omitempty"` +} + +func (e *Event) SetTimestamp(t time.Time) { + e.Timestamp = t +} + +func NewEvent(level EventLevel, locator EventLocator, message EventMessage, source string, from, to time.Time) *Event { + return &Event{Level: level, Source: source, From: from, To: to, Locator: locator, Message: message} +} + +type eventsPlugin struct { + mu sync.Mutex + logger *logrus.Entry + events []MetricsEvent +} + +func newEventsPlugin(logger *logrus.Entry) *eventsPlugin { + return &eventsPlugin{logger: logger.WithField("plugin", EventsPluginName)} +} + +func (p *eventsPlugin) Name() string { return EventsPluginName } + +func (p *eventsPlugin) Record(ev MetricsEvent) { + if _, ok := ev.(*Event); !ok { + return + } + p.mu.Lock() + p.events = append(p.events, ev) + p.mu.Unlock() +} + +func (p *eventsPlugin) Events() []MetricsEvent { + return p.events +} diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go index 23e82eca76..efcdd3234c 100644 --- a/pkg/metrics/metrics.go +++ b/pkg/metrics/metrics.go @@ -38,6 +38,7 @@ type MetricsAgent struct { client ctrlruntimeclient.Client insightsPlugin *insightsPlugin + eventsPlugin *eventsPlugin buildPlugin *buildPlugin nodesPlugin *nodesMetricsPlugin leasePlugin *leasesPlugin @@ -68,6 +69,7 @@ func NewMetricsAgent(ctx context.Context, clusterConfig *rest.Config) (*MetricsA logger: logger, client: client, insightsPlugin: newInsightsPlugin(logger), + eventsPlugin: newEventsPlugin(logger), buildPlugin: newBuildPlugin(ctx, logger, client), nodesPlugin: newNodesMetricsPlugin(ctx, logger, client, metricsClient, nodesCh), leasePlugin: newLeasesPlugin(logger), @@ -99,6 +101,7 @@ func (ma *MetricsAgent) Run() { } // Record the event to all plugins ma.insightsPlugin.Record(ev) + ma.eventsPlugin.Record(ev) ma.buildPlugin.Record(ev) ma.nodesPlugin.Record(ev) ma.leasePlugin.Record(ev) @@ -132,13 +135,15 @@ func (ma *MetricsAgent) Stop() { // flush writes the accumulated events to a JSON file in the artifacts directory. func (ma *MetricsAgent) flush() { - output := make(map[string]any, 6) - output[ma.insightsPlugin.Name()] = ma.insightsPlugin.Events() - output[ma.buildPlugin.Name()] = ma.buildPlugin.Events() - output[ma.nodesPlugin.Name()] = ma.nodesPlugin.Events() - output[ma.leasePlugin.Name()] = ma.leasePlugin.Events() - output[ma.imagesPlugin.Name()] = ma.imagesPlugin.Events() - output[ma.podPlugin.Name()] = ma.podPlugin.Events() + output := map[string]any{ + ma.insightsPlugin.Name(): ma.insightsPlugin.Events(), + ma.eventsPlugin.Name(): ma.eventsPlugin.Events(), + ma.buildPlugin.Name(): ma.buildPlugin.Events(), + ma.nodesPlugin.Name(): ma.nodesPlugin.Events(), + ma.leasePlugin.Name(): ma.leasePlugin.Events(), + ma.imagesPlugin.Name(): ma.imagesPlugin.Events(), + ma.podPlugin.Name(): ma.podPlugin.Events(), + } data, err := json.MarshalIndent(output, "", " ") if err != nil {