diff --git a/CHANGELOG.md b/CHANGELOG.md index a5182671a2..2bb89f90f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## main / (unreleased) +* [CHANGE] eventrecorder: The output data format now uses the new `events/v2` schema. This is a breaking change: alert labels, alert annotations, group labels, silence annotations, and muted-alert labels are JSON maps, and protobuf consumers must use the new schema. + ## 0.34.0 / 2026-08-16 * [CHANGE] notify: The `reason` label on `alertmanager_notifications_failed_total` now distinguishes `authError` (HTTP 401/403) and `rateLimited` (HTTP 429) from the generic `clientError`. Dashboards/alerts matching `reason="clientError"` for these codes must be updated. #5332 diff --git a/app/app.go b/app/app.go index cb1c4c6790..68382fb01f 100644 --- a/app/app.go +++ b/app/app.go @@ -39,7 +39,6 @@ import ( "github.com/prometheus/alertmanager/config" "github.com/prometheus/alertmanager/dispatch" "github.com/prometheus/alertmanager/eventrecorder" - "github.com/prometheus/alertmanager/eventrecorder/eventrecorderpb" "github.com/prometheus/alertmanager/httpserver" "github.com/prometheus/alertmanager/marker" "github.com/prometheus/alertmanager/nflog" @@ -265,23 +264,12 @@ func (a *App) setup() error { a.onStop("event recorder", eventRec.Close) recordCtx := eventrecorder.WithEventRecording(context.Background()) - eventRec.RecordEvent(recordCtx, func() *eventrecorderpb.EventData { - return &eventrecorderpb.EventData{ - EventType: &eventrecorderpb.EventData_AlertmanagerStartupEvent{ - AlertmanagerStartupEvent: &eventrecorderpb.AlertmanagerStartupEvent{ - Version: version.Version, - BuildContext: version.BuildContext(), - }, - }, - } + eventRec.RecordEvent(recordCtx, func() eventrecorder.EventData { + return eventrecorder.NewAlertmanagerStartupEvent(version.Version, version.BuildContext()) }) a.onStop("shutdown event", func() error { - eventRec.RecordEvent(recordCtx, func() *eventrecorderpb.EventData { - return &eventrecorderpb.EventData{ - EventType: &eventrecorderpb.EventData_AlertmanagerShutdownEvent{ - AlertmanagerShutdownEvent: &eventrecorderpb.AlertmanagerShutdownEvent{}, - }, - } + eventRec.RecordEvent(recordCtx, func() eventrecorder.EventData { + return eventrecorder.NewAlertmanagerShutdownEvent() }) return nil }) diff --git a/buf.yaml b/buf.yaml index 225e01263f..1fb8793125 100644 --- a/buf.yaml +++ b/buf.yaml @@ -3,11 +3,11 @@ version: v2 modules: - path: cluster/clusterpb name: prometheus/alertmanager/cluster - - path: eventrecorder/eventrecorderpb - name: prometheus/alertmanager/eventrecorder - path: nflog/nflogpb name: prometheus/alertmanager/nflog - path: proto/api name: prometheus/alertmanager/api + - path: proto/eventrecorder + name: prometheus/alertmanager/eventrecorder - path: silence/silencepb name: prometheus/alertmanager/silence diff --git a/dispatch/dispatch.go b/dispatch/dispatch.go index 47e45151d7..2e3da19970 100644 --- a/dispatch/dispatch.go +++ b/dispatch/dispatch.go @@ -34,7 +34,6 @@ import ( "github.com/prometheus/alertmanager/alert" "github.com/prometheus/alertmanager/eventrecorder" - "github.com/prometheus/alertmanager/eventrecorder/eventrecorderpb" "github.com/prometheus/alertmanager/marker" "github.com/prometheus/alertmanager/notify" "github.com/prometheus/alertmanager/pkg/labels" @@ -890,7 +889,7 @@ func (ag *aggrGroup) insert(ctx context.Context, alert *alert.Alert) bool { span.RecordError(err) ag.logger.Error(message, "err", err) } else { - ag.recorder.RecordEvent(ctx, func() *eventrecorderpb.EventData { + ag.recorder.RecordEvent(ctx, func() eventrecorder.EventData { return notify.NewAlertGroupedEvent(ag.alertGroupInfo(), alert) }) // The alert set changed; the alert is already visible via ag.alerts. @@ -965,21 +964,17 @@ func (ag *aggrGroup) recordResolvedEvents(resolved types.AlertSlice) { if len(resolved) == 0 { return } - groupInfo := ag.alertGroupInfo() for _, a := range resolved { - ag.recorder.RecordEvent(ag.ctx, func() *eventrecorderpb.EventData { - return notify.NewAlertResolvedEvent(groupInfo, a) + ag.recorder.RecordEvent(ag.ctx, func() eventrecorder.EventData { + return notify.NewAlertResolvedEvent(ag.alertGroupInfo(), a) }) } } -func (ag *aggrGroup) alertGroupInfo() *eventrecorderpb.AlertGroupInfo { - return &eventrecorderpb.AlertGroupInfo{ - GroupKey: ag.GroupKey(), - GroupLabels: eventrecorder.LabelSetAsProto(ag.labels), - GroupId: notify.Key(ag.GroupKey()).Hash(), - ReceiverName: ag.opts.Receiver, - } +func (ag *aggrGroup) alertGroupInfo() eventrecorder.AlertGroup { + return eventrecorder.NewAlertGroup( + ag.GroupKey(), ag.labels, notify.Key(ag.GroupKey()).Hash(), ag.opts.Receiver, nil, "", + ) } type nilLimits struct{} diff --git a/docs/configuration.md b/docs/configuration.md index 92cf0e04d8..eec8781b57 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -2175,6 +2175,12 @@ stdout_outputs: [ - ... ] ``` +Every output uses the schema in `proto/eventrecorder/events/v2/events.proto`. +Alert labels, alert annotations, group labels, silence annotations, and +muted-alert labels are encoded as maps. Protobuf consumers must use the Go +package `github.com/prometheus/alertmanager/eventrecorder/events/v2` or bindings +generated from that schema. + #### `` Writes each event as a single JSON line to a file. The file is reopened @@ -2234,7 +2240,10 @@ url: For example, [Cloudflare Pipelines streams](https://developers.cloudflare.com/pipelines/streams/writing-to-streams/) accept JSON arrays through their HTTP ingestion endpoints and can be configured -as a batched webhook output: +as a batched webhook output. Because the event timestamp field is named +`@timestamp`, quote it when referencing it from the pipeline SQL. A complete +fan-out example is available under +[`doc/examples/cloudflare-pipelines`](https://github.com/prometheus/alertmanager/blob/main/doc/examples/cloudflare-pipelines/README.md). ```yaml event_recorder: @@ -2277,7 +2286,7 @@ topic: # On-the-wire encoding for each record value: "json" (protojson) or # "protobuf" (binary proto). JSON is the default for symmetry with the # file and webhook outputs; consumers that already use the -# eventrecorder.proto schema may prefer protobuf for compactness. +# selected event recorder protobuf schema may prefer protobuf for compactness. [ format: <"json" | "protobuf"> | default = "json" ] # Producer acknowledgement level. "leader" matches the franz-go default diff --git a/eventrecorder/eventrecorderpb/eventrecorder.pb.go b/eventrecorder/eventrecorderpb/eventrecorder.pb.go deleted file mode 100644 index 3926cfb61f..0000000000 --- a/eventrecorder/eventrecorderpb/eventrecorder.pb.go +++ /dev/null @@ -1,2106 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.36.12 -// protoc (unknown) -// source: eventrecorder.proto - -package eventrecorderpb - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - durationpb "google.golang.org/protobuf/types/known/durationpb" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" - reflect "reflect" - sync "sync" - unsafe "unsafe" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// NotifyReason describes why a notification was sent for an aggregation -// group. -type NotifyReason int32 - -const ( - // Default / unknown reason. - NotifyReason_NOTIFY_REASON_UNSPECIFIED NotifyReason = 0 - // The group has never been notified before and contains at least one - // firing alert. - NotifyReason_NOTIFY_REASON_FIRST_NOTIFICATION NotifyReason = 1 - // New firing alerts have been added to the group since the last - // notification. - NotifyReason_NOTIFY_REASON_NEW_ALERTS_IN_GROUP NotifyReason = 2 - // Some alerts in the group have resolved since the last notification. - NotifyReason_NOTIFY_REASON_NEW_RESOLVED_ALERTS NotifyReason = 3 - // All alerts in the group have resolved. - NotifyReason_NOTIFY_REASON_ALL_ALERTS_RESOLVED NotifyReason = 4 - // The configured repeat interval has elapsed since the last - // notification. - NotifyReason_NOTIFY_REASON_REPEAT_INTERVAL_ELAPSED NotifyReason = 5 -) - -// Enum value maps for NotifyReason. -var ( - NotifyReason_name = map[int32]string{ - 0: "NOTIFY_REASON_UNSPECIFIED", - 1: "NOTIFY_REASON_FIRST_NOTIFICATION", - 2: "NOTIFY_REASON_NEW_ALERTS_IN_GROUP", - 3: "NOTIFY_REASON_NEW_RESOLVED_ALERTS", - 4: "NOTIFY_REASON_ALL_ALERTS_RESOLVED", - 5: "NOTIFY_REASON_REPEAT_INTERVAL_ELAPSED", - } - NotifyReason_value = map[string]int32{ - "NOTIFY_REASON_UNSPECIFIED": 0, - "NOTIFY_REASON_FIRST_NOTIFICATION": 1, - "NOTIFY_REASON_NEW_ALERTS_IN_GROUP": 2, - "NOTIFY_REASON_NEW_RESOLVED_ALERTS": 3, - "NOTIFY_REASON_ALL_ALERTS_RESOLVED": 4, - "NOTIFY_REASON_REPEAT_INTERVAL_ELAPSED": 5, - } -) - -func (x NotifyReason) Enum() *NotifyReason { - p := new(NotifyReason) - *p = x - return p -} - -func (x NotifyReason) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (NotifyReason) Descriptor() protoreflect.EnumDescriptor { - return file_eventrecorder_proto_enumTypes[0].Descriptor() -} - -func (NotifyReason) Type() protoreflect.EnumType { - return &file_eventrecorder_proto_enumTypes[0] -} - -func (x NotifyReason) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use NotifyReason.Descriptor instead. -func (NotifyReason) EnumDescriptor() ([]byte, []int) { - return file_eventrecorder_proto_rawDescGZIP(), []int{0} -} - -// Type enumerates the supported matching operators. -type Matcher_Type int32 - -const ( - // Unspecified / unknown match type. - Matcher_TYPE_UNSPECIFIED Matcher_Type = 0 - // Exact string equality (=). - Matcher_TYPE_EQUAL Matcher_Type = 1 - // Regular expression match (=~). - Matcher_TYPE_REGEXP Matcher_Type = 2 - // Negated exact string equality (!=). - Matcher_TYPE_NOT_EQUAL Matcher_Type = 3 - // Negated regular expression match (!~). - Matcher_TYPE_NOT_REGEXP Matcher_Type = 4 -) - -// Enum value maps for Matcher_Type. -var ( - Matcher_Type_name = map[int32]string{ - 0: "TYPE_UNSPECIFIED", - 1: "TYPE_EQUAL", - 2: "TYPE_REGEXP", - 3: "TYPE_NOT_EQUAL", - 4: "TYPE_NOT_REGEXP", - } - Matcher_Type_value = map[string]int32{ - "TYPE_UNSPECIFIED": 0, - "TYPE_EQUAL": 1, - "TYPE_REGEXP": 2, - "TYPE_NOT_EQUAL": 3, - "TYPE_NOT_REGEXP": 4, - } -) - -func (x Matcher_Type) Enum() *Matcher_Type { - p := new(Matcher_Type) - *p = x - return p -} - -func (x Matcher_Type) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (Matcher_Type) Descriptor() protoreflect.EnumDescriptor { - return file_eventrecorder_proto_enumTypes[1].Descriptor() -} - -func (Matcher_Type) Type() protoreflect.EnumType { - return &file_eventrecorder_proto_enumTypes[1] -} - -func (x Matcher_Type) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use Matcher_Type.Descriptor instead. -func (Matcher_Type) EnumDescriptor() ([]byte, []int) { - return file_eventrecorder_proto_rawDescGZIP(), []int{15, 0} -} - -// Event is the top-level envelope written to each event recorder output. -// It wraps the specific event data with metadata about when and where -// the event was produced. -type Event struct { - state protoimpl.MessageState `protogen:"open.v1"` - // The wall-clock time at which the event was recorded. - Timestamp *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=timestamp,json=@timestamp,proto3" json:"timestamp,omitempty"` - // The hostname or address of the Alertmanager instance that produced - // the event. - Instance string `protobuf:"bytes,2,opt,name=instance,proto3" json:"instance,omitempty"` - // The event payload. Exactly one of the oneof fields inside EventData - // will be set. - Data *EventData `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` - // The ordinal position of this instance among its HA cluster peers. - // Zero when clustering is disabled. - ClusterPosition uint32 `protobuf:"varint,4,opt,name=cluster_position,json=clusterPosition,proto3" json:"cluster_position,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *Event) Reset() { - *x = Event{} - mi := &file_eventrecorder_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *Event) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Event) ProtoMessage() {} - -func (x *Event) ProtoReflect() protoreflect.Message { - mi := &file_eventrecorder_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Event.ProtoReflect.Descriptor instead. -func (*Event) Descriptor() ([]byte, []int) { - return file_eventrecorder_proto_rawDescGZIP(), []int{0} -} - -func (x *Event) GetTimestamp() *timestamppb.Timestamp { - if x != nil { - return x.Timestamp - } - return nil -} - -func (x *Event) GetInstance() string { - if x != nil { - return x.Instance - } - return "" -} - -func (x *Event) GetData() *EventData { - if x != nil { - return x.Data - } - return nil -} - -func (x *Event) GetClusterPosition() uint32 { - if x != nil { - return x.ClusterPosition - } - return 0 -} - -// EventData carries the payload for a single event recorder entry. -// Exactly one of the oneof fields will be populated. -type EventData struct { - state protoimpl.MessageState `protogen:"open.v1"` - // Types that are valid to be assigned to EventType: - // - // *EventData_AlertmanagerStartupEvent - // *EventData_AlertmanagerShutdownEvent - // *EventData_AlertCreated - // *EventData_AlertResolved - // *EventData_AlertGrouped - // *EventData_Notification - // *EventData_SilenceCreated - // *EventData_SilenceUpdated - // *EventData_SilenceMutedAlert - // *EventData_InhibitionMutedAlert - EventType isEventData_EventType `protobuf_oneof:"event_type"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *EventData) Reset() { - *x = EventData{} - mi := &file_eventrecorder_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *EventData) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*EventData) ProtoMessage() {} - -func (x *EventData) ProtoReflect() protoreflect.Message { - mi := &file_eventrecorder_proto_msgTypes[1] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use EventData.ProtoReflect.Descriptor instead. -func (*EventData) Descriptor() ([]byte, []int) { - return file_eventrecorder_proto_rawDescGZIP(), []int{1} -} - -func (x *EventData) GetEventType() isEventData_EventType { - if x != nil { - return x.EventType - } - return nil -} - -func (x *EventData) GetAlertmanagerStartupEvent() *AlertmanagerStartupEvent { - if x != nil { - if x, ok := x.EventType.(*EventData_AlertmanagerStartupEvent); ok { - return x.AlertmanagerStartupEvent - } - } - return nil -} - -func (x *EventData) GetAlertmanagerShutdownEvent() *AlertmanagerShutdownEvent { - if x != nil { - if x, ok := x.EventType.(*EventData_AlertmanagerShutdownEvent); ok { - return x.AlertmanagerShutdownEvent - } - } - return nil -} - -func (x *EventData) GetAlertCreated() *AlertCreatedEvent { - if x != nil { - if x, ok := x.EventType.(*EventData_AlertCreated); ok { - return x.AlertCreated - } - } - return nil -} - -func (x *EventData) GetAlertResolved() *AlertResolvedEvent { - if x != nil { - if x, ok := x.EventType.(*EventData_AlertResolved); ok { - return x.AlertResolved - } - } - return nil -} - -func (x *EventData) GetAlertGrouped() *AlertGroupedEvent { - if x != nil { - if x, ok := x.EventType.(*EventData_AlertGrouped); ok { - return x.AlertGrouped - } - } - return nil -} - -func (x *EventData) GetNotification() *NotificationEvent { - if x != nil { - if x, ok := x.EventType.(*EventData_Notification); ok { - return x.Notification - } - } - return nil -} - -func (x *EventData) GetSilenceCreated() *SilenceCreatedEvent { - if x != nil { - if x, ok := x.EventType.(*EventData_SilenceCreated); ok { - return x.SilenceCreated - } - } - return nil -} - -func (x *EventData) GetSilenceUpdated() *SilenceUpdatedEvent { - if x != nil { - if x, ok := x.EventType.(*EventData_SilenceUpdated); ok { - return x.SilenceUpdated - } - } - return nil -} - -func (x *EventData) GetSilenceMutedAlert() *SilenceMutedAlertEvent { - if x != nil { - if x, ok := x.EventType.(*EventData_SilenceMutedAlert); ok { - return x.SilenceMutedAlert - } - } - return nil -} - -func (x *EventData) GetInhibitionMutedAlert() *InhibitionMutedAlertEvent { - if x != nil { - if x, ok := x.EventType.(*EventData_InhibitionMutedAlert); ok { - return x.InhibitionMutedAlert - } - } - return nil -} - -type isEventData_EventType interface { - isEventData_EventType() -} - -type EventData_AlertmanagerStartupEvent struct { - // Recorded when the Alertmanager process starts. - AlertmanagerStartupEvent *AlertmanagerStartupEvent `protobuf:"bytes,1,opt,name=alertmanager_startup_event,json=alertmanagerStartupEvent,proto3,oneof"` -} - -type EventData_AlertmanagerShutdownEvent struct { - // Recorded when the Alertmanager process shuts down gracefully. - AlertmanagerShutdownEvent *AlertmanagerShutdownEvent `protobuf:"bytes,2,opt,name=alertmanager_shutdown_event,json=alertmanagerShutdownEvent,proto3,oneof"` -} - -type EventData_AlertCreated struct { - // Recorded when a new alert is first inserted into the alert store. - AlertCreated *AlertCreatedEvent `protobuf:"bytes,3,opt,name=alert_created,json=alertCreated,proto3,oneof"` -} - -type EventData_AlertResolved struct { - // Recorded when an alert transitions to the resolved state and is - // removed from its aggregation group after successful notification. - AlertResolved *AlertResolvedEvent `protobuf:"bytes,4,opt,name=alert_resolved,json=alertResolved,proto3,oneof"` -} - -type EventData_AlertGrouped struct { - // Recorded when an alert is inserted into an aggregation group for - // the first time. - AlertGrouped *AlertGroupedEvent `protobuf:"bytes,5,opt,name=alert_grouped,json=alertGrouped,proto3,oneof"` -} - -type EventData_Notification struct { - // Recorded after a notification is successfully delivered to an - // integration (e.g., webhook, email, PagerDuty). - Notification *NotificationEvent `protobuf:"bytes,6,opt,name=notification,proto3,oneof"` -} - -type EventData_SilenceCreated struct { - // Recorded when a new silence is created. - SilenceCreated *SilenceCreatedEvent `protobuf:"bytes,7,opt,name=silence_created,json=silenceCreated,proto3,oneof"` -} - -type EventData_SilenceUpdated struct { - // Recorded when an existing silence is updated (e.g., extended or - // re-commented). - SilenceUpdated *SilenceUpdatedEvent `protobuf:"bytes,8,opt,name=silence_updated,json=silenceUpdated,proto3,oneof"` -} - -type EventData_SilenceMutedAlert struct { - // Recorded each time a silence actively suppresses an alert during - // the muting evaluation pass. - SilenceMutedAlert *SilenceMutedAlertEvent `protobuf:"bytes,9,opt,name=silence_muted_alert,json=silenceMutedAlert,proto3,oneof"` -} - -type EventData_InhibitionMutedAlert struct { - // Recorded each time one or more inhibition rules suppress an alert - // during the muting evaluation pass. - InhibitionMutedAlert *InhibitionMutedAlertEvent `protobuf:"bytes,10,opt,name=inhibition_muted_alert,json=inhibitionMutedAlert,proto3,oneof"` -} - -func (*EventData_AlertmanagerStartupEvent) isEventData_EventType() {} - -func (*EventData_AlertmanagerShutdownEvent) isEventData_EventType() {} - -func (*EventData_AlertCreated) isEventData_EventType() {} - -func (*EventData_AlertResolved) isEventData_EventType() {} - -func (*EventData_AlertGrouped) isEventData_EventType() {} - -func (*EventData_Notification) isEventData_EventType() {} - -func (*EventData_SilenceCreated) isEventData_EventType() {} - -func (*EventData_SilenceUpdated) isEventData_EventType() {} - -func (*EventData_SilenceMutedAlert) isEventData_EventType() {} - -func (*EventData_InhibitionMutedAlert) isEventData_EventType() {} - -// AlertmanagerStartupEvent is emitted once when the process starts. -type AlertmanagerStartupEvent struct { - state protoimpl.MessageState `protogen:"open.v1"` - // The semantic version of the Alertmanager binary (e.g., "0.28.0"). - Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` - // Free-form build metadata such as Go version, branch, and revision. - BuildContext string `protobuf:"bytes,2,opt,name=build_context,json=buildContext,proto3" json:"build_context,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *AlertmanagerStartupEvent) Reset() { - *x = AlertmanagerStartupEvent{} - mi := &file_eventrecorder_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *AlertmanagerStartupEvent) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AlertmanagerStartupEvent) ProtoMessage() {} - -func (x *AlertmanagerStartupEvent) ProtoReflect() protoreflect.Message { - mi := &file_eventrecorder_proto_msgTypes[2] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AlertmanagerStartupEvent.ProtoReflect.Descriptor instead. -func (*AlertmanagerStartupEvent) Descriptor() ([]byte, []int) { - return file_eventrecorder_proto_rawDescGZIP(), []int{2} -} - -func (x *AlertmanagerStartupEvent) GetVersion() string { - if x != nil { - return x.Version - } - return "" -} - -func (x *AlertmanagerStartupEvent) GetBuildContext() string { - if x != nil { - return x.BuildContext - } - return "" -} - -// AlertmanagerShutdownEvent is emitted when the process shuts down -// gracefully. It carries no additional data. -type AlertmanagerShutdownEvent struct { - state protoimpl.MessageState `protogen:"open.v1"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *AlertmanagerShutdownEvent) Reset() { - *x = AlertmanagerShutdownEvent{} - mi := &file_eventrecorder_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *AlertmanagerShutdownEvent) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AlertmanagerShutdownEvent) ProtoMessage() {} - -func (x *AlertmanagerShutdownEvent) ProtoReflect() protoreflect.Message { - mi := &file_eventrecorder_proto_msgTypes[3] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AlertmanagerShutdownEvent.ProtoReflect.Descriptor instead. -func (*AlertmanagerShutdownEvent) Descriptor() ([]byte, []int) { - return file_eventrecorder_proto_rawDescGZIP(), []int{3} -} - -// LabelPair is a single key-value label. -type LabelPair struct { - state protoimpl.MessageState `protogen:"open.v1"` - // The label name (e.g., "alertname"). - Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - // The label value (e.g., "HighMemoryUsage"). - Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *LabelPair) Reset() { - *x = LabelPair{} - mi := &file_eventrecorder_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *LabelPair) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*LabelPair) ProtoMessage() {} - -func (x *LabelPair) ProtoReflect() protoreflect.Message { - mi := &file_eventrecorder_proto_msgTypes[4] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use LabelPair.ProtoReflect.Descriptor instead. -func (*LabelPair) Descriptor() ([]byte, []int) { - return file_eventrecorder_proto_rawDescGZIP(), []int{4} -} - -func (x *LabelPair) GetKey() string { - if x != nil { - return x.Key - } - return "" -} - -func (x *LabelPair) GetValue() string { - if x != nil { - return x.Value - } - return "" -} - -// LabelSet is an ordered collection of label pairs. -type LabelSet struct { - state protoimpl.MessageState `protogen:"open.v1"` - // The label pairs that make up this set. - Labels []*LabelPair `protobuf:"bytes,1,rep,name=labels,proto3" json:"labels,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *LabelSet) Reset() { - *x = LabelSet{} - mi := &file_eventrecorder_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *LabelSet) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*LabelSet) ProtoMessage() {} - -func (x *LabelSet) ProtoReflect() protoreflect.Message { - mi := &file_eventrecorder_proto_msgTypes[5] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use LabelSet.ProtoReflect.Descriptor instead. -func (*LabelSet) Descriptor() ([]byte, []int) { - return file_eventrecorder_proto_rawDescGZIP(), []int{5} -} - -func (x *LabelSet) GetLabels() []*LabelPair { - if x != nil { - return x.Labels - } - return nil -} - -// Alert represents a snapshot of an alert at the time the event was -// recorded. -type Alert struct { - state protoimpl.MessageState `protogen:"open.v1"` - // The unique fingerprint derived from the alert's label set. - Fingerprint uint64 `protobuf:"varint,1,opt,name=fingerprint,proto3" json:"fingerprint,omitempty"` - // The value of the "alertname" label, provided for convenience. - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - // The full label set that identifies this alert. - Labels *LabelSet `protobuf:"bytes,3,opt,name=labels,proto3" json:"labels,omitempty"` - // Informational annotations attached to the alert (e.g., summary, - // description). - Annotations *LabelSet `protobuf:"bytes,4,opt,name=annotations,proto3" json:"annotations,omitempty"` - // The time at which the alert started firing. - StartsAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=starts_at,json=startsAt,proto3" json:"starts_at,omitempty"` - // The time at which the alert is considered resolved. For firing - // alerts this is typically set to a time in the future. - EndsAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=ends_at,json=endsAt,proto3" json:"ends_at,omitempty"` - // Whether the alert was resolved at the time the event was recorded. - Resolved bool `protobuf:"varint,7,opt,name=resolved,proto3" json:"resolved,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *Alert) Reset() { - *x = Alert{} - mi := &file_eventrecorder_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *Alert) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Alert) ProtoMessage() {} - -func (x *Alert) ProtoReflect() protoreflect.Message { - mi := &file_eventrecorder_proto_msgTypes[6] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Alert.ProtoReflect.Descriptor instead. -func (*Alert) Descriptor() ([]byte, []int) { - return file_eventrecorder_proto_rawDescGZIP(), []int{6} -} - -func (x *Alert) GetFingerprint() uint64 { - if x != nil { - return x.Fingerprint - } - return 0 -} - -func (x *Alert) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Alert) GetLabels() *LabelSet { - if x != nil { - return x.Labels - } - return nil -} - -func (x *Alert) GetAnnotations() *LabelSet { - if x != nil { - return x.Annotations - } - return nil -} - -func (x *Alert) GetStartsAt() *timestamppb.Timestamp { - if x != nil { - return x.StartsAt - } - return nil -} - -func (x *Alert) GetEndsAt() *timestamppb.Timestamp { - if x != nil { - return x.EndsAt - } - return nil -} - -func (x *Alert) GetResolved() bool { - if x != nil { - return x.Resolved - } - return false -} - -// GroupedAlert is a reference to an alert within an aggregation group. -// It always carries the content hash; the full alert details are -// included when available. -type GroupedAlert struct { - state protoimpl.MessageState `protogen:"open.v1"` - // A hash of the alert's label set, used for deduplication within the - // notification pipeline. - Hash uint64 `protobuf:"varint,1,opt,name=hash,proto3" json:"hash,omitempty"` - // The full alert details. May be absent when only the hash is needed - // (e.g., in firing/resolved lists on NotificationEvent). - Details *Alert `protobuf:"bytes,2,opt,name=details,proto3,oneof" json:"details,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *GroupedAlert) Reset() { - *x = GroupedAlert{} - mi := &file_eventrecorder_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *GroupedAlert) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GroupedAlert) ProtoMessage() {} - -func (x *GroupedAlert) ProtoReflect() protoreflect.Message { - mi := &file_eventrecorder_proto_msgTypes[7] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GroupedAlert.ProtoReflect.Descriptor instead. -func (*GroupedAlert) Descriptor() ([]byte, []int) { - return file_eventrecorder_proto_rawDescGZIP(), []int{7} -} - -func (x *GroupedAlert) GetHash() uint64 { - if x != nil { - return x.Hash - } - return 0 -} - -func (x *GroupedAlert) GetDetails() *Alert { - if x != nil { - return x.Details - } - return nil -} - -// AlertGroupInfo describes the aggregation group context in which an -// alert is being processed. -type AlertGroupInfo struct { - state protoimpl.MessageState `protogen:"open.v1"` - // The composite key that uniquely identifies this aggregation group - // (encodes route and group label values). - GroupKey string `protobuf:"bytes,1,opt,name=group_key,json=groupKey,proto3" json:"group_key,omitempty"` - // The label set used to group alerts together within this route. - GroupLabels *LabelSet `protobuf:"bytes,2,opt,name=group_labels,json=groupLabels,proto3" json:"group_labels,omitempty"` - // A stable, shortened identifier derived from the group key (SHA-256 - // hex). - GroupId string `protobuf:"bytes,3,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"` - // The name of the receiver that this group routes to. - ReceiverName string `protobuf:"bytes,4,opt,name=receiver_name,json=receiverName,proto3" json:"receiver_name,omitempty"` - // The set of matchers defined on the route that matched these alerts. - Matchers []*Matcher `protobuf:"bytes,5,rep,name=matchers,proto3" json:"matchers,omitempty"` - // A UUID that uniquely identifies this aggregation group instance. - GroupUuid string `protobuf:"bytes,6,opt,name=group_uuid,json=groupUuid,proto3" json:"group_uuid,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *AlertGroupInfo) Reset() { - *x = AlertGroupInfo{} - mi := &file_eventrecorder_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *AlertGroupInfo) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AlertGroupInfo) ProtoMessage() {} - -func (x *AlertGroupInfo) ProtoReflect() protoreflect.Message { - mi := &file_eventrecorder_proto_msgTypes[8] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AlertGroupInfo.ProtoReflect.Descriptor instead. -func (*AlertGroupInfo) Descriptor() ([]byte, []int) { - return file_eventrecorder_proto_rawDescGZIP(), []int{8} -} - -func (x *AlertGroupInfo) GetGroupKey() string { - if x != nil { - return x.GroupKey - } - return "" -} - -func (x *AlertGroupInfo) GetGroupLabels() *LabelSet { - if x != nil { - return x.GroupLabels - } - return nil -} - -func (x *AlertGroupInfo) GetGroupId() string { - if x != nil { - return x.GroupId - } - return "" -} - -func (x *AlertGroupInfo) GetReceiverName() string { - if x != nil { - return x.ReceiverName - } - return "" -} - -func (x *AlertGroupInfo) GetMatchers() []*Matcher { - if x != nil { - return x.Matchers - } - return nil -} - -func (x *AlertGroupInfo) GetGroupUuid() string { - if x != nil { - return x.GroupUuid - } - return "" -} - -// AlertCreatedEvent is emitted when a brand-new alert is inserted into -// the in-memory alert store. -type AlertCreatedEvent struct { - state protoimpl.MessageState `protogen:"open.v1"` - // The newly created alert. - Alert *Alert `protobuf:"bytes,1,opt,name=alert,proto3" json:"alert,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *AlertCreatedEvent) Reset() { - *x = AlertCreatedEvent{} - mi := &file_eventrecorder_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *AlertCreatedEvent) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AlertCreatedEvent) ProtoMessage() {} - -func (x *AlertCreatedEvent) ProtoReflect() protoreflect.Message { - mi := &file_eventrecorder_proto_msgTypes[9] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AlertCreatedEvent.ProtoReflect.Descriptor instead. -func (*AlertCreatedEvent) Descriptor() ([]byte, []int) { - return file_eventrecorder_proto_rawDescGZIP(), []int{9} -} - -func (x *AlertCreatedEvent) GetAlert() *Alert { - if x != nil { - return x.Alert - } - return nil -} - -// AlertResolvedEvent is emitted when an alert is removed from its -// aggregation group after a successful notification that included the -// resolution. -type AlertResolvedEvent struct { - state protoimpl.MessageState `protogen:"open.v1"` - // The resolved alert, including its hash and full details. - Alert *GroupedAlert `protobuf:"bytes,1,opt,name=alert,proto3" json:"alert,omitempty"` - // The aggregation group from which the alert was resolved. - GroupInfo *AlertGroupInfo `protobuf:"bytes,2,opt,name=group_info,json=groupInfo,proto3" json:"group_info,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *AlertResolvedEvent) Reset() { - *x = AlertResolvedEvent{} - mi := &file_eventrecorder_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *AlertResolvedEvent) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AlertResolvedEvent) ProtoMessage() {} - -func (x *AlertResolvedEvent) ProtoReflect() protoreflect.Message { - mi := &file_eventrecorder_proto_msgTypes[10] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AlertResolvedEvent.ProtoReflect.Descriptor instead. -func (*AlertResolvedEvent) Descriptor() ([]byte, []int) { - return file_eventrecorder_proto_rawDescGZIP(), []int{10} -} - -func (x *AlertResolvedEvent) GetAlert() *GroupedAlert { - if x != nil { - return x.Alert - } - return nil -} - -func (x *AlertResolvedEvent) GetGroupInfo() *AlertGroupInfo { - if x != nil { - return x.GroupInfo - } - return nil -} - -// AlertGroupedEvent is emitted the first time an alert is inserted into -// an aggregation group. -type AlertGroupedEvent struct { - state protoimpl.MessageState `protogen:"open.v1"` - // The alert being grouped, including its hash and full details. - Alert *GroupedAlert `protobuf:"bytes,1,opt,name=alert,proto3" json:"alert,omitempty"` - // The aggregation group the alert was added to. - GroupInfo *AlertGroupInfo `protobuf:"bytes,2,opt,name=group_info,json=groupInfo,proto3" json:"group_info,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *AlertGroupedEvent) Reset() { - *x = AlertGroupedEvent{} - mi := &file_eventrecorder_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *AlertGroupedEvent) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AlertGroupedEvent) ProtoMessage() {} - -func (x *AlertGroupedEvent) ProtoReflect() protoreflect.Message { - mi := &file_eventrecorder_proto_msgTypes[11] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AlertGroupedEvent.ProtoReflect.Descriptor instead. -func (*AlertGroupedEvent) Descriptor() ([]byte, []int) { - return file_eventrecorder_proto_rawDescGZIP(), []int{11} -} - -func (x *AlertGroupedEvent) GetAlert() *GroupedAlert { - if x != nil { - return x.Alert - } - return nil -} - -func (x *AlertGroupedEvent) GetGroupInfo() *AlertGroupInfo { - if x != nil { - return x.GroupInfo - } - return nil -} - -// Integration identifies a specific notification integration (e.g., -// the second PagerDuty receiver in a receiver definition). -type Integration struct { - state protoimpl.MessageState `protogen:"open.v1"` - // The type of the integration (e.g., "webhook", "pagerduty"). - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // The zero-based index of this integration within its receiver. - Index int64 `protobuf:"varint,2,opt,name=index,proto3" json:"index,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *Integration) Reset() { - *x = Integration{} - mi := &file_eventrecorder_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *Integration) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Integration) ProtoMessage() {} - -func (x *Integration) ProtoReflect() protoreflect.Message { - mi := &file_eventrecorder_proto_msgTypes[12] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Integration.ProtoReflect.Descriptor instead. -func (*Integration) Descriptor() ([]byte, []int) { - return file_eventrecorder_proto_rawDescGZIP(), []int{12} -} - -func (x *Integration) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Integration) GetIndex() int64 { - if x != nil { - return x.Index - } - return 0 -} - -// NotificationEvent is emitted after a notification is successfully -// delivered to an integration. -type NotificationEvent struct { - state protoimpl.MessageState `protogen:"open.v1"` - // All alerts that were included in the notification. - Alerts []*GroupedAlert `protobuf:"bytes,1,rep,name=alerts,proto3" json:"alerts,omitempty"` - // The subset of alerts that are currently firing. - FiringAlerts []*GroupedAlert `protobuf:"bytes,2,rep,name=firing_alerts,json=firingAlerts,proto3" json:"firing_alerts,omitempty"` - // The subset of alerts that are resolved. - ResolvedAlerts []*GroupedAlert `protobuf:"bytes,3,rep,name=resolved_alerts,json=resolvedAlerts,proto3" json:"resolved_alerts,omitempty"` - // Alerts that were muted (silenced or inhibited) during this flush - // cycle. - MutedAlerts []*GroupedAlert `protobuf:"bytes,4,rep,name=muted_alerts,json=mutedAlerts,proto3" json:"muted_alerts,omitempty"` - // The aggregation group context for this notification. - GroupInfo *AlertGroupInfo `protobuf:"bytes,5,opt,name=group_info,json=groupInfo,proto3" json:"group_info,omitempty"` - // The configured repeat interval for the aggregation group's route. - RepeatInterval *durationpb.Duration `protobuf:"bytes,6,opt,name=repeat_interval,json=repeatInterval,proto3" json:"repeat_interval,omitempty"` - // The reason the notification was triggered. - Reason NotifyReason `protobuf:"varint,7,opt,name=reason,proto3,enum=eventrecorderpb.NotifyReason" json:"reason,omitempty"` - // A monotonically increasing identifier for each flush cycle of the - // aggregation group. - FlushId uint64 `protobuf:"varint,8,opt,name=flush_id,json=flushId,proto3" json:"flush_id,omitempty"` - // The integration that delivered the notification. - Integration *Integration `protobuf:"bytes,9,opt,name=integration,proto3" json:"integration,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *NotificationEvent) Reset() { - *x = NotificationEvent{} - mi := &file_eventrecorder_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *NotificationEvent) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*NotificationEvent) ProtoMessage() {} - -func (x *NotificationEvent) ProtoReflect() protoreflect.Message { - mi := &file_eventrecorder_proto_msgTypes[13] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use NotificationEvent.ProtoReflect.Descriptor instead. -func (*NotificationEvent) Descriptor() ([]byte, []int) { - return file_eventrecorder_proto_rawDescGZIP(), []int{13} -} - -func (x *NotificationEvent) GetAlerts() []*GroupedAlert { - if x != nil { - return x.Alerts - } - return nil -} - -func (x *NotificationEvent) GetFiringAlerts() []*GroupedAlert { - if x != nil { - return x.FiringAlerts - } - return nil -} - -func (x *NotificationEvent) GetResolvedAlerts() []*GroupedAlert { - if x != nil { - return x.ResolvedAlerts - } - return nil -} - -func (x *NotificationEvent) GetMutedAlerts() []*GroupedAlert { - if x != nil { - return x.MutedAlerts - } - return nil -} - -func (x *NotificationEvent) GetGroupInfo() *AlertGroupInfo { - if x != nil { - return x.GroupInfo - } - return nil -} - -func (x *NotificationEvent) GetRepeatInterval() *durationpb.Duration { - if x != nil { - return x.RepeatInterval - } - return nil -} - -func (x *NotificationEvent) GetReason() NotifyReason { - if x != nil { - return x.Reason - } - return NotifyReason_NOTIFY_REASON_UNSPECIFIED -} - -func (x *NotificationEvent) GetFlushId() uint64 { - if x != nil { - return x.FlushId - } - return 0 -} - -func (x *NotificationEvent) GetIntegration() *Integration { - if x != nil { - return x.Integration - } - return nil -} - -// Silence is a snapshot of a silence definition at the time the event -// was recorded. -type Silence struct { - state protoimpl.MessageState `protogen:"open.v1"` - // The globally unique silence identifier (UUID). - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - // The matchers that define which alerts this silence suppresses. - // For silences with multiple matcher sets, this is the first set. - Matchers []*Matcher `protobuf:"bytes,2,rep,name=matchers,proto3" json:"matchers,omitempty"` - // Optional structured annotations on the silence (key-value pairs). - Annotations *LabelSet `protobuf:"bytes,3,opt,name=annotations,proto3" json:"annotations,omitempty"` - // The time at which the silence becomes active. - StartsAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=starts_at,json=startsAt,proto3" json:"starts_at,omitempty"` - // The time at which the silence expires. - EndsAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=ends_at,json=endsAt,proto3" json:"ends_at,omitempty"` - // The last time the silence was created or updated. - UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` - // The author who created the silence. - CreatedBy string `protobuf:"bytes,7,opt,name=created_by,json=createdBy,proto3" json:"created_by,omitempty"` - // A human-readable comment explaining the silence. - Comment string `protobuf:"bytes,8,opt,name=comment,proto3" json:"comment,omitempty"` - // Additional matcher sets evaluated with OR logic. At least one - // matcher set must match for the silence to apply. - MatcherSets []*MatcherSet `protobuf:"bytes,9,rep,name=matcher_sets,json=matcherSets,proto3" json:"matcher_sets,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *Silence) Reset() { - *x = Silence{} - mi := &file_eventrecorder_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *Silence) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Silence) ProtoMessage() {} - -func (x *Silence) ProtoReflect() protoreflect.Message { - mi := &file_eventrecorder_proto_msgTypes[14] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Silence.ProtoReflect.Descriptor instead. -func (*Silence) Descriptor() ([]byte, []int) { - return file_eventrecorder_proto_rawDescGZIP(), []int{14} -} - -func (x *Silence) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *Silence) GetMatchers() []*Matcher { - if x != nil { - return x.Matchers - } - return nil -} - -func (x *Silence) GetAnnotations() *LabelSet { - if x != nil { - return x.Annotations - } - return nil -} - -func (x *Silence) GetStartsAt() *timestamppb.Timestamp { - if x != nil { - return x.StartsAt - } - return nil -} - -func (x *Silence) GetEndsAt() *timestamppb.Timestamp { - if x != nil { - return x.EndsAt - } - return nil -} - -func (x *Silence) GetUpdatedAt() *timestamppb.Timestamp { - if x != nil { - return x.UpdatedAt - } - return nil -} - -func (x *Silence) GetCreatedBy() string { - if x != nil { - return x.CreatedBy - } - return "" -} - -func (x *Silence) GetComment() string { - if x != nil { - return x.Comment - } - return "" -} - -func (x *Silence) GetMatcherSets() []*MatcherSet { - if x != nil { - return x.MatcherSets - } - return nil -} - -// Matcher defines a single label matching rule. -type Matcher struct { - state protoimpl.MessageState `protogen:"open.v1"` - // The matching operator to apply. - Type Matcher_Type `protobuf:"varint,1,opt,name=type,proto3,enum=eventrecorderpb.Matcher_Type" json:"type,omitempty"` - // The label name to match against. - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - // The value or pattern to match, interpreted according to type. - Pattern string `protobuf:"bytes,3,opt,name=pattern,proto3" json:"pattern,omitempty"` - // Human-readable string representation (e.g., "env=~prod.*"). - Rendered string `protobuf:"bytes,4,opt,name=rendered,proto3" json:"rendered,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *Matcher) Reset() { - *x = Matcher{} - mi := &file_eventrecorder_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *Matcher) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Matcher) ProtoMessage() {} - -func (x *Matcher) ProtoReflect() protoreflect.Message { - mi := &file_eventrecorder_proto_msgTypes[15] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Matcher.ProtoReflect.Descriptor instead. -func (*Matcher) Descriptor() ([]byte, []int) { - return file_eventrecorder_proto_rawDescGZIP(), []int{15} -} - -func (x *Matcher) GetType() Matcher_Type { - if x != nil { - return x.Type - } - return Matcher_TYPE_UNSPECIFIED -} - -func (x *Matcher) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Matcher) GetPattern() string { - if x != nil { - return x.Pattern - } - return "" -} - -func (x *Matcher) GetRendered() string { - if x != nil { - return x.Rendered - } - return "" -} - -// MatcherSet is a conjunction of matchers: all matchers in the set must -// match for the set to match. -type MatcherSet struct { - state protoimpl.MessageState `protogen:"open.v1"` - // The matchers that make up this set (evaluated with AND logic). - Matchers []*Matcher `protobuf:"bytes,1,rep,name=matchers,proto3" json:"matchers,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *MatcherSet) Reset() { - *x = MatcherSet{} - mi := &file_eventrecorder_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *MatcherSet) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*MatcherSet) ProtoMessage() {} - -func (x *MatcherSet) ProtoReflect() protoreflect.Message { - mi := &file_eventrecorder_proto_msgTypes[16] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use MatcherSet.ProtoReflect.Descriptor instead. -func (*MatcherSet) Descriptor() ([]byte, []int) { - return file_eventrecorder_proto_rawDescGZIP(), []int{16} -} - -func (x *MatcherSet) GetMatchers() []*Matcher { - if x != nil { - return x.Matchers - } - return nil -} - -// SilenceCreatedEvent is emitted when a new silence is created. -type SilenceCreatedEvent struct { - state protoimpl.MessageState `protogen:"open.v1"` - // The newly created silence. - Silence *Silence `protobuf:"bytes,1,opt,name=silence,proto3" json:"silence,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *SilenceCreatedEvent) Reset() { - *x = SilenceCreatedEvent{} - mi := &file_eventrecorder_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *SilenceCreatedEvent) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SilenceCreatedEvent) ProtoMessage() {} - -func (x *SilenceCreatedEvent) ProtoReflect() protoreflect.Message { - mi := &file_eventrecorder_proto_msgTypes[17] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SilenceCreatedEvent.ProtoReflect.Descriptor instead. -func (*SilenceCreatedEvent) Descriptor() ([]byte, []int) { - return file_eventrecorder_proto_rawDescGZIP(), []int{17} -} - -func (x *SilenceCreatedEvent) GetSilence() *Silence { - if x != nil { - return x.Silence - } - return nil -} - -// SilenceUpdatedEvent is emitted when an existing silence is modified. -type SilenceUpdatedEvent struct { - state protoimpl.MessageState `protogen:"open.v1"` - // The silence after the update. - Silence *Silence `protobuf:"bytes,1,opt,name=silence,proto3" json:"silence,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *SilenceUpdatedEvent) Reset() { - *x = SilenceUpdatedEvent{} - mi := &file_eventrecorder_proto_msgTypes[18] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *SilenceUpdatedEvent) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SilenceUpdatedEvent) ProtoMessage() {} - -func (x *SilenceUpdatedEvent) ProtoReflect() protoreflect.Message { - mi := &file_eventrecorder_proto_msgTypes[18] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SilenceUpdatedEvent.ProtoReflect.Descriptor instead. -func (*SilenceUpdatedEvent) Descriptor() ([]byte, []int) { - return file_eventrecorder_proto_rawDescGZIP(), []int{18} -} - -func (x *SilenceUpdatedEvent) GetSilence() *Silence { - if x != nil { - return x.Silence - } - return nil -} - -// MutedAlert identifies an alert that was suppressed by a silence or -// inhibition rule. -type MutedAlert struct { - state protoimpl.MessageState `protogen:"open.v1"` - // The label set of the muted alert. - Labels *LabelSet `protobuf:"bytes,1,opt,name=labels,proto3" json:"labels,omitempty"` - // The fingerprint of the muted alert. - Fingerprint uint64 `protobuf:"varint,2,opt,name=fingerprint,proto3" json:"fingerprint,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *MutedAlert) Reset() { - *x = MutedAlert{} - mi := &file_eventrecorder_proto_msgTypes[19] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *MutedAlert) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*MutedAlert) ProtoMessage() {} - -func (x *MutedAlert) ProtoReflect() protoreflect.Message { - mi := &file_eventrecorder_proto_msgTypes[19] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use MutedAlert.ProtoReflect.Descriptor instead. -func (*MutedAlert) Descriptor() ([]byte, []int) { - return file_eventrecorder_proto_rawDescGZIP(), []int{19} -} - -func (x *MutedAlert) GetLabels() *LabelSet { - if x != nil { - return x.Labels - } - return nil -} - -func (x *MutedAlert) GetFingerprint() uint64 { - if x != nil { - return x.Fingerprint - } - return 0 -} - -// SilenceMutedAlertEvent is emitted each time a silence suppresses an -// alert during the muting evaluation pass. -type SilenceMutedAlertEvent struct { - state protoimpl.MessageState `protogen:"open.v1"` - // The silence that suppressed the alert. - Silence *Silence `protobuf:"bytes,1,opt,name=silence,proto3" json:"silence,omitempty"` - // The alert that was suppressed. - MutedAlert *MutedAlert `protobuf:"bytes,2,opt,name=muted_alert,json=mutedAlert,proto3" json:"muted_alert,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *SilenceMutedAlertEvent) Reset() { - *x = SilenceMutedAlertEvent{} - mi := &file_eventrecorder_proto_msgTypes[20] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *SilenceMutedAlertEvent) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SilenceMutedAlertEvent) ProtoMessage() {} - -func (x *SilenceMutedAlertEvent) ProtoReflect() protoreflect.Message { - mi := &file_eventrecorder_proto_msgTypes[20] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SilenceMutedAlertEvent.ProtoReflect.Descriptor instead. -func (*SilenceMutedAlertEvent) Descriptor() ([]byte, []int) { - return file_eventrecorder_proto_rawDescGZIP(), []int{20} -} - -func (x *SilenceMutedAlertEvent) GetSilence() *Silence { - if x != nil { - return x.Silence - } - return nil -} - -func (x *SilenceMutedAlertEvent) GetMutedAlert() *MutedAlert { - if x != nil { - return x.MutedAlert - } - return nil -} - -// InhibitRule is a snapshot of an inhibition rule definition. -type InhibitRule struct { - state protoimpl.MessageState `protogen:"open.v1"` - // Matchers that identify source alerts (those that do the inhibiting). - SourceMatchers []*Matcher `protobuf:"bytes,1,rep,name=source_matchers,json=sourceMatchers,proto3" json:"source_matchers,omitempty"` - // Matchers that identify target alerts (those that get inhibited). - TargetMatchers []*Matcher `protobuf:"bytes,2,rep,name=target_matchers,json=targetMatchers,proto3" json:"target_matchers,omitempty"` - // Label names whose values must be equal between source and target - // alerts for the inhibition to take effect. - EqualLabels []string `protobuf:"bytes,3,rep,name=equal_labels,json=equalLabels,proto3" json:"equal_labels,omitempty"` - // Name is the optional name of the inhibition rule. - Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *InhibitRule) Reset() { - *x = InhibitRule{} - mi := &file_eventrecorder_proto_msgTypes[21] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *InhibitRule) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*InhibitRule) ProtoMessage() {} - -func (x *InhibitRule) ProtoReflect() protoreflect.Message { - mi := &file_eventrecorder_proto_msgTypes[21] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use InhibitRule.ProtoReflect.Descriptor instead. -func (*InhibitRule) Descriptor() ([]byte, []int) { - return file_eventrecorder_proto_rawDescGZIP(), []int{21} -} - -func (x *InhibitRule) GetSourceMatchers() []*Matcher { - if x != nil { - return x.SourceMatchers - } - return nil -} - -func (x *InhibitRule) GetTargetMatchers() []*Matcher { - if x != nil { - return x.TargetMatchers - } - return nil -} - -func (x *InhibitRule) GetEqualLabels() []string { - if x != nil { - return x.EqualLabels - } - return nil -} - -func (x *InhibitRule) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -// InhibitionMutedAlertEvent is emitted when one or more inhibition -// rules suppress an alert. -type InhibitionMutedAlertEvent struct { - state protoimpl.MessageState `protogen:"open.v1"` - // The inhibition rules that matched. - InhibitRules []*InhibitRule `protobuf:"bytes,1,rep,name=inhibit_rules,json=inhibitRules,proto3" json:"inhibit_rules,omitempty"` - // The alert that was suppressed. - MutedAlert *MutedAlert `protobuf:"bytes,2,opt,name=muted_alert,json=mutedAlert,proto3" json:"muted_alert,omitempty"` - // The fingerprints of the source alerts that caused the inhibition. - InhibitingFingerprints []uint64 `protobuf:"varint,3,rep,packed,name=inhibiting_fingerprints,json=inhibitingFingerprints,proto3" json:"inhibiting_fingerprints,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *InhibitionMutedAlertEvent) Reset() { - *x = InhibitionMutedAlertEvent{} - mi := &file_eventrecorder_proto_msgTypes[22] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *InhibitionMutedAlertEvent) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*InhibitionMutedAlertEvent) ProtoMessage() {} - -func (x *InhibitionMutedAlertEvent) ProtoReflect() protoreflect.Message { - mi := &file_eventrecorder_proto_msgTypes[22] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use InhibitionMutedAlertEvent.ProtoReflect.Descriptor instead. -func (*InhibitionMutedAlertEvent) Descriptor() ([]byte, []int) { - return file_eventrecorder_proto_rawDescGZIP(), []int{22} -} - -func (x *InhibitionMutedAlertEvent) GetInhibitRules() []*InhibitRule { - if x != nil { - return x.InhibitRules - } - return nil -} - -func (x *InhibitionMutedAlertEvent) GetMutedAlert() *MutedAlert { - if x != nil { - return x.MutedAlert - } - return nil -} - -func (x *InhibitionMutedAlertEvent) GetInhibitingFingerprints() []uint64 { - if x != nil { - return x.InhibitingFingerprints - } - return nil -} - -var File_eventrecorder_proto protoreflect.FileDescriptor - -const file_eventrecorder_proto_rawDesc = "" + - "\n" + - "\x13eventrecorder.proto\x12\x0feventrecorderpb\x1a\x1egoogle/protobuf/duration.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xb9\x01\n" + - "\x05Event\x129\n" + - "\ttimestamp\x18\x01 \x01(\v2\x1a.google.protobuf.TimestampR\n" + - "@timestamp\x12\x1a\n" + - "\binstance\x18\x02 \x01(\tR\binstance\x12.\n" + - "\x04data\x18\x03 \x01(\v2\x1a.eventrecorderpb.EventDataR\x04data\x12)\n" + - "\x10cluster_position\x18\x04 \x01(\rR\x0fclusterPosition\"\x81\a\n" + - "\tEventData\x12i\n" + - "\x1aalertmanager_startup_event\x18\x01 \x01(\v2).eventrecorderpb.AlertmanagerStartupEventH\x00R\x18alertmanagerStartupEvent\x12l\n" + - "\x1balertmanager_shutdown_event\x18\x02 \x01(\v2*.eventrecorderpb.AlertmanagerShutdownEventH\x00R\x19alertmanagerShutdownEvent\x12I\n" + - "\ralert_created\x18\x03 \x01(\v2\".eventrecorderpb.AlertCreatedEventH\x00R\falertCreated\x12L\n" + - "\x0ealert_resolved\x18\x04 \x01(\v2#.eventrecorderpb.AlertResolvedEventH\x00R\ralertResolved\x12I\n" + - "\ralert_grouped\x18\x05 \x01(\v2\".eventrecorderpb.AlertGroupedEventH\x00R\falertGrouped\x12H\n" + - "\fnotification\x18\x06 \x01(\v2\".eventrecorderpb.NotificationEventH\x00R\fnotification\x12O\n" + - "\x0fsilence_created\x18\a \x01(\v2$.eventrecorderpb.SilenceCreatedEventH\x00R\x0esilenceCreated\x12O\n" + - "\x0fsilence_updated\x18\b \x01(\v2$.eventrecorderpb.SilenceUpdatedEventH\x00R\x0esilenceUpdated\x12Y\n" + - "\x13silence_muted_alert\x18\t \x01(\v2'.eventrecorderpb.SilenceMutedAlertEventH\x00R\x11silenceMutedAlert\x12b\n" + - "\x16inhibition_muted_alert\x18\n" + - " \x01(\v2*.eventrecorderpb.InhibitionMutedAlertEventH\x00R\x14inhibitionMutedAlertB\f\n" + - "\n" + - "event_type\"Y\n" + - "\x18AlertmanagerStartupEvent\x12\x18\n" + - "\aversion\x18\x01 \x01(\tR\aversion\x12#\n" + - "\rbuild_context\x18\x02 \x01(\tR\fbuildContext\"\x1b\n" + - "\x19AlertmanagerShutdownEvent\"3\n" + - "\tLabelPair\x12\x10\n" + - "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + - "\x05value\x18\x02 \x01(\tR\x05value\">\n" + - "\bLabelSet\x122\n" + - "\x06labels\x18\x01 \x03(\v2\x1a.eventrecorderpb.LabelPairR\x06labels\"\xb7\x02\n" + - "\x05Alert\x12 \n" + - "\vfingerprint\x18\x01 \x01(\x04R\vfingerprint\x12\x12\n" + - "\x04name\x18\x02 \x01(\tR\x04name\x121\n" + - "\x06labels\x18\x03 \x01(\v2\x19.eventrecorderpb.LabelSetR\x06labels\x12;\n" + - "\vannotations\x18\x04 \x01(\v2\x19.eventrecorderpb.LabelSetR\vannotations\x127\n" + - "\tstarts_at\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\bstartsAt\x123\n" + - "\aends_at\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\x06endsAt\x12\x1a\n" + - "\bresolved\x18\a \x01(\bR\bresolved\"e\n" + - "\fGroupedAlert\x12\x12\n" + - "\x04hash\x18\x01 \x01(\x04R\x04hash\x125\n" + - "\adetails\x18\x02 \x01(\v2\x16.eventrecorderpb.AlertH\x00R\adetails\x88\x01\x01B\n" + - "\n" + - "\b_details\"\x80\x02\n" + - "\x0eAlertGroupInfo\x12\x1b\n" + - "\tgroup_key\x18\x01 \x01(\tR\bgroupKey\x12<\n" + - "\fgroup_labels\x18\x02 \x01(\v2\x19.eventrecorderpb.LabelSetR\vgroupLabels\x12\x19\n" + - "\bgroup_id\x18\x03 \x01(\tR\agroupId\x12#\n" + - "\rreceiver_name\x18\x04 \x01(\tR\freceiverName\x124\n" + - "\bmatchers\x18\x05 \x03(\v2\x18.eventrecorderpb.MatcherR\bmatchers\x12\x1d\n" + - "\n" + - "group_uuid\x18\x06 \x01(\tR\tgroupUuid\"A\n" + - "\x11AlertCreatedEvent\x12,\n" + - "\x05alert\x18\x01 \x01(\v2\x16.eventrecorderpb.AlertR\x05alert\"\x89\x01\n" + - "\x12AlertResolvedEvent\x123\n" + - "\x05alert\x18\x01 \x01(\v2\x1d.eventrecorderpb.GroupedAlertR\x05alert\x12>\n" + - "\n" + - "group_info\x18\x02 \x01(\v2\x1f.eventrecorderpb.AlertGroupInfoR\tgroupInfo\"\x88\x01\n" + - "\x11AlertGroupedEvent\x123\n" + - "\x05alert\x18\x01 \x01(\v2\x1d.eventrecorderpb.GroupedAlertR\x05alert\x12>\n" + - "\n" + - "group_info\x18\x02 \x01(\v2\x1f.eventrecorderpb.AlertGroupInfoR\tgroupInfo\"7\n" + - "\vIntegration\x12\x12\n" + - "\x04name\x18\x01 \x01(\tR\x04name\x12\x14\n" + - "\x05index\x18\x02 \x01(\x03R\x05index\"\xae\x04\n" + - "\x11NotificationEvent\x125\n" + - "\x06alerts\x18\x01 \x03(\v2\x1d.eventrecorderpb.GroupedAlertR\x06alerts\x12B\n" + - "\rfiring_alerts\x18\x02 \x03(\v2\x1d.eventrecorderpb.GroupedAlertR\ffiringAlerts\x12F\n" + - "\x0fresolved_alerts\x18\x03 \x03(\v2\x1d.eventrecorderpb.GroupedAlertR\x0eresolvedAlerts\x12@\n" + - "\fmuted_alerts\x18\x04 \x03(\v2\x1d.eventrecorderpb.GroupedAlertR\vmutedAlerts\x12>\n" + - "\n" + - "group_info\x18\x05 \x01(\v2\x1f.eventrecorderpb.AlertGroupInfoR\tgroupInfo\x12B\n" + - "\x0frepeat_interval\x18\x06 \x01(\v2\x19.google.protobuf.DurationR\x0erepeatInterval\x125\n" + - "\x06reason\x18\a \x01(\x0e2\x1d.eventrecorderpb.NotifyReasonR\x06reason\x12\x19\n" + - "\bflush_id\x18\b \x01(\x04R\aflushId\x12>\n" + - "\vintegration\x18\t \x01(\v2\x1c.eventrecorderpb.IntegrationR\vintegration\"\xae\x03\n" + - "\aSilence\x12\x0e\n" + - "\x02id\x18\x01 \x01(\tR\x02id\x124\n" + - "\bmatchers\x18\x02 \x03(\v2\x18.eventrecorderpb.MatcherR\bmatchers\x12;\n" + - "\vannotations\x18\x03 \x01(\v2\x19.eventrecorderpb.LabelSetR\vannotations\x127\n" + - "\tstarts_at\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\bstartsAt\x123\n" + - "\aends_at\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\x06endsAt\x129\n" + - "\n" + - "updated_at\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\tupdatedAt\x12\x1d\n" + - "\n" + - "created_by\x18\a \x01(\tR\tcreatedBy\x12\x18\n" + - "\acomment\x18\b \x01(\tR\acomment\x12>\n" + - "\fmatcher_sets\x18\t \x03(\v2\x1b.eventrecorderpb.MatcherSetR\vmatcherSets\"\xee\x01\n" + - "\aMatcher\x121\n" + - "\x04type\x18\x01 \x01(\x0e2\x1d.eventrecorderpb.Matcher.TypeR\x04type\x12\x12\n" + - "\x04name\x18\x02 \x01(\tR\x04name\x12\x18\n" + - "\apattern\x18\x03 \x01(\tR\apattern\x12\x1a\n" + - "\brendered\x18\x04 \x01(\tR\brendered\"f\n" + - "\x04Type\x12\x14\n" + - "\x10TYPE_UNSPECIFIED\x10\x00\x12\x0e\n" + - "\n" + - "TYPE_EQUAL\x10\x01\x12\x0f\n" + - "\vTYPE_REGEXP\x10\x02\x12\x12\n" + - "\x0eTYPE_NOT_EQUAL\x10\x03\x12\x13\n" + - "\x0fTYPE_NOT_REGEXP\x10\x04\"B\n" + - "\n" + - "MatcherSet\x124\n" + - "\bmatchers\x18\x01 \x03(\v2\x18.eventrecorderpb.MatcherR\bmatchers\"I\n" + - "\x13SilenceCreatedEvent\x122\n" + - "\asilence\x18\x01 \x01(\v2\x18.eventrecorderpb.SilenceR\asilence\"I\n" + - "\x13SilenceUpdatedEvent\x122\n" + - "\asilence\x18\x01 \x01(\v2\x18.eventrecorderpb.SilenceR\asilence\"a\n" + - "\n" + - "MutedAlert\x121\n" + - "\x06labels\x18\x01 \x01(\v2\x19.eventrecorderpb.LabelSetR\x06labels\x12 \n" + - "\vfingerprint\x18\x02 \x01(\x04R\vfingerprint\"\x8a\x01\n" + - "\x16SilenceMutedAlertEvent\x122\n" + - "\asilence\x18\x01 \x01(\v2\x18.eventrecorderpb.SilenceR\asilence\x12<\n" + - "\vmuted_alert\x18\x02 \x01(\v2\x1b.eventrecorderpb.MutedAlertR\n" + - "mutedAlert\"\xca\x01\n" + - "\vInhibitRule\x12A\n" + - "\x0fsource_matchers\x18\x01 \x03(\v2\x18.eventrecorderpb.MatcherR\x0esourceMatchers\x12A\n" + - "\x0ftarget_matchers\x18\x02 \x03(\v2\x18.eventrecorderpb.MatcherR\x0etargetMatchers\x12!\n" + - "\fequal_labels\x18\x03 \x03(\tR\vequalLabels\x12\x12\n" + - "\x04name\x18\x04 \x01(\tR\x04name\"\xd5\x01\n" + - "\x19InhibitionMutedAlertEvent\x12A\n" + - "\rinhibit_rules\x18\x01 \x03(\v2\x1c.eventrecorderpb.InhibitRuleR\finhibitRules\x12<\n" + - "\vmuted_alert\x18\x02 \x01(\v2\x1b.eventrecorderpb.MutedAlertR\n" + - "mutedAlert\x127\n" + - "\x17inhibiting_fingerprints\x18\x03 \x03(\x04R\x16inhibitingFingerprints*\xf3\x01\n" + - "\fNotifyReason\x12\x1d\n" + - "\x19NOTIFY_REASON_UNSPECIFIED\x10\x00\x12$\n" + - " NOTIFY_REASON_FIRST_NOTIFICATION\x10\x01\x12%\n" + - "!NOTIFY_REASON_NEW_ALERTS_IN_GROUP\x10\x02\x12%\n" + - "!NOTIFY_REASON_NEW_RESOLVED_ALERTS\x10\x03\x12%\n" + - "!NOTIFY_REASON_ALL_ALERTS_RESOLVED\x10\x04\x12)\n" + - "%NOTIFY_REASON_REPEAT_INTERVAL_ELAPSED\x10\x05BBZ@github.com/prometheus/alertmanager/eventrecorder/eventrecorderpbb\x06proto3" - -var ( - file_eventrecorder_proto_rawDescOnce sync.Once - file_eventrecorder_proto_rawDescData []byte -) - -func file_eventrecorder_proto_rawDescGZIP() []byte { - file_eventrecorder_proto_rawDescOnce.Do(func() { - file_eventrecorder_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_eventrecorder_proto_rawDesc), len(file_eventrecorder_proto_rawDesc))) - }) - return file_eventrecorder_proto_rawDescData -} - -var file_eventrecorder_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_eventrecorder_proto_msgTypes = make([]protoimpl.MessageInfo, 23) -var file_eventrecorder_proto_goTypes = []any{ - (NotifyReason)(0), // 0: eventrecorderpb.NotifyReason - (Matcher_Type)(0), // 1: eventrecorderpb.Matcher.Type - (*Event)(nil), // 2: eventrecorderpb.Event - (*EventData)(nil), // 3: eventrecorderpb.EventData - (*AlertmanagerStartupEvent)(nil), // 4: eventrecorderpb.AlertmanagerStartupEvent - (*AlertmanagerShutdownEvent)(nil), // 5: eventrecorderpb.AlertmanagerShutdownEvent - (*LabelPair)(nil), // 6: eventrecorderpb.LabelPair - (*LabelSet)(nil), // 7: eventrecorderpb.LabelSet - (*Alert)(nil), // 8: eventrecorderpb.Alert - (*GroupedAlert)(nil), // 9: eventrecorderpb.GroupedAlert - (*AlertGroupInfo)(nil), // 10: eventrecorderpb.AlertGroupInfo - (*AlertCreatedEvent)(nil), // 11: eventrecorderpb.AlertCreatedEvent - (*AlertResolvedEvent)(nil), // 12: eventrecorderpb.AlertResolvedEvent - (*AlertGroupedEvent)(nil), // 13: eventrecorderpb.AlertGroupedEvent - (*Integration)(nil), // 14: eventrecorderpb.Integration - (*NotificationEvent)(nil), // 15: eventrecorderpb.NotificationEvent - (*Silence)(nil), // 16: eventrecorderpb.Silence - (*Matcher)(nil), // 17: eventrecorderpb.Matcher - (*MatcherSet)(nil), // 18: eventrecorderpb.MatcherSet - (*SilenceCreatedEvent)(nil), // 19: eventrecorderpb.SilenceCreatedEvent - (*SilenceUpdatedEvent)(nil), // 20: eventrecorderpb.SilenceUpdatedEvent - (*MutedAlert)(nil), // 21: eventrecorderpb.MutedAlert - (*SilenceMutedAlertEvent)(nil), // 22: eventrecorderpb.SilenceMutedAlertEvent - (*InhibitRule)(nil), // 23: eventrecorderpb.InhibitRule - (*InhibitionMutedAlertEvent)(nil), // 24: eventrecorderpb.InhibitionMutedAlertEvent - (*timestamppb.Timestamp)(nil), // 25: google.protobuf.Timestamp - (*durationpb.Duration)(nil), // 26: google.protobuf.Duration -} -var file_eventrecorder_proto_depIdxs = []int32{ - 25, // 0: eventrecorderpb.Event.timestamp:type_name -> google.protobuf.Timestamp - 3, // 1: eventrecorderpb.Event.data:type_name -> eventrecorderpb.EventData - 4, // 2: eventrecorderpb.EventData.alertmanager_startup_event:type_name -> eventrecorderpb.AlertmanagerStartupEvent - 5, // 3: eventrecorderpb.EventData.alertmanager_shutdown_event:type_name -> eventrecorderpb.AlertmanagerShutdownEvent - 11, // 4: eventrecorderpb.EventData.alert_created:type_name -> eventrecorderpb.AlertCreatedEvent - 12, // 5: eventrecorderpb.EventData.alert_resolved:type_name -> eventrecorderpb.AlertResolvedEvent - 13, // 6: eventrecorderpb.EventData.alert_grouped:type_name -> eventrecorderpb.AlertGroupedEvent - 15, // 7: eventrecorderpb.EventData.notification:type_name -> eventrecorderpb.NotificationEvent - 19, // 8: eventrecorderpb.EventData.silence_created:type_name -> eventrecorderpb.SilenceCreatedEvent - 20, // 9: eventrecorderpb.EventData.silence_updated:type_name -> eventrecorderpb.SilenceUpdatedEvent - 22, // 10: eventrecorderpb.EventData.silence_muted_alert:type_name -> eventrecorderpb.SilenceMutedAlertEvent - 24, // 11: eventrecorderpb.EventData.inhibition_muted_alert:type_name -> eventrecorderpb.InhibitionMutedAlertEvent - 6, // 12: eventrecorderpb.LabelSet.labels:type_name -> eventrecorderpb.LabelPair - 7, // 13: eventrecorderpb.Alert.labels:type_name -> eventrecorderpb.LabelSet - 7, // 14: eventrecorderpb.Alert.annotations:type_name -> eventrecorderpb.LabelSet - 25, // 15: eventrecorderpb.Alert.starts_at:type_name -> google.protobuf.Timestamp - 25, // 16: eventrecorderpb.Alert.ends_at:type_name -> google.protobuf.Timestamp - 8, // 17: eventrecorderpb.GroupedAlert.details:type_name -> eventrecorderpb.Alert - 7, // 18: eventrecorderpb.AlertGroupInfo.group_labels:type_name -> eventrecorderpb.LabelSet - 17, // 19: eventrecorderpb.AlertGroupInfo.matchers:type_name -> eventrecorderpb.Matcher - 8, // 20: eventrecorderpb.AlertCreatedEvent.alert:type_name -> eventrecorderpb.Alert - 9, // 21: eventrecorderpb.AlertResolvedEvent.alert:type_name -> eventrecorderpb.GroupedAlert - 10, // 22: eventrecorderpb.AlertResolvedEvent.group_info:type_name -> eventrecorderpb.AlertGroupInfo - 9, // 23: eventrecorderpb.AlertGroupedEvent.alert:type_name -> eventrecorderpb.GroupedAlert - 10, // 24: eventrecorderpb.AlertGroupedEvent.group_info:type_name -> eventrecorderpb.AlertGroupInfo - 9, // 25: eventrecorderpb.NotificationEvent.alerts:type_name -> eventrecorderpb.GroupedAlert - 9, // 26: eventrecorderpb.NotificationEvent.firing_alerts:type_name -> eventrecorderpb.GroupedAlert - 9, // 27: eventrecorderpb.NotificationEvent.resolved_alerts:type_name -> eventrecorderpb.GroupedAlert - 9, // 28: eventrecorderpb.NotificationEvent.muted_alerts:type_name -> eventrecorderpb.GroupedAlert - 10, // 29: eventrecorderpb.NotificationEvent.group_info:type_name -> eventrecorderpb.AlertGroupInfo - 26, // 30: eventrecorderpb.NotificationEvent.repeat_interval:type_name -> google.protobuf.Duration - 0, // 31: eventrecorderpb.NotificationEvent.reason:type_name -> eventrecorderpb.NotifyReason - 14, // 32: eventrecorderpb.NotificationEvent.integration:type_name -> eventrecorderpb.Integration - 17, // 33: eventrecorderpb.Silence.matchers:type_name -> eventrecorderpb.Matcher - 7, // 34: eventrecorderpb.Silence.annotations:type_name -> eventrecorderpb.LabelSet - 25, // 35: eventrecorderpb.Silence.starts_at:type_name -> google.protobuf.Timestamp - 25, // 36: eventrecorderpb.Silence.ends_at:type_name -> google.protobuf.Timestamp - 25, // 37: eventrecorderpb.Silence.updated_at:type_name -> google.protobuf.Timestamp - 18, // 38: eventrecorderpb.Silence.matcher_sets:type_name -> eventrecorderpb.MatcherSet - 1, // 39: eventrecorderpb.Matcher.type:type_name -> eventrecorderpb.Matcher.Type - 17, // 40: eventrecorderpb.MatcherSet.matchers:type_name -> eventrecorderpb.Matcher - 16, // 41: eventrecorderpb.SilenceCreatedEvent.silence:type_name -> eventrecorderpb.Silence - 16, // 42: eventrecorderpb.SilenceUpdatedEvent.silence:type_name -> eventrecorderpb.Silence - 7, // 43: eventrecorderpb.MutedAlert.labels:type_name -> eventrecorderpb.LabelSet - 16, // 44: eventrecorderpb.SilenceMutedAlertEvent.silence:type_name -> eventrecorderpb.Silence - 21, // 45: eventrecorderpb.SilenceMutedAlertEvent.muted_alert:type_name -> eventrecorderpb.MutedAlert - 17, // 46: eventrecorderpb.InhibitRule.source_matchers:type_name -> eventrecorderpb.Matcher - 17, // 47: eventrecorderpb.InhibitRule.target_matchers:type_name -> eventrecorderpb.Matcher - 23, // 48: eventrecorderpb.InhibitionMutedAlertEvent.inhibit_rules:type_name -> eventrecorderpb.InhibitRule - 21, // 49: eventrecorderpb.InhibitionMutedAlertEvent.muted_alert:type_name -> eventrecorderpb.MutedAlert - 50, // [50:50] is the sub-list for method output_type - 50, // [50:50] is the sub-list for method input_type - 50, // [50:50] is the sub-list for extension type_name - 50, // [50:50] is the sub-list for extension extendee - 0, // [0:50] is the sub-list for field type_name -} - -func init() { file_eventrecorder_proto_init() } -func file_eventrecorder_proto_init() { - if File_eventrecorder_proto != nil { - return - } - file_eventrecorder_proto_msgTypes[1].OneofWrappers = []any{ - (*EventData_AlertmanagerStartupEvent)(nil), - (*EventData_AlertmanagerShutdownEvent)(nil), - (*EventData_AlertCreated)(nil), - (*EventData_AlertResolved)(nil), - (*EventData_AlertGrouped)(nil), - (*EventData_Notification)(nil), - (*EventData_SilenceCreated)(nil), - (*EventData_SilenceUpdated)(nil), - (*EventData_SilenceMutedAlert)(nil), - (*EventData_InhibitionMutedAlert)(nil), - } - file_eventrecorder_proto_msgTypes[7].OneofWrappers = []any{} - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_eventrecorder_proto_rawDesc), len(file_eventrecorder_proto_rawDesc)), - NumEnums: 2, - NumMessages: 23, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_eventrecorder_proto_goTypes, - DependencyIndexes: file_eventrecorder_proto_depIdxs, - EnumInfos: file_eventrecorder_proto_enumTypes, - MessageInfos: file_eventrecorder_proto_msgTypes, - }.Build() - File_eventrecorder_proto = out.File - file_eventrecorder_proto_goTypes = nil - file_eventrecorder_proto_depIdxs = nil -} diff --git a/eventrecorder/eventrecorderpb/eventrecorder.proto b/eventrecorder/eventrecorderpb/eventrecorder.proto deleted file mode 100644 index 3de19298cd..0000000000 --- a/eventrecorder/eventrecorderpb/eventrecorder.proto +++ /dev/null @@ -1,392 +0,0 @@ -syntax = "proto3"; - -package eventrecorderpb; - -import "google/protobuf/duration.proto"; -import "google/protobuf/timestamp.proto"; - -option go_package = "github.com/prometheus/alertmanager/eventrecorder/eventrecorderpb"; - -// Event is the top-level envelope written to each event recorder output. -// It wraps the specific event data with metadata about when and where -// the event was produced. -message Event { - // The wall-clock time at which the event was recorded. - google.protobuf.Timestamp timestamp = 1 [json_name = "@timestamp"]; - - // The hostname or address of the Alertmanager instance that produced - // the event. - string instance = 2; - - // The event payload. Exactly one of the oneof fields inside EventData - // will be set. - EventData data = 3; - - // The ordinal position of this instance among its HA cluster peers. - // Zero when clustering is disabled. - uint32 cluster_position = 4; -} - -// EventData carries the payload for a single event recorder entry. -// Exactly one of the oneof fields will be populated. -message EventData { - oneof event_type { - // Recorded when the Alertmanager process starts. - AlertmanagerStartupEvent alertmanager_startup_event = 1; - - // Recorded when the Alertmanager process shuts down gracefully. - AlertmanagerShutdownEvent alertmanager_shutdown_event = 2; - - // Recorded when a new alert is first inserted into the alert store. - AlertCreatedEvent alert_created = 3; - - // Recorded when an alert transitions to the resolved state and is - // removed from its aggregation group after successful notification. - AlertResolvedEvent alert_resolved = 4; - - // Recorded when an alert is inserted into an aggregation group for - // the first time. - AlertGroupedEvent alert_grouped = 5; - - // Recorded after a notification is successfully delivered to an - // integration (e.g., webhook, email, PagerDuty). - NotificationEvent notification = 6; - - // Recorded when a new silence is created. - SilenceCreatedEvent silence_created = 7; - - // Recorded when an existing silence is updated (e.g., extended or - // re-commented). - SilenceUpdatedEvent silence_updated = 8; - - // Recorded each time a silence actively suppresses an alert during - // the muting evaluation pass. - SilenceMutedAlertEvent silence_muted_alert = 9; - - // Recorded each time one or more inhibition rules suppress an alert - // during the muting evaluation pass. - InhibitionMutedAlertEvent inhibition_muted_alert = 10; - } -} - -// AlertmanagerStartupEvent is emitted once when the process starts. -message AlertmanagerStartupEvent { - // The semantic version of the Alertmanager binary (e.g., "0.28.0"). - string version = 1; - - // Free-form build metadata such as Go version, branch, and revision. - string build_context = 2; -} - -// AlertmanagerShutdownEvent is emitted when the process shuts down -// gracefully. It carries no additional data. -message AlertmanagerShutdownEvent {} - -// LabelPair is a single key-value label. -message LabelPair { - // The label name (e.g., "alertname"). - string key = 1; - - // The label value (e.g., "HighMemoryUsage"). - string value = 2; -} - -// LabelSet is an ordered collection of label pairs. -message LabelSet { - // The label pairs that make up this set. - repeated LabelPair labels = 1; -} - -// Alert represents a snapshot of an alert at the time the event was -// recorded. -message Alert { - // The unique fingerprint derived from the alert's label set. - uint64 fingerprint = 1; - - // The value of the "alertname" label, provided for convenience. - string name = 2; - - // The full label set that identifies this alert. - LabelSet labels = 3; - - // Informational annotations attached to the alert (e.g., summary, - // description). - LabelSet annotations = 4; - - // The time at which the alert started firing. - google.protobuf.Timestamp starts_at = 5; - - // The time at which the alert is considered resolved. For firing - // alerts this is typically set to a time in the future. - google.protobuf.Timestamp ends_at = 6; - - // Whether the alert was resolved at the time the event was recorded. - bool resolved = 7; -} - -// GroupedAlert is a reference to an alert within an aggregation group. -// It always carries the content hash; the full alert details are -// included when available. -message GroupedAlert { - // A hash of the alert's label set, used for deduplication within the - // notification pipeline. - uint64 hash = 1; - - // The full alert details. May be absent when only the hash is needed - // (e.g., in firing/resolved lists on NotificationEvent). - optional Alert details = 2; -} - -// AlertGroupInfo describes the aggregation group context in which an -// alert is being processed. -message AlertGroupInfo { - // The composite key that uniquely identifies this aggregation group - // (encodes route and group label values). - string group_key = 1; - - // The label set used to group alerts together within this route. - LabelSet group_labels = 2; - - // A stable, shortened identifier derived from the group key (SHA-256 - // hex). - string group_id = 3; - - // The name of the receiver that this group routes to. - string receiver_name = 4; - - // The set of matchers defined on the route that matched these alerts. - repeated Matcher matchers = 5; - - // A UUID that uniquely identifies this aggregation group instance. - string group_uuid = 6; -} - -// AlertCreatedEvent is emitted when a brand-new alert is inserted into -// the in-memory alert store. -message AlertCreatedEvent { - // The newly created alert. - Alert alert = 1; -} - -// AlertResolvedEvent is emitted when an alert is removed from its -// aggregation group after a successful notification that included the -// resolution. -message AlertResolvedEvent { - // The resolved alert, including its hash and full details. - GroupedAlert alert = 1; - - // The aggregation group from which the alert was resolved. - AlertGroupInfo group_info = 2; -} - -// AlertGroupedEvent is emitted the first time an alert is inserted into -// an aggregation group. -message AlertGroupedEvent { - // The alert being grouped, including its hash and full details. - GroupedAlert alert = 1; - - // The aggregation group the alert was added to. - AlertGroupInfo group_info = 2; -} - -// NotifyReason describes why a notification was sent for an aggregation -// group. -enum NotifyReason { - // Default / unknown reason. - NOTIFY_REASON_UNSPECIFIED = 0; - - // The group has never been notified before and contains at least one - // firing alert. - NOTIFY_REASON_FIRST_NOTIFICATION = 1; - - // New firing alerts have been added to the group since the last - // notification. - NOTIFY_REASON_NEW_ALERTS_IN_GROUP = 2; - - // Some alerts in the group have resolved since the last notification. - NOTIFY_REASON_NEW_RESOLVED_ALERTS = 3; - - // All alerts in the group have resolved. - NOTIFY_REASON_ALL_ALERTS_RESOLVED = 4; - - // The configured repeat interval has elapsed since the last - // notification. - NOTIFY_REASON_REPEAT_INTERVAL_ELAPSED = 5; -} - -// Integration identifies a specific notification integration (e.g., -// the second PagerDuty receiver in a receiver definition). -message Integration { - // The type of the integration (e.g., "webhook", "pagerduty"). - string name = 1; - - // The zero-based index of this integration within its receiver. - int64 index = 2; -} - -// NotificationEvent is emitted after a notification is successfully -// delivered to an integration. -message NotificationEvent { - // All alerts that were included in the notification. - repeated GroupedAlert alerts = 1; - - // The subset of alerts that are currently firing. - repeated GroupedAlert firing_alerts = 2; - - // The subset of alerts that are resolved. - repeated GroupedAlert resolved_alerts = 3; - - // Alerts that were muted (silenced or inhibited) during this flush - // cycle. - repeated GroupedAlert muted_alerts = 4; - - // The aggregation group context for this notification. - AlertGroupInfo group_info = 5; - - // The configured repeat interval for the aggregation group's route. - google.protobuf.Duration repeat_interval = 6; - - // The reason the notification was triggered. - NotifyReason reason = 7; - - // A monotonically increasing identifier for each flush cycle of the - // aggregation group. - uint64 flush_id = 8; - - // The integration that delivered the notification. - Integration integration = 9; -} - -// Silence is a snapshot of a silence definition at the time the event -// was recorded. -message Silence { - // The globally unique silence identifier (UUID). - string id = 1; - - // The matchers that define which alerts this silence suppresses. - // For silences with multiple matcher sets, this is the first set. - repeated Matcher matchers = 2; - - // Optional structured annotations on the silence (key-value pairs). - LabelSet annotations = 3; - - // The time at which the silence becomes active. - google.protobuf.Timestamp starts_at = 4; - - // The time at which the silence expires. - google.protobuf.Timestamp ends_at = 5; - - // The last time the silence was created or updated. - google.protobuf.Timestamp updated_at = 6; - - // The author who created the silence. - string created_by = 7; - - // A human-readable comment explaining the silence. - string comment = 8; - - // Additional matcher sets evaluated with OR logic. At least one - // matcher set must match for the silence to apply. - repeated MatcherSet matcher_sets = 9; -} - -// Matcher defines a single label matching rule. -message Matcher { - // Type enumerates the supported matching operators. - enum Type { - // Unspecified / unknown match type. - TYPE_UNSPECIFIED = 0; - - // Exact string equality (=). - TYPE_EQUAL = 1; - - // Regular expression match (=~). - TYPE_REGEXP = 2; - - // Negated exact string equality (!=). - TYPE_NOT_EQUAL = 3; - - // Negated regular expression match (!~). - TYPE_NOT_REGEXP = 4; - } - - // The matching operator to apply. - Type type = 1; - - // The label name to match against. - string name = 2; - - // The value or pattern to match, interpreted according to type. - string pattern = 3; - - // Human-readable string representation (e.g., "env=~prod.*"). - string rendered = 4; -} - -// MatcherSet is a conjunction of matchers: all matchers in the set must -// match for the set to match. -message MatcherSet { - // The matchers that make up this set (evaluated with AND logic). - repeated Matcher matchers = 1; -} - -// SilenceCreatedEvent is emitted when a new silence is created. -message SilenceCreatedEvent { - // The newly created silence. - Silence silence = 1; -} - -// SilenceUpdatedEvent is emitted when an existing silence is modified. -message SilenceUpdatedEvent { - // The silence after the update. - Silence silence = 1; -} - -// MutedAlert identifies an alert that was suppressed by a silence or -// inhibition rule. -message MutedAlert { - // The label set of the muted alert. - LabelSet labels = 1; - - // The fingerprint of the muted alert. - uint64 fingerprint = 2; -} - -// SilenceMutedAlertEvent is emitted each time a silence suppresses an -// alert during the muting evaluation pass. -message SilenceMutedAlertEvent { - // The silence that suppressed the alert. - Silence silence = 1; - - // The alert that was suppressed. - MutedAlert muted_alert = 2; -} - -// InhibitRule is a snapshot of an inhibition rule definition. -message InhibitRule { - // Matchers that identify source alerts (those that do the inhibiting). - repeated Matcher source_matchers = 1; - - // Matchers that identify target alerts (those that get inhibited). - repeated Matcher target_matchers = 2; - - // Label names whose values must be equal between source and target - // alerts for the inhibition to take effect. - repeated string equal_labels = 3; - - // Name is the optional name of the inhibition rule. - string name = 4; -} - -// InhibitionMutedAlertEvent is emitted when one or more inhibition -// rules suppress an alert. -message InhibitionMutedAlertEvent { - // The inhibition rules that matched. - repeated InhibitRule inhibit_rules = 1; - - // The alert that was suppressed. - MutedAlert muted_alert = 2; - - // The fingerprints of the source alerts that caused the inhibition. - repeated uint64 inhibiting_fingerprints = 3; -} diff --git a/eventrecorder/events.go b/eventrecorder/events.go index 4b5e5d5891..929cade8eb 100644 --- a/eventrecorder/events.go +++ b/eventrecorder/events.go @@ -11,282 +11,402 @@ // See the License for the specific language governing permissions and // limitations under the License. -// This file contains pure-functional helpers that convert internal -// Alertmanager types into eventrecorderpb messages, plus convenience -// constructors for the EventData oneof variants. None of these -// functions touch the Recorder; they are imported and called by the -// dispatch, silence, inhibit, and provider packages to build event -// payloads that are then handed to Recorder.RecordEvent. - package eventrecorder import ( + "maps" "slices" - "strings" + "time" "github.com/prometheus/common/model" + "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/durationpb" "google.golang.org/protobuf/types/known/timestamppb" - "github.com/prometheus/alertmanager/eventrecorder/eventrecorderpb" + "github.com/prometheus/alertmanager/alert" + events "github.com/prometheus/alertmanager/eventrecorder/events/v2" "github.com/prometheus/alertmanager/pkg/labels" silencepb "github.com/prometheus/alertmanager/silence/silencepb" - "github.com/prometheus/alertmanager/types" ) -// LabelSetAsProto converts a model.LabelSet to an eventrecorderpb.LabelSet. -// Labels are sorted by name for deterministic output. -func LabelSetAsProto(ls model.LabelSet) *eventrecorderpb.LabelSet { - names := make([]model.LabelName, 0, len(ls)) - for k := range ls { - names = append(names, k) +// EventData is an immutable event recorder payload without envelope metadata. +// Its protobuf representation is private so producers cannot construct invalid +// output events. +type EventData struct { + message *events.EventData + eventType string +} + +// Event is an immutable event recorder output with envelope metadata. Its +// protobuf representation is private so destinations cannot be passed arbitrary +// protobuf messages. +type Event struct { + message *events.Event + eventType string +} + +// MarshalJSON serializes the event using its protobuf schema. +func (e Event) MarshalJSON() ([]byte, error) { + return protojson.Marshal(e.message) +} + +// MarshalProtobuf serializes the event using its protobuf schema. +func (e Event) MarshalProtobuf() ([]byte, error) { + return proto.Marshal(e.message) +} + +func (d EventData) typeName() string { + return eventTypeName(d.eventType) +} + +func (e Event) typeName() string { + return eventTypeName(e.eventType) +} + +func eventTypeName(eventType string) string { + if eventType == "" { + return "unknown" } - slices.SortFunc(names, func(a, b model.LabelName) int { - return strings.Compare(string(a), string(b)) - }) - pairs := make([]*eventrecorderpb.LabelPair, 0, len(ls)) - for _, k := range names { - pairs = append(pairs, &eventrecorderpb.LabelPair{Key: string(k), Value: string(ls[k])}) + return eventType +} + +func (e Event) protoMessage() proto.Message { + return e.message +} + +func (d EventData) withMetadata(timestamp *timestamppb.Timestamp, instance string, clusterPosition uint64) Event { + return Event{ + message: &events.Event{ + Timestamp: timestamp, Instance: instance, Data: d.message, ClusterPosition: clusterPosition, + }, + eventType: d.eventType, } - return &eventrecorderpb.LabelSet{Labels: pairs} -} - -// AlertAsProto converts a types.Alert to an eventrecorderpb.Alert. -func AlertAsProto(alert *types.Alert) *eventrecorderpb.Alert { - return &eventrecorderpb.Alert{ - Fingerprint: uint64(alert.Fingerprint()), - Name: alert.Name(), - Labels: LabelSetAsProto(alert.Labels), - Annotations: LabelSetAsProto(alert.Annotations), - StartsAt: timestamppb.New(alert.StartsAt), - EndsAt: timestamppb.New(alert.EndsAt), - Resolved: alert.Resolved(), +} + +// AlertGroup is an immutable aggregation-group snapshot. +type AlertGroup struct { + message *events.AlertGroupInfo +} + +// GroupedAlert is an immutable grouped-alert snapshot. +type GroupedAlert struct { + message *events.GroupedAlert +} + +// InhibitRule is an immutable inhibition-rule snapshot. +type InhibitRule struct { + message *events.InhibitRule +} + +// NotificationReason describes why a notification was sent. +type NotificationReason int + +const ( + NotificationReasonUnspecified NotificationReason = iota + NotificationReasonFirstNotification + NotificationReasonNewAlertsInGroup + NotificationReasonNewResolvedAlerts + NotificationReasonAllAlertsResolved + NotificationReasonRepeatIntervalElapsed +) + +// Notification contains the snapshots used to construct a notification event. +type Notification struct { + Alerts []GroupedAlert + FiringAlerts []GroupedAlert + ResolvedAlerts []GroupedAlert + MutedAlerts []GroupedAlert + Group AlertGroup + RepeatInterval time.Duration + Reason NotificationReason + FlushID uint64 + Integration string + IntegrationIdx int64 +} + +// NewAlertGroup snapshots aggregation-group metadata. +func NewAlertGroup(groupKey string, groupLabels model.LabelSet, groupID, receiverName string, matchers labels.Matchers, groupUUID string) AlertGroup { + return AlertGroup{message: &events.AlertGroupInfo{ + GroupKey: groupKey, GroupLabels: labelSetMap(groupLabels), GroupId: groupID, + ReceiverName: receiverName, Matchers: matchersToEvents(matchers), GroupUuid: groupUUID, + }} +} + +// NewGroupedAlert snapshots an alert and its notification-pipeline hash. +func NewGroupedAlert(hash uint64, a *alert.Alert) GroupedAlert { + return GroupedAlert{message: &events.GroupedAlert{Hash: hash, Details: alertToEvents(a)}} +} + +// NewGroupedAlertReference snapshots a hash-only grouped-alert reference. +func NewGroupedAlertReference(hash uint64) GroupedAlert { + return GroupedAlert{message: &events.GroupedAlert{Hash: hash}} +} + +// NewAlertmanagerStartupEvent constructs startup event data. +func NewAlertmanagerStartupEvent(version, buildContext string) EventData { + return newEventData("alertmanager_startup_event", &events.EventData{EventType: &events.EventData_AlertmanagerStartupEvent{ + AlertmanagerStartupEvent: &events.AlertmanagerStartupEvent{Version: version, BuildContext: buildContext}, + }}) +} + +// NewAlertmanagerShutdownEvent constructs shutdown event data. +func NewAlertmanagerShutdownEvent() EventData { + return newEventData("alertmanager_shutdown_event", &events.EventData{EventType: &events.EventData_AlertmanagerShutdownEvent{ + AlertmanagerShutdownEvent: &events.AlertmanagerShutdownEvent{}, + }}) +} + +// NewAlertCreatedEvent constructs alert-created event data. +func NewAlertCreatedEvent(a *alert.Alert) EventData { + return newEventData("alert_created", &events.EventData{EventType: &events.EventData_AlertCreated{ + AlertCreated: &events.AlertCreatedEvent{Alert: alertToEvents(a)}, + }}) +} + +// NewAlertGroupedEvent constructs alert-grouped event data. +func NewAlertGroupedEvent(group AlertGroup, groupedAlert GroupedAlert) EventData { + return newEventData("alert_grouped", &events.EventData{EventType: &events.EventData_AlertGrouped{ + AlertGrouped: &events.AlertGroupedEvent{Alert: groupedAlert.message, GroupInfo: group.message}, + }}) +} + +// NewAlertResolvedEvent constructs alert-resolved event data. +func NewAlertResolvedEvent(group AlertGroup, groupedAlert GroupedAlert) EventData { + return newEventData("alert_resolved", &events.EventData{EventType: &events.EventData_AlertResolved{ + AlertResolved: &events.AlertResolvedEvent{Alert: groupedAlert.message, GroupInfo: group.message}, + }}) +} + +// NewNotificationEvent constructs notification event data. +func NewNotificationEvent(notification Notification) EventData { + return newEventData("notification", &events.EventData{EventType: &events.EventData_Notification{ + Notification: &events.NotificationEvent{ + Alerts: groupedAlertsToEvents(notification.Alerts), FiringAlerts: groupedAlertsToEvents(notification.FiringAlerts), + ResolvedAlerts: groupedAlertsToEvents(notification.ResolvedAlerts), MutedAlerts: groupedAlertsToEvents(notification.MutedAlerts), + GroupInfo: notification.Group.message, RepeatInterval: durationpb.New(notification.RepeatInterval), + Reason: notificationReasonToEvents(notification.Reason), FlushId: notification.FlushID, + Integration: &events.Integration{Name: notification.Integration, Index: notification.IntegrationIdx}, + }, + }}) +} + +// NewSilenceMutedAlertEvent constructs silence-muted-alert event data. +func NewSilenceMutedAlertEvent(silence *silencepb.Silence, fp model.Fingerprint, labelSet model.LabelSet) EventData { + return newEventData("silence_muted_alert", &events.EventData{EventType: &events.EventData_SilenceMutedAlert{ + SilenceMutedAlert: &events.SilenceMutedAlertEvent{Silence: silenceToEvents(silence), MutedAlert: &events.MutedAlert{ + Fingerprint: uint64(fp), Labels: labelSetMap(labelSet), + }}, + }}) +} + +// NewSilenceCreatedEvent constructs silence-created event data. +func NewSilenceCreatedEvent(silence *silencepb.Silence) EventData { + return newEventData("silence_created", &events.EventData{EventType: &events.EventData_SilenceCreated{ + SilenceCreated: &events.SilenceCreatedEvent{Silence: silenceToEvents(silence)}, + }}) +} + +// NewSilenceUpdatedEvent constructs silence-updated event data. +func NewSilenceUpdatedEvent(silence *silencepb.Silence) EventData { + return newEventData("silence_updated", &events.EventData{EventType: &events.EventData_SilenceUpdated{ + SilenceUpdated: &events.SilenceUpdatedEvent{Silence: silenceToEvents(silence)}, + }}) +} + +// NewInhibitRule snapshots an inhibition rule. +func NewInhibitRule(name string, sourceMatchers, targetMatchers labels.Matchers, equal map[model.LabelName]struct{}) InhibitRule { + equalLabels := make([]string, 0, len(equal)) + for label := range equal { + equalLabels = append(equalLabels, string(label)) } + slices.Sort(equalLabels) + return InhibitRule{message: &events.InhibitRule{ + Name: name, SourceMatchers: matchersToEvents(sourceMatchers), TargetMatchers: matchersToEvents(targetMatchers), EqualLabels: equalLabels, + }} } -// MatcherAsProto converts a single *labels.Matcher to its protobuf -// representation. -func MatcherAsProto(m *labels.Matcher) *eventrecorderpb.Matcher { - var matcherType eventrecorderpb.Matcher_Type - switch m.Type { - case labels.MatchEqual: - matcherType = eventrecorderpb.Matcher_TYPE_EQUAL - case labels.MatchNotEqual: - matcherType = eventrecorderpb.Matcher_TYPE_NOT_EQUAL - case labels.MatchRegexp: - matcherType = eventrecorderpb.Matcher_TYPE_REGEXP - case labels.MatchNotRegexp: - matcherType = eventrecorderpb.Matcher_TYPE_NOT_REGEXP - default: - matcherType = eventrecorderpb.Matcher_TYPE_UNSPECIFIED +// NewInhibitionMutedAlertEvent constructs inhibition-muted-alert event data. +func NewInhibitionMutedAlertEvent(rules []InhibitRule, fp model.Fingerprint, labelSet model.LabelSet, inhibitingFPs []model.Fingerprint) EventData { + fps := make([]uint64, len(inhibitingFPs)) + for i, fingerprint := range inhibitingFPs { + fps[i] = uint64(fingerprint) } - return &eventrecorderpb.Matcher{ - Type: matcherType, - Name: m.Name, - Pattern: m.Value, - Rendered: m.String(), + eventRules := make([]*events.InhibitRule, len(rules)) + for i, rule := range rules { + eventRules[i] = rule.message } + return newEventData("inhibition_muted_alert", &events.EventData{EventType: &events.EventData_InhibitionMutedAlert{ + InhibitionMutedAlert: &events.InhibitionMutedAlertEvent{ + InhibitRules: eventRules, MutedAlert: &events.MutedAlert{Fingerprint: uint64(fp), Labels: labelSetMap(labelSet)}, + InhibitingFingerprints: fps, + }, + }}) +} + +func newEventData(eventType string, message *events.EventData) EventData { + return EventData{message: message, eventType: eventType} } -// MatchersAsProto converts a slice of matchers to their protobuf -// representations. -func MatchersAsProto(matchers labels.Matchers) []*eventrecorderpb.Matcher { - result := make([]*eventrecorderpb.Matcher, len(matchers)) - for i, m := range matchers { - result[i] = MatcherAsProto(m) +func labelSetMap(labelSet model.LabelSet) map[string]string { + result := make(map[string]string, len(labelSet)) + for name, value := range labelSet { + result[string(name)] = string(value) } return result } -// SilenceMatcherAsProto converts a silencepb.Matcher to an -// eventrecorderpb.Matcher. -func SilenceMatcherAsProto(m *silencepb.Matcher) *eventrecorderpb.Matcher { - var matcherType eventrecorderpb.Matcher_Type - switch m.Type { - case silencepb.Matcher_EQUAL: - matcherType = eventrecorderpb.Matcher_TYPE_EQUAL - case silencepb.Matcher_REGEXP: - matcherType = eventrecorderpb.Matcher_TYPE_REGEXP - case silencepb.Matcher_NOT_EQUAL: - matcherType = eventrecorderpb.Matcher_TYPE_NOT_EQUAL - case silencepb.Matcher_NOT_REGEXP: - matcherType = eventrecorderpb.Matcher_TYPE_NOT_REGEXP - default: - matcherType = eventrecorderpb.Matcher_TYPE_UNSPECIFIED +func stringMap(values map[string]string) map[string]string { + if len(values) == 0 { + return nil } + result := make(map[string]string, len(values)) + maps.Copy(result, values) + return result +} - var rendered string - var matchType labels.MatchType - switch m.Type { - case silencepb.Matcher_EQUAL: - matchType = labels.MatchEqual - case silencepb.Matcher_NOT_EQUAL: - matchType = labels.MatchNotEqual - case silencepb.Matcher_REGEXP: - matchType = labels.MatchRegexp - case silencepb.Matcher_NOT_REGEXP: - matchType = labels.MatchNotRegexp - default: - matchType = labels.MatchEqual +func alertToEvents(a *alert.Alert) *events.Alert { + if a == nil { + return nil } - if lm, err := labels.NewMatcher(matchType, m.Name, m.Pattern); err == nil { - rendered = lm.String() + return &events.Alert{ + Fingerprint: uint64(a.Fingerprint()), Name: a.Name(), Labels: labelSetMap(a.Labels), Annotations: labelSetMap(a.Annotations), + StartsAt: timestamppb.New(a.StartsAt), EndsAt: timestamppb.New(a.EndsAt), Resolved: a.Resolved(), } +} - return &eventrecorderpb.Matcher{ - Type: matcherType, - Name: m.Name, - Pattern: m.Pattern, - Rendered: rendered, +func matchersToEvents(matchers labels.Matchers) []*events.Matcher { + result := make([]*events.Matcher, 0, len(matchers)) + for _, matcher := range matchers { + if matcher == nil { + continue + } + result = append(result, &events.Matcher{Type: matcherTypeToEvents(matcher.Type), Name: matcher.Name, Pattern: matcher.Value, Rendered: matcher.String()}) } + return result } -// SilenceAsProto converts a silencepb.Silence to an -// eventrecorderpb.Silence. -func SilenceAsProto(sil *silencepb.Silence) *eventrecorderpb.Silence { - matcherSets := make([]*eventrecorderpb.MatcherSet, len(sil.MatcherSets)) - for i, ms := range sil.MatcherSets { - matcherSet := &eventrecorderpb.MatcherSet{ - Matchers: make([]*eventrecorderpb.Matcher, len(ms.Matchers)), - } - for j, m := range ms.Matchers { - matcherSet.Matchers[j] = SilenceMatcherAsProto(m) - } - matcherSets[i] = matcherSet +func matcherTypeToEvents(matcherType labels.MatchType) events.Matcher_Type { + switch matcherType { + case labels.MatchEqual: + return events.Matcher_TYPE_EQUAL + case labels.MatchNotEqual: + return events.Matcher_TYPE_NOT_EQUAL + case labels.MatchRegexp: + return events.Matcher_TYPE_REGEXP + case labels.MatchNotRegexp: + return events.Matcher_TYPE_NOT_REGEXP + default: + return events.Matcher_TYPE_UNSPECIFIED } +} - var matchers []*eventrecorderpb.Matcher - if len(matcherSets) > 0 { +func silenceToEvents(silence *silencepb.Silence) *events.Silence { + if silence == nil { + return nil + } + matcherSets := silenceMatcherSetsToEvents(silence.MatcherSets) + receiverMatcherSets := silenceMatcherSetsToEvents(silence.ReceiverMatcherSets) + matchers := silenceMatchersToEvents(silence.Matchers) + if len(matchers) == 0 && len(matcherSets) > 0 { matchers = matcherSets[0].Matchers } - - return &eventrecorderpb.Silence{ - Id: sil.Id, - Matchers: matchers, - MatcherSets: matcherSets, - StartsAt: sil.StartsAt, - EndsAt: sil.EndsAt, - UpdatedAt: sil.UpdatedAt, - CreatedBy: sil.CreatedBy, - Comment: sil.Comment, + return &events.Silence{ + Id: silence.Id, Matchers: matchers, Annotations: stringMap(silence.Annotations), StartsAt: cloneTimestamp(silence.StartsAt), + EndsAt: cloneTimestamp(silence.EndsAt), UpdatedAt: cloneTimestamp(silence.UpdatedAt), CreatedBy: silence.CreatedBy, + Comment: silence.Comment, MatcherSets: matcherSets, ReceiverMatcherSets: receiverMatcherSets, } } -// InhibitRuleAsProto converts inhibit rule fields to an -// eventrecorderpb.InhibitRule. It accepts the individual fields rather -// than the InhibitRule struct to avoid an import cycle. -func InhibitRuleAsProto(name string, sourceMatchers, targetMatchers labels.Matchers, equal map[model.LabelName]struct{}) *eventrecorderpb.InhibitRule { - equalLabels := make([]string, 0, len(equal)) - for label := range equal { - equalLabels = append(equalLabels, string(label)) - } - slices.Sort(equalLabels) - return &eventrecorderpb.InhibitRule{ - Name: name, - SourceMatchers: MatchersAsProto(sourceMatchers), - TargetMatchers: MatchersAsProto(targetMatchers), - EqualLabels: equalLabels, +func silenceMatcherSetsToEvents(sets []*silencepb.MatcherSet) []*events.MatcherSet { + result := make([]*events.MatcherSet, 0, len(sets)) + for _, set := range sets { + if set == nil { + continue + } + result = append(result, &events.MatcherSet{Matchers: silenceMatchersToEvents(set.Matchers)}) } + return result } -// NewAlertCreatedEvent constructs an AlertCreated event. -func NewAlertCreatedEvent(alert *types.Alert) *eventrecorderpb.EventData { - return &eventrecorderpb.EventData{ - EventType: &eventrecorderpb.EventData_AlertCreated{ - AlertCreated: &eventrecorderpb.AlertCreatedEvent{ - Alert: AlertAsProto(alert), - }, - }, +func silenceMatchersToEvents(matchers []*silencepb.Matcher) []*events.Matcher { + result := make([]*events.Matcher, 0, len(matchers)) + for _, matcher := range matchers { + if matcher == nil { + continue + } + result = append(result, silenceMatcherToEvents(matcher)) } + return result } -// NewSilenceMutedAlertEvent constructs a SilenceMutedAlert event. -func NewSilenceMutedAlertEvent(silence *eventrecorderpb.Silence, fp model.Fingerprint, lset model.LabelSet) *eventrecorderpb.EventData { - return &eventrecorderpb.EventData{ - EventType: &eventrecorderpb.EventData_SilenceMutedAlert{ - SilenceMutedAlert: &eventrecorderpb.SilenceMutedAlertEvent{ - Silence: silence, - MutedAlert: &eventrecorderpb.MutedAlert{ - Fingerprint: uint64(fp), - Labels: LabelSetAsProto(lset), - }, - }, - }, +func silenceMatcherToEvents(matcher *silencepb.Matcher) *events.Matcher { + if matcher == nil { + return nil + } + eventType := events.Matcher_TYPE_UNSPECIFIED + switch matcher.Type { + case silencepb.Matcher_EQUAL: + eventType = events.Matcher_TYPE_EQUAL + case silencepb.Matcher_REGEXP: + eventType = events.Matcher_TYPE_REGEXP + case silencepb.Matcher_NOT_EQUAL: + eventType = events.Matcher_TYPE_NOT_EQUAL + case silencepb.Matcher_NOT_REGEXP: + eventType = events.Matcher_TYPE_NOT_REGEXP } + return &events.Matcher{Type: eventType, Name: matcher.Name, Pattern: matcher.Pattern, Rendered: silenceMatcherRendered(matcher)} } -// NewSilenceCreatedEvent constructs a SilenceCreated event. -func NewSilenceCreatedEvent(silence *eventrecorderpb.Silence) *eventrecorderpb.EventData { - return &eventrecorderpb.EventData{ - EventType: &eventrecorderpb.EventData_SilenceCreated{ - SilenceCreated: &eventrecorderpb.SilenceCreatedEvent{ - Silence: silence, - }, - }, +func silenceMatcherRendered(matcher *silencepb.Matcher) string { + var matcherType labels.MatchType + switch matcher.Type { + case silencepb.Matcher_EQUAL: + matcherType = labels.MatchEqual + case silencepb.Matcher_REGEXP: + matcherType = labels.MatchRegexp + case silencepb.Matcher_NOT_EQUAL: + matcherType = labels.MatchNotEqual + case silencepb.Matcher_NOT_REGEXP: + matcherType = labels.MatchNotRegexp + default: + return "" } + rendered := "" + if parsed, err := labels.NewMatcher(matcherType, matcher.Name, matcher.Pattern); err == nil { + rendered = parsed.String() + } + return rendered } -// NewSilenceUpdatedEvent constructs a SilenceUpdated event. -func NewSilenceUpdatedEvent(silence *eventrecorderpb.Silence) *eventrecorderpb.EventData { - return &eventrecorderpb.EventData{ - EventType: &eventrecorderpb.EventData_SilenceUpdated{ - SilenceUpdated: &eventrecorderpb.SilenceUpdatedEvent{ - Silence: silence, - }, - }, +func cloneTimestamp(timestamp *timestamppb.Timestamp) *timestamppb.Timestamp { + if timestamp == nil { + return nil } + return timestamppb.New(timestamp.AsTime()) } -// NewInhibitionMutedAlertEvent constructs an InhibitionMutedAlert event. -func NewInhibitionMutedAlertEvent(rules []*eventrecorderpb.InhibitRule, fp model.Fingerprint, lset model.LabelSet, inhibitingFPs []model.Fingerprint) *eventrecorderpb.EventData { - fps := make([]uint64, len(inhibitingFPs)) - for i, f := range inhibitingFPs { - fps[i] = uint64(f) - } - return &eventrecorderpb.EventData{ - EventType: &eventrecorderpb.EventData_InhibitionMutedAlert{ - InhibitionMutedAlert: &eventrecorderpb.InhibitionMutedAlertEvent{ - InhibitRules: rules, - MutedAlert: &eventrecorderpb.MutedAlert{ - Fingerprint: uint64(fp), - Labels: LabelSetAsProto(lset), - }, - InhibitingFingerprints: fps, - }, - }, +func groupedAlertsToEvents(alerts []GroupedAlert) []*events.GroupedAlert { + result := make([]*events.GroupedAlert, len(alerts)) + for i, groupedAlert := range alerts { + result[i] = groupedAlert.message } + return result } -// extractEventType returns the proto oneof field name for the event -// type (e.g. "alert_created", "notification"). It uses a type switch -// on the generated oneof wrapper types, avoiding proto reflection. -// A nil input is reported as "unknown" so logging and metric paths -// stay panic-free. -func extractEventType(event *eventrecorderpb.EventData) string { - if event == nil { - return "unknown" - } - switch event.EventType.(type) { - case *eventrecorderpb.EventData_AlertmanagerStartupEvent: - return "alertmanager_startup_event" - case *eventrecorderpb.EventData_AlertmanagerShutdownEvent: - return "alertmanager_shutdown_event" - case *eventrecorderpb.EventData_AlertCreated: - return "alert_created" - case *eventrecorderpb.EventData_AlertResolved: - return "alert_resolved" - case *eventrecorderpb.EventData_AlertGrouped: - return "alert_grouped" - case *eventrecorderpb.EventData_Notification: - return "notification" - case *eventrecorderpb.EventData_SilenceCreated: - return "silence_created" - case *eventrecorderpb.EventData_SilenceUpdated: - return "silence_updated" - case *eventrecorderpb.EventData_SilenceMutedAlert: - return "silence_muted_alert" - case *eventrecorderpb.EventData_InhibitionMutedAlert: - return "inhibition_muted_alert" +func notificationReasonToEvents(reason NotificationReason) events.NotifyReason { + switch reason { + case NotificationReasonFirstNotification: + return events.NotifyReason_NOTIFY_REASON_FIRST_NOTIFICATION + case NotificationReasonNewAlertsInGroup: + return events.NotifyReason_NOTIFY_REASON_NEW_ALERTS_IN_GROUP + case NotificationReasonNewResolvedAlerts: + return events.NotifyReason_NOTIFY_REASON_NEW_RESOLVED_ALERTS + case NotificationReasonAllAlertsResolved: + return events.NotifyReason_NOTIFY_REASON_ALL_ALERTS_RESOLVED + case NotificationReasonRepeatIntervalElapsed: + return events.NotifyReason_NOTIFY_REASON_REPEAT_INTERVAL_ELAPSED default: - return "unknown" + return events.NotifyReason_NOTIFY_REASON_UNSPECIFIED } } diff --git a/eventrecorder/events/v2/events.pb.go b/eventrecorder/events/v2/events.pb.go new file mode 100644 index 0000000000..374d5776e2 --- /dev/null +++ b/eventrecorder/events/v2/events.pb.go @@ -0,0 +1,1899 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc (unknown) +// source: events/v2/events.proto + +package eventsv2 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + durationpb "google.golang.org/protobuf/types/known/durationpb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// NotifyReason describes why a notification was sent. +type NotifyReason int32 + +const ( + NotifyReason_NOTIFY_REASON_UNSPECIFIED NotifyReason = 0 + NotifyReason_NOTIFY_REASON_FIRST_NOTIFICATION NotifyReason = 1 + NotifyReason_NOTIFY_REASON_NEW_ALERTS_IN_GROUP NotifyReason = 2 + NotifyReason_NOTIFY_REASON_NEW_RESOLVED_ALERTS NotifyReason = 3 + NotifyReason_NOTIFY_REASON_ALL_ALERTS_RESOLVED NotifyReason = 4 + NotifyReason_NOTIFY_REASON_REPEAT_INTERVAL_ELAPSED NotifyReason = 5 +) + +// Enum value maps for NotifyReason. +var ( + NotifyReason_name = map[int32]string{ + 0: "NOTIFY_REASON_UNSPECIFIED", + 1: "NOTIFY_REASON_FIRST_NOTIFICATION", + 2: "NOTIFY_REASON_NEW_ALERTS_IN_GROUP", + 3: "NOTIFY_REASON_NEW_RESOLVED_ALERTS", + 4: "NOTIFY_REASON_ALL_ALERTS_RESOLVED", + 5: "NOTIFY_REASON_REPEAT_INTERVAL_ELAPSED", + } + NotifyReason_value = map[string]int32{ + "NOTIFY_REASON_UNSPECIFIED": 0, + "NOTIFY_REASON_FIRST_NOTIFICATION": 1, + "NOTIFY_REASON_NEW_ALERTS_IN_GROUP": 2, + "NOTIFY_REASON_NEW_RESOLVED_ALERTS": 3, + "NOTIFY_REASON_ALL_ALERTS_RESOLVED": 4, + "NOTIFY_REASON_REPEAT_INTERVAL_ELAPSED": 5, + } +) + +func (x NotifyReason) Enum() *NotifyReason { + p := new(NotifyReason) + *p = x + return p +} + +func (x NotifyReason) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (NotifyReason) Descriptor() protoreflect.EnumDescriptor { + return file_events_v2_events_proto_enumTypes[0].Descriptor() +} + +func (NotifyReason) Type() protoreflect.EnumType { + return &file_events_v2_events_proto_enumTypes[0] +} + +func (x NotifyReason) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use NotifyReason.Descriptor instead. +func (NotifyReason) EnumDescriptor() ([]byte, []int) { + return file_events_v2_events_proto_rawDescGZIP(), []int{0} +} + +type Matcher_Type int32 + +const ( + Matcher_TYPE_UNSPECIFIED Matcher_Type = 0 + Matcher_TYPE_EQUAL Matcher_Type = 1 + Matcher_TYPE_REGEXP Matcher_Type = 2 + Matcher_TYPE_NOT_EQUAL Matcher_Type = 3 + Matcher_TYPE_NOT_REGEXP Matcher_Type = 4 +) + +// Enum value maps for Matcher_Type. +var ( + Matcher_Type_name = map[int32]string{ + 0: "TYPE_UNSPECIFIED", + 1: "TYPE_EQUAL", + 2: "TYPE_REGEXP", + 3: "TYPE_NOT_EQUAL", + 4: "TYPE_NOT_REGEXP", + } + Matcher_Type_value = map[string]int32{ + "TYPE_UNSPECIFIED": 0, + "TYPE_EQUAL": 1, + "TYPE_REGEXP": 2, + "TYPE_NOT_EQUAL": 3, + "TYPE_NOT_REGEXP": 4, + } +) + +func (x Matcher_Type) Enum() *Matcher_Type { + p := new(Matcher_Type) + *p = x + return p +} + +func (x Matcher_Type) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Matcher_Type) Descriptor() protoreflect.EnumDescriptor { + return file_events_v2_events_proto_enumTypes[1].Descriptor() +} + +func (Matcher_Type) Type() protoreflect.EnumType { + return &file_events_v2_events_proto_enumTypes[1] +} + +func (x Matcher_Type) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Matcher_Type.Descriptor instead. +func (Matcher_Type) EnumDescriptor() ([]byte, []int) { + return file_events_v2_events_proto_rawDescGZIP(), []int{13, 0} +} + +// Event is the top-level envelope written to each event recorder output. +type Event struct { + state protoimpl.MessageState `protogen:"open.v1"` + Timestamp *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=timestamp,json=@timestamp,proto3" json:"timestamp,omitempty"` + Instance string `protobuf:"bytes,2,opt,name=instance,proto3" json:"instance,omitempty"` + Data *EventData `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` + ClusterPosition uint64 `protobuf:"varint,4,opt,name=cluster_position,json=clusterPosition,proto3" json:"cluster_position,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Event) Reset() { + *x = Event{} + mi := &file_events_v2_events_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Event) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Event) ProtoMessage() {} + +func (x *Event) ProtoReflect() protoreflect.Message { + mi := &file_events_v2_events_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Event.ProtoReflect.Descriptor instead. +func (*Event) Descriptor() ([]byte, []int) { + return file_events_v2_events_proto_rawDescGZIP(), []int{0} +} + +func (x *Event) GetTimestamp() *timestamppb.Timestamp { + if x != nil { + return x.Timestamp + } + return nil +} + +func (x *Event) GetInstance() string { + if x != nil { + return x.Instance + } + return "" +} + +func (x *Event) GetData() *EventData { + if x != nil { + return x.Data + } + return nil +} + +func (x *Event) GetClusterPosition() uint64 { + if x != nil { + return x.ClusterPosition + } + return 0 +} + +// EventData carries the payload for a single event recorder entry. +type EventData struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to EventType: + // + // *EventData_AlertmanagerStartupEvent + // *EventData_AlertmanagerShutdownEvent + // *EventData_AlertCreated + // *EventData_AlertResolved + // *EventData_AlertGrouped + // *EventData_Notification + // *EventData_SilenceCreated + // *EventData_SilenceUpdated + // *EventData_SilenceMutedAlert + // *EventData_InhibitionMutedAlert + EventType isEventData_EventType `protobuf_oneof:"event_type"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *EventData) Reset() { + *x = EventData{} + mi := &file_events_v2_events_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *EventData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EventData) ProtoMessage() {} + +func (x *EventData) ProtoReflect() protoreflect.Message { + mi := &file_events_v2_events_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EventData.ProtoReflect.Descriptor instead. +func (*EventData) Descriptor() ([]byte, []int) { + return file_events_v2_events_proto_rawDescGZIP(), []int{1} +} + +func (x *EventData) GetEventType() isEventData_EventType { + if x != nil { + return x.EventType + } + return nil +} + +func (x *EventData) GetAlertmanagerStartupEvent() *AlertmanagerStartupEvent { + if x != nil { + if x, ok := x.EventType.(*EventData_AlertmanagerStartupEvent); ok { + return x.AlertmanagerStartupEvent + } + } + return nil +} + +func (x *EventData) GetAlertmanagerShutdownEvent() *AlertmanagerShutdownEvent { + if x != nil { + if x, ok := x.EventType.(*EventData_AlertmanagerShutdownEvent); ok { + return x.AlertmanagerShutdownEvent + } + } + return nil +} + +func (x *EventData) GetAlertCreated() *AlertCreatedEvent { + if x != nil { + if x, ok := x.EventType.(*EventData_AlertCreated); ok { + return x.AlertCreated + } + } + return nil +} + +func (x *EventData) GetAlertResolved() *AlertResolvedEvent { + if x != nil { + if x, ok := x.EventType.(*EventData_AlertResolved); ok { + return x.AlertResolved + } + } + return nil +} + +func (x *EventData) GetAlertGrouped() *AlertGroupedEvent { + if x != nil { + if x, ok := x.EventType.(*EventData_AlertGrouped); ok { + return x.AlertGrouped + } + } + return nil +} + +func (x *EventData) GetNotification() *NotificationEvent { + if x != nil { + if x, ok := x.EventType.(*EventData_Notification); ok { + return x.Notification + } + } + return nil +} + +func (x *EventData) GetSilenceCreated() *SilenceCreatedEvent { + if x != nil { + if x, ok := x.EventType.(*EventData_SilenceCreated); ok { + return x.SilenceCreated + } + } + return nil +} + +func (x *EventData) GetSilenceUpdated() *SilenceUpdatedEvent { + if x != nil { + if x, ok := x.EventType.(*EventData_SilenceUpdated); ok { + return x.SilenceUpdated + } + } + return nil +} + +func (x *EventData) GetSilenceMutedAlert() *SilenceMutedAlertEvent { + if x != nil { + if x, ok := x.EventType.(*EventData_SilenceMutedAlert); ok { + return x.SilenceMutedAlert + } + } + return nil +} + +func (x *EventData) GetInhibitionMutedAlert() *InhibitionMutedAlertEvent { + if x != nil { + if x, ok := x.EventType.(*EventData_InhibitionMutedAlert); ok { + return x.InhibitionMutedAlert + } + } + return nil +} + +type isEventData_EventType interface { + isEventData_EventType() +} + +type EventData_AlertmanagerStartupEvent struct { + AlertmanagerStartupEvent *AlertmanagerStartupEvent `protobuf:"bytes,1,opt,name=alertmanager_startup_event,json=alertmanagerStartupEvent,proto3,oneof"` +} + +type EventData_AlertmanagerShutdownEvent struct { + AlertmanagerShutdownEvent *AlertmanagerShutdownEvent `protobuf:"bytes,2,opt,name=alertmanager_shutdown_event,json=alertmanagerShutdownEvent,proto3,oneof"` +} + +type EventData_AlertCreated struct { + AlertCreated *AlertCreatedEvent `protobuf:"bytes,3,opt,name=alert_created,json=alertCreated,proto3,oneof"` +} + +type EventData_AlertResolved struct { + AlertResolved *AlertResolvedEvent `protobuf:"bytes,4,opt,name=alert_resolved,json=alertResolved,proto3,oneof"` +} + +type EventData_AlertGrouped struct { + AlertGrouped *AlertGroupedEvent `protobuf:"bytes,5,opt,name=alert_grouped,json=alertGrouped,proto3,oneof"` +} + +type EventData_Notification struct { + Notification *NotificationEvent `protobuf:"bytes,6,opt,name=notification,proto3,oneof"` +} + +type EventData_SilenceCreated struct { + SilenceCreated *SilenceCreatedEvent `protobuf:"bytes,7,opt,name=silence_created,json=silenceCreated,proto3,oneof"` +} + +type EventData_SilenceUpdated struct { + SilenceUpdated *SilenceUpdatedEvent `protobuf:"bytes,8,opt,name=silence_updated,json=silenceUpdated,proto3,oneof"` +} + +type EventData_SilenceMutedAlert struct { + SilenceMutedAlert *SilenceMutedAlertEvent `protobuf:"bytes,9,opt,name=silence_muted_alert,json=silenceMutedAlert,proto3,oneof"` +} + +type EventData_InhibitionMutedAlert struct { + InhibitionMutedAlert *InhibitionMutedAlertEvent `protobuf:"bytes,10,opt,name=inhibition_muted_alert,json=inhibitionMutedAlert,proto3,oneof"` +} + +func (*EventData_AlertmanagerStartupEvent) isEventData_EventType() {} + +func (*EventData_AlertmanagerShutdownEvent) isEventData_EventType() {} + +func (*EventData_AlertCreated) isEventData_EventType() {} + +func (*EventData_AlertResolved) isEventData_EventType() {} + +func (*EventData_AlertGrouped) isEventData_EventType() {} + +func (*EventData_Notification) isEventData_EventType() {} + +func (*EventData_SilenceCreated) isEventData_EventType() {} + +func (*EventData_SilenceUpdated) isEventData_EventType() {} + +func (*EventData_SilenceMutedAlert) isEventData_EventType() {} + +func (*EventData_InhibitionMutedAlert) isEventData_EventType() {} + +// AlertmanagerStartupEvent is emitted once when the process starts. +type AlertmanagerStartupEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + BuildContext string `protobuf:"bytes,2,opt,name=build_context,json=buildContext,proto3" json:"build_context,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AlertmanagerStartupEvent) Reset() { + *x = AlertmanagerStartupEvent{} + mi := &file_events_v2_events_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AlertmanagerStartupEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AlertmanagerStartupEvent) ProtoMessage() {} + +func (x *AlertmanagerStartupEvent) ProtoReflect() protoreflect.Message { + mi := &file_events_v2_events_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AlertmanagerStartupEvent.ProtoReflect.Descriptor instead. +func (*AlertmanagerStartupEvent) Descriptor() ([]byte, []int) { + return file_events_v2_events_proto_rawDescGZIP(), []int{2} +} + +func (x *AlertmanagerStartupEvent) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *AlertmanagerStartupEvent) GetBuildContext() string { + if x != nil { + return x.BuildContext + } + return "" +} + +// AlertmanagerShutdownEvent is emitted when the process shuts down gracefully. +type AlertmanagerShutdownEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AlertmanagerShutdownEvent) Reset() { + *x = AlertmanagerShutdownEvent{} + mi := &file_events_v2_events_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AlertmanagerShutdownEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AlertmanagerShutdownEvent) ProtoMessage() {} + +func (x *AlertmanagerShutdownEvent) ProtoReflect() protoreflect.Message { + mi := &file_events_v2_events_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AlertmanagerShutdownEvent.ProtoReflect.Descriptor instead. +func (*AlertmanagerShutdownEvent) Descriptor() ([]byte, []int) { + return file_events_v2_events_proto_rawDescGZIP(), []int{3} +} + +// Alert represents a snapshot of an alert at the time the event was recorded. +type Alert struct { + state protoimpl.MessageState `protogen:"open.v1"` + Fingerprint uint64 `protobuf:"varint,1,opt,name=fingerprint,proto3" json:"fingerprint,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Labels map[string]string `protobuf:"bytes,3,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + Annotations map[string]string `protobuf:"bytes,4,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + StartsAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=starts_at,json=startsAt,proto3" json:"starts_at,omitempty"` + EndsAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=ends_at,json=endsAt,proto3" json:"ends_at,omitempty"` + Resolved bool `protobuf:"varint,7,opt,name=resolved,proto3" json:"resolved,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Alert) Reset() { + *x = Alert{} + mi := &file_events_v2_events_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Alert) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Alert) ProtoMessage() {} + +func (x *Alert) ProtoReflect() protoreflect.Message { + mi := &file_events_v2_events_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Alert.ProtoReflect.Descriptor instead. +func (*Alert) Descriptor() ([]byte, []int) { + return file_events_v2_events_proto_rawDescGZIP(), []int{4} +} + +func (x *Alert) GetFingerprint() uint64 { + if x != nil { + return x.Fingerprint + } + return 0 +} + +func (x *Alert) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Alert) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + +func (x *Alert) GetAnnotations() map[string]string { + if x != nil { + return x.Annotations + } + return nil +} + +func (x *Alert) GetStartsAt() *timestamppb.Timestamp { + if x != nil { + return x.StartsAt + } + return nil +} + +func (x *Alert) GetEndsAt() *timestamppb.Timestamp { + if x != nil { + return x.EndsAt + } + return nil +} + +func (x *Alert) GetResolved() bool { + if x != nil { + return x.Resolved + } + return false +} + +// GroupedAlert is a reference to an alert within an aggregation group. +type GroupedAlert struct { + state protoimpl.MessageState `protogen:"open.v1"` + Hash uint64 `protobuf:"varint,1,opt,name=hash,proto3" json:"hash,omitempty"` + Details *Alert `protobuf:"bytes,2,opt,name=details,proto3,oneof" json:"details,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupedAlert) Reset() { + *x = GroupedAlert{} + mi := &file_events_v2_events_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupedAlert) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupedAlert) ProtoMessage() {} + +func (x *GroupedAlert) ProtoReflect() protoreflect.Message { + mi := &file_events_v2_events_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupedAlert.ProtoReflect.Descriptor instead. +func (*GroupedAlert) Descriptor() ([]byte, []int) { + return file_events_v2_events_proto_rawDescGZIP(), []int{5} +} + +func (x *GroupedAlert) GetHash() uint64 { + if x != nil { + return x.Hash + } + return 0 +} + +func (x *GroupedAlert) GetDetails() *Alert { + if x != nil { + return x.Details + } + return nil +} + +// AlertGroupInfo describes an alert's aggregation group context. +type AlertGroupInfo struct { + state protoimpl.MessageState `protogen:"open.v1"` + GroupKey string `protobuf:"bytes,1,opt,name=group_key,json=groupKey,proto3" json:"group_key,omitempty"` + GroupLabels map[string]string `protobuf:"bytes,2,rep,name=group_labels,json=groupLabels,proto3" json:"group_labels,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + GroupId string `protobuf:"bytes,3,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"` + ReceiverName string `protobuf:"bytes,4,opt,name=receiver_name,json=receiverName,proto3" json:"receiver_name,omitempty"` + Matchers []*Matcher `protobuf:"bytes,5,rep,name=matchers,proto3" json:"matchers,omitempty"` + GroupUuid string `protobuf:"bytes,6,opt,name=group_uuid,json=groupUuid,proto3" json:"group_uuid,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AlertGroupInfo) Reset() { + *x = AlertGroupInfo{} + mi := &file_events_v2_events_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AlertGroupInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AlertGroupInfo) ProtoMessage() {} + +func (x *AlertGroupInfo) ProtoReflect() protoreflect.Message { + mi := &file_events_v2_events_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AlertGroupInfo.ProtoReflect.Descriptor instead. +func (*AlertGroupInfo) Descriptor() ([]byte, []int) { + return file_events_v2_events_proto_rawDescGZIP(), []int{6} +} + +func (x *AlertGroupInfo) GetGroupKey() string { + if x != nil { + return x.GroupKey + } + return "" +} + +func (x *AlertGroupInfo) GetGroupLabels() map[string]string { + if x != nil { + return x.GroupLabels + } + return nil +} + +func (x *AlertGroupInfo) GetGroupId() string { + if x != nil { + return x.GroupId + } + return "" +} + +func (x *AlertGroupInfo) GetReceiverName() string { + if x != nil { + return x.ReceiverName + } + return "" +} + +func (x *AlertGroupInfo) GetMatchers() []*Matcher { + if x != nil { + return x.Matchers + } + return nil +} + +func (x *AlertGroupInfo) GetGroupUuid() string { + if x != nil { + return x.GroupUuid + } + return "" +} + +// AlertCreatedEvent is emitted when a new alert is inserted. +type AlertCreatedEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + Alert *Alert `protobuf:"bytes,1,opt,name=alert,proto3" json:"alert,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AlertCreatedEvent) Reset() { + *x = AlertCreatedEvent{} + mi := &file_events_v2_events_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AlertCreatedEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AlertCreatedEvent) ProtoMessage() {} + +func (x *AlertCreatedEvent) ProtoReflect() protoreflect.Message { + mi := &file_events_v2_events_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AlertCreatedEvent.ProtoReflect.Descriptor instead. +func (*AlertCreatedEvent) Descriptor() ([]byte, []int) { + return file_events_v2_events_proto_rawDescGZIP(), []int{7} +} + +func (x *AlertCreatedEvent) GetAlert() *Alert { + if x != nil { + return x.Alert + } + return nil +} + +// AlertResolvedEvent is emitted when a resolved alert leaves its group. +type AlertResolvedEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + Alert *GroupedAlert `protobuf:"bytes,1,opt,name=alert,proto3" json:"alert,omitempty"` + GroupInfo *AlertGroupInfo `protobuf:"bytes,2,opt,name=group_info,json=groupInfo,proto3" json:"group_info,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AlertResolvedEvent) Reset() { + *x = AlertResolvedEvent{} + mi := &file_events_v2_events_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AlertResolvedEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AlertResolvedEvent) ProtoMessage() {} + +func (x *AlertResolvedEvent) ProtoReflect() protoreflect.Message { + mi := &file_events_v2_events_proto_msgTypes[8] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AlertResolvedEvent.ProtoReflect.Descriptor instead. +func (*AlertResolvedEvent) Descriptor() ([]byte, []int) { + return file_events_v2_events_proto_rawDescGZIP(), []int{8} +} + +func (x *AlertResolvedEvent) GetAlert() *GroupedAlert { + if x != nil { + return x.Alert + } + return nil +} + +func (x *AlertResolvedEvent) GetGroupInfo() *AlertGroupInfo { + if x != nil { + return x.GroupInfo + } + return nil +} + +// AlertGroupedEvent is emitted when an alert first enters a group. +type AlertGroupedEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + Alert *GroupedAlert `protobuf:"bytes,1,opt,name=alert,proto3" json:"alert,omitempty"` + GroupInfo *AlertGroupInfo `protobuf:"bytes,2,opt,name=group_info,json=groupInfo,proto3" json:"group_info,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AlertGroupedEvent) Reset() { + *x = AlertGroupedEvent{} + mi := &file_events_v2_events_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AlertGroupedEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AlertGroupedEvent) ProtoMessage() {} + +func (x *AlertGroupedEvent) ProtoReflect() protoreflect.Message { + mi := &file_events_v2_events_proto_msgTypes[9] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AlertGroupedEvent.ProtoReflect.Descriptor instead. +func (*AlertGroupedEvent) Descriptor() ([]byte, []int) { + return file_events_v2_events_proto_rawDescGZIP(), []int{9} +} + +func (x *AlertGroupedEvent) GetAlert() *GroupedAlert { + if x != nil { + return x.Alert + } + return nil +} + +func (x *AlertGroupedEvent) GetGroupInfo() *AlertGroupInfo { + if x != nil { + return x.GroupInfo + } + return nil +} + +// Integration identifies a notification integration. +type Integration struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Index int64 `protobuf:"varint,2,opt,name=index,proto3" json:"index,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Integration) Reset() { + *x = Integration{} + mi := &file_events_v2_events_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Integration) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Integration) ProtoMessage() {} + +func (x *Integration) ProtoReflect() protoreflect.Message { + mi := &file_events_v2_events_proto_msgTypes[10] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Integration.ProtoReflect.Descriptor instead. +func (*Integration) Descriptor() ([]byte, []int) { + return file_events_v2_events_proto_rawDescGZIP(), []int{10} +} + +func (x *Integration) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Integration) GetIndex() int64 { + if x != nil { + return x.Index + } + return 0 +} + +// NotificationEvent is emitted after a notification is delivered. +type NotificationEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + Alerts []*GroupedAlert `protobuf:"bytes,1,rep,name=alerts,proto3" json:"alerts,omitempty"` + FiringAlerts []*GroupedAlert `protobuf:"bytes,2,rep,name=firing_alerts,json=firingAlerts,proto3" json:"firing_alerts,omitempty"` + ResolvedAlerts []*GroupedAlert `protobuf:"bytes,3,rep,name=resolved_alerts,json=resolvedAlerts,proto3" json:"resolved_alerts,omitempty"` + MutedAlerts []*GroupedAlert `protobuf:"bytes,4,rep,name=muted_alerts,json=mutedAlerts,proto3" json:"muted_alerts,omitempty"` + GroupInfo *AlertGroupInfo `protobuf:"bytes,5,opt,name=group_info,json=groupInfo,proto3" json:"group_info,omitempty"` + RepeatInterval *durationpb.Duration `protobuf:"bytes,6,opt,name=repeat_interval,json=repeatInterval,proto3" json:"repeat_interval,omitempty"` + Reason NotifyReason `protobuf:"varint,7,opt,name=reason,proto3,enum=events.v2.NotifyReason" json:"reason,omitempty"` + FlushId uint64 `protobuf:"varint,8,opt,name=flush_id,json=flushId,proto3" json:"flush_id,omitempty"` + Integration *Integration `protobuf:"bytes,9,opt,name=integration,proto3" json:"integration,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *NotificationEvent) Reset() { + *x = NotificationEvent{} + mi := &file_events_v2_events_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NotificationEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NotificationEvent) ProtoMessage() {} + +func (x *NotificationEvent) ProtoReflect() protoreflect.Message { + mi := &file_events_v2_events_proto_msgTypes[11] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NotificationEvent.ProtoReflect.Descriptor instead. +func (*NotificationEvent) Descriptor() ([]byte, []int) { + return file_events_v2_events_proto_rawDescGZIP(), []int{11} +} + +func (x *NotificationEvent) GetAlerts() []*GroupedAlert { + if x != nil { + return x.Alerts + } + return nil +} + +func (x *NotificationEvent) GetFiringAlerts() []*GroupedAlert { + if x != nil { + return x.FiringAlerts + } + return nil +} + +func (x *NotificationEvent) GetResolvedAlerts() []*GroupedAlert { + if x != nil { + return x.ResolvedAlerts + } + return nil +} + +func (x *NotificationEvent) GetMutedAlerts() []*GroupedAlert { + if x != nil { + return x.MutedAlerts + } + return nil +} + +func (x *NotificationEvent) GetGroupInfo() *AlertGroupInfo { + if x != nil { + return x.GroupInfo + } + return nil +} + +func (x *NotificationEvent) GetRepeatInterval() *durationpb.Duration { + if x != nil { + return x.RepeatInterval + } + return nil +} + +func (x *NotificationEvent) GetReason() NotifyReason { + if x != nil { + return x.Reason + } + return NotifyReason_NOTIFY_REASON_UNSPECIFIED +} + +func (x *NotificationEvent) GetFlushId() uint64 { + if x != nil { + return x.FlushId + } + return 0 +} + +func (x *NotificationEvent) GetIntegration() *Integration { + if x != nil { + return x.Integration + } + return nil +} + +// Silence is a snapshot of a silence definition. +type Silence struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Matchers []*Matcher `protobuf:"bytes,2,rep,name=matchers,proto3" json:"matchers,omitempty"` + Annotations map[string]string `protobuf:"bytes,3,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + StartsAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=starts_at,json=startsAt,proto3" json:"starts_at,omitempty"` + EndsAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=ends_at,json=endsAt,proto3" json:"ends_at,omitempty"` + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + CreatedBy string `protobuf:"bytes,7,opt,name=created_by,json=createdBy,proto3" json:"created_by,omitempty"` + Comment string `protobuf:"bytes,8,opt,name=comment,proto3" json:"comment,omitempty"` + MatcherSets []*MatcherSet `protobuf:"bytes,9,rep,name=matcher_sets,json=matcherSets,proto3" json:"matcher_sets,omitempty"` + ReceiverMatcherSets []*MatcherSet `protobuf:"bytes,10,rep,name=receiver_matcher_sets,json=receiverMatcherSets,proto3" json:"receiver_matcher_sets,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Silence) Reset() { + *x = Silence{} + mi := &file_events_v2_events_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Silence) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Silence) ProtoMessage() {} + +func (x *Silence) ProtoReflect() protoreflect.Message { + mi := &file_events_v2_events_proto_msgTypes[12] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Silence.ProtoReflect.Descriptor instead. +func (*Silence) Descriptor() ([]byte, []int) { + return file_events_v2_events_proto_rawDescGZIP(), []int{12} +} + +func (x *Silence) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Silence) GetMatchers() []*Matcher { + if x != nil { + return x.Matchers + } + return nil +} + +func (x *Silence) GetAnnotations() map[string]string { + if x != nil { + return x.Annotations + } + return nil +} + +func (x *Silence) GetStartsAt() *timestamppb.Timestamp { + if x != nil { + return x.StartsAt + } + return nil +} + +func (x *Silence) GetEndsAt() *timestamppb.Timestamp { + if x != nil { + return x.EndsAt + } + return nil +} + +func (x *Silence) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + +func (x *Silence) GetCreatedBy() string { + if x != nil { + return x.CreatedBy + } + return "" +} + +func (x *Silence) GetComment() string { + if x != nil { + return x.Comment + } + return "" +} + +func (x *Silence) GetMatcherSets() []*MatcherSet { + if x != nil { + return x.MatcherSets + } + return nil +} + +func (x *Silence) GetReceiverMatcherSets() []*MatcherSet { + if x != nil { + return x.ReceiverMatcherSets + } + return nil +} + +// Matcher defines a single label matching rule. +type Matcher struct { + state protoimpl.MessageState `protogen:"open.v1"` + Type Matcher_Type `protobuf:"varint,1,opt,name=type,proto3,enum=events.v2.Matcher_Type" json:"type,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Pattern string `protobuf:"bytes,3,opt,name=pattern,proto3" json:"pattern,omitempty"` + Rendered string `protobuf:"bytes,4,opt,name=rendered,proto3" json:"rendered,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Matcher) Reset() { + *x = Matcher{} + mi := &file_events_v2_events_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Matcher) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Matcher) ProtoMessage() {} + +func (x *Matcher) ProtoReflect() protoreflect.Message { + mi := &file_events_v2_events_proto_msgTypes[13] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Matcher.ProtoReflect.Descriptor instead. +func (*Matcher) Descriptor() ([]byte, []int) { + return file_events_v2_events_proto_rawDescGZIP(), []int{13} +} + +func (x *Matcher) GetType() Matcher_Type { + if x != nil { + return x.Type + } + return Matcher_TYPE_UNSPECIFIED +} + +func (x *Matcher) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Matcher) GetPattern() string { + if x != nil { + return x.Pattern + } + return "" +} + +func (x *Matcher) GetRendered() string { + if x != nil { + return x.Rendered + } + return "" +} + +// MatcherSet is a conjunction of matchers. +type MatcherSet struct { + state protoimpl.MessageState `protogen:"open.v1"` + Matchers []*Matcher `protobuf:"bytes,1,rep,name=matchers,proto3" json:"matchers,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MatcherSet) Reset() { + *x = MatcherSet{} + mi := &file_events_v2_events_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MatcherSet) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MatcherSet) ProtoMessage() {} + +func (x *MatcherSet) ProtoReflect() protoreflect.Message { + mi := &file_events_v2_events_proto_msgTypes[14] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MatcherSet.ProtoReflect.Descriptor instead. +func (*MatcherSet) Descriptor() ([]byte, []int) { + return file_events_v2_events_proto_rawDescGZIP(), []int{14} +} + +func (x *MatcherSet) GetMatchers() []*Matcher { + if x != nil { + return x.Matchers + } + return nil +} + +// SilenceCreatedEvent is emitted when a silence is created. +type SilenceCreatedEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + Silence *Silence `protobuf:"bytes,1,opt,name=silence,proto3" json:"silence,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SilenceCreatedEvent) Reset() { + *x = SilenceCreatedEvent{} + mi := &file_events_v2_events_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SilenceCreatedEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SilenceCreatedEvent) ProtoMessage() {} + +func (x *SilenceCreatedEvent) ProtoReflect() protoreflect.Message { + mi := &file_events_v2_events_proto_msgTypes[15] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SilenceCreatedEvent.ProtoReflect.Descriptor instead. +func (*SilenceCreatedEvent) Descriptor() ([]byte, []int) { + return file_events_v2_events_proto_rawDescGZIP(), []int{15} +} + +func (x *SilenceCreatedEvent) GetSilence() *Silence { + if x != nil { + return x.Silence + } + return nil +} + +// SilenceUpdatedEvent is emitted when a silence is modified. +type SilenceUpdatedEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + Silence *Silence `protobuf:"bytes,1,opt,name=silence,proto3" json:"silence,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SilenceUpdatedEvent) Reset() { + *x = SilenceUpdatedEvent{} + mi := &file_events_v2_events_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SilenceUpdatedEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SilenceUpdatedEvent) ProtoMessage() {} + +func (x *SilenceUpdatedEvent) ProtoReflect() protoreflect.Message { + mi := &file_events_v2_events_proto_msgTypes[16] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SilenceUpdatedEvent.ProtoReflect.Descriptor instead. +func (*SilenceUpdatedEvent) Descriptor() ([]byte, []int) { + return file_events_v2_events_proto_rawDescGZIP(), []int{16} +} + +func (x *SilenceUpdatedEvent) GetSilence() *Silence { + if x != nil { + return x.Silence + } + return nil +} + +// MutedAlert identifies an alert suppressed by a silence or inhibition rule. +type MutedAlert struct { + state protoimpl.MessageState `protogen:"open.v1"` + Labels map[string]string `protobuf:"bytes,1,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + Fingerprint uint64 `protobuf:"varint,2,opt,name=fingerprint,proto3" json:"fingerprint,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MutedAlert) Reset() { + *x = MutedAlert{} + mi := &file_events_v2_events_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MutedAlert) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MutedAlert) ProtoMessage() {} + +func (x *MutedAlert) ProtoReflect() protoreflect.Message { + mi := &file_events_v2_events_proto_msgTypes[17] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MutedAlert.ProtoReflect.Descriptor instead. +func (*MutedAlert) Descriptor() ([]byte, []int) { + return file_events_v2_events_proto_rawDescGZIP(), []int{17} +} + +func (x *MutedAlert) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + +func (x *MutedAlert) GetFingerprint() uint64 { + if x != nil { + return x.Fingerprint + } + return 0 +} + +// SilenceMutedAlertEvent is emitted when a silence suppresses an alert. +type SilenceMutedAlertEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + Silence *Silence `protobuf:"bytes,1,opt,name=silence,proto3" json:"silence,omitempty"` + MutedAlert *MutedAlert `protobuf:"bytes,2,opt,name=muted_alert,json=mutedAlert,proto3" json:"muted_alert,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SilenceMutedAlertEvent) Reset() { + *x = SilenceMutedAlertEvent{} + mi := &file_events_v2_events_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SilenceMutedAlertEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SilenceMutedAlertEvent) ProtoMessage() {} + +func (x *SilenceMutedAlertEvent) ProtoReflect() protoreflect.Message { + mi := &file_events_v2_events_proto_msgTypes[18] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SilenceMutedAlertEvent.ProtoReflect.Descriptor instead. +func (*SilenceMutedAlertEvent) Descriptor() ([]byte, []int) { + return file_events_v2_events_proto_rawDescGZIP(), []int{18} +} + +func (x *SilenceMutedAlertEvent) GetSilence() *Silence { + if x != nil { + return x.Silence + } + return nil +} + +func (x *SilenceMutedAlertEvent) GetMutedAlert() *MutedAlert { + if x != nil { + return x.MutedAlert + } + return nil +} + +// InhibitRule is a snapshot of an inhibition rule definition. +type InhibitRule struct { + state protoimpl.MessageState `protogen:"open.v1"` + SourceMatchers []*Matcher `protobuf:"bytes,1,rep,name=source_matchers,json=sourceMatchers,proto3" json:"source_matchers,omitempty"` + TargetMatchers []*Matcher `protobuf:"bytes,2,rep,name=target_matchers,json=targetMatchers,proto3" json:"target_matchers,omitempty"` + EqualLabels []string `protobuf:"bytes,3,rep,name=equal_labels,json=equalLabels,proto3" json:"equal_labels,omitempty"` + Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *InhibitRule) Reset() { + *x = InhibitRule{} + mi := &file_events_v2_events_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *InhibitRule) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InhibitRule) ProtoMessage() {} + +func (x *InhibitRule) ProtoReflect() protoreflect.Message { + mi := &file_events_v2_events_proto_msgTypes[19] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InhibitRule.ProtoReflect.Descriptor instead. +func (*InhibitRule) Descriptor() ([]byte, []int) { + return file_events_v2_events_proto_rawDescGZIP(), []int{19} +} + +func (x *InhibitRule) GetSourceMatchers() []*Matcher { + if x != nil { + return x.SourceMatchers + } + return nil +} + +func (x *InhibitRule) GetTargetMatchers() []*Matcher { + if x != nil { + return x.TargetMatchers + } + return nil +} + +func (x *InhibitRule) GetEqualLabels() []string { + if x != nil { + return x.EqualLabels + } + return nil +} + +func (x *InhibitRule) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +// InhibitionMutedAlertEvent is emitted when inhibition suppresses an alert. +type InhibitionMutedAlertEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + InhibitRules []*InhibitRule `protobuf:"bytes,1,rep,name=inhibit_rules,json=inhibitRules,proto3" json:"inhibit_rules,omitempty"` + MutedAlert *MutedAlert `protobuf:"bytes,2,opt,name=muted_alert,json=mutedAlert,proto3" json:"muted_alert,omitempty"` + InhibitingFingerprints []uint64 `protobuf:"varint,3,rep,packed,name=inhibiting_fingerprints,json=inhibitingFingerprints,proto3" json:"inhibiting_fingerprints,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *InhibitionMutedAlertEvent) Reset() { + *x = InhibitionMutedAlertEvent{} + mi := &file_events_v2_events_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *InhibitionMutedAlertEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InhibitionMutedAlertEvent) ProtoMessage() {} + +func (x *InhibitionMutedAlertEvent) ProtoReflect() protoreflect.Message { + mi := &file_events_v2_events_proto_msgTypes[20] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InhibitionMutedAlertEvent.ProtoReflect.Descriptor instead. +func (*InhibitionMutedAlertEvent) Descriptor() ([]byte, []int) { + return file_events_v2_events_proto_rawDescGZIP(), []int{20} +} + +func (x *InhibitionMutedAlertEvent) GetInhibitRules() []*InhibitRule { + if x != nil { + return x.InhibitRules + } + return nil +} + +func (x *InhibitionMutedAlertEvent) GetMutedAlert() *MutedAlert { + if x != nil { + return x.MutedAlert + } + return nil +} + +func (x *InhibitionMutedAlertEvent) GetInhibitingFingerprints() []uint64 { + if x != nil { + return x.InhibitingFingerprints + } + return nil +} + +var File_events_v2_events_proto protoreflect.FileDescriptor + +const file_events_v2_events_proto_rawDesc = "" + + "\n" + + "\x16events/v2/events.proto\x12\tevents.v2\x1a\x1egoogle/protobuf/duration.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xb3\x01\n" + + "\x05Event\x129\n" + + "\ttimestamp\x18\x01 \x01(\v2\x1a.google.protobuf.TimestampR\n" + + "@timestamp\x12\x1a\n" + + "\binstance\x18\x02 \x01(\tR\binstance\x12(\n" + + "\x04data\x18\x03 \x01(\v2\x14.events.v2.EventDataR\x04data\x12)\n" + + "\x10cluster_position\x18\x04 \x01(\x04R\x0fclusterPosition\"\xc5\x06\n" + + "\tEventData\x12c\n" + + "\x1aalertmanager_startup_event\x18\x01 \x01(\v2#.events.v2.AlertmanagerStartupEventH\x00R\x18alertmanagerStartupEvent\x12f\n" + + "\x1balertmanager_shutdown_event\x18\x02 \x01(\v2$.events.v2.AlertmanagerShutdownEventH\x00R\x19alertmanagerShutdownEvent\x12C\n" + + "\ralert_created\x18\x03 \x01(\v2\x1c.events.v2.AlertCreatedEventH\x00R\falertCreated\x12F\n" + + "\x0ealert_resolved\x18\x04 \x01(\v2\x1d.events.v2.AlertResolvedEventH\x00R\ralertResolved\x12C\n" + + "\ralert_grouped\x18\x05 \x01(\v2\x1c.events.v2.AlertGroupedEventH\x00R\falertGrouped\x12B\n" + + "\fnotification\x18\x06 \x01(\v2\x1c.events.v2.NotificationEventH\x00R\fnotification\x12I\n" + + "\x0fsilence_created\x18\a \x01(\v2\x1e.events.v2.SilenceCreatedEventH\x00R\x0esilenceCreated\x12I\n" + + "\x0fsilence_updated\x18\b \x01(\v2\x1e.events.v2.SilenceUpdatedEventH\x00R\x0esilenceUpdated\x12S\n" + + "\x13silence_muted_alert\x18\t \x01(\v2!.events.v2.SilenceMutedAlertEventH\x00R\x11silenceMutedAlert\x12\\\n" + + "\x16inhibition_muted_alert\x18\n" + + " \x01(\v2$.events.v2.InhibitionMutedAlertEventH\x00R\x14inhibitionMutedAlertB\f\n" + + "\n" + + "event_type\"Y\n" + + "\x18AlertmanagerStartupEvent\x12\x18\n" + + "\aversion\x18\x01 \x01(\tR\aversion\x12#\n" + + "\rbuild_context\x18\x02 \x01(\tR\fbuildContext\"\x1b\n" + + "\x19AlertmanagerShutdownEvent\"\xbd\x03\n" + + "\x05Alert\x12 \n" + + "\vfingerprint\x18\x01 \x01(\x04R\vfingerprint\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x124\n" + + "\x06labels\x18\x03 \x03(\v2\x1c.events.v2.Alert.LabelsEntryR\x06labels\x12C\n" + + "\vannotations\x18\x04 \x03(\v2!.events.v2.Alert.AnnotationsEntryR\vannotations\x127\n" + + "\tstarts_at\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\bstartsAt\x123\n" + + "\aends_at\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\x06endsAt\x12\x1a\n" + + "\bresolved\x18\a \x01(\bR\bresolved\x1a9\n" + + "\vLabelsEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\x1a>\n" + + "\x10AnnotationsEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"_\n" + + "\fGroupedAlert\x12\x12\n" + + "\x04hash\x18\x01 \x01(\x04R\x04hash\x12/\n" + + "\adetails\x18\x02 \x01(\v2\x10.events.v2.AlertH\x00R\adetails\x88\x01\x01B\n" + + "\n" + + "\b_details\"\xcb\x02\n" + + "\x0eAlertGroupInfo\x12\x1b\n" + + "\tgroup_key\x18\x01 \x01(\tR\bgroupKey\x12M\n" + + "\fgroup_labels\x18\x02 \x03(\v2*.events.v2.AlertGroupInfo.GroupLabelsEntryR\vgroupLabels\x12\x19\n" + + "\bgroup_id\x18\x03 \x01(\tR\agroupId\x12#\n" + + "\rreceiver_name\x18\x04 \x01(\tR\freceiverName\x12.\n" + + "\bmatchers\x18\x05 \x03(\v2\x12.events.v2.MatcherR\bmatchers\x12\x1d\n" + + "\n" + + "group_uuid\x18\x06 \x01(\tR\tgroupUuid\x1a>\n" + + "\x10GroupLabelsEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\";\n" + + "\x11AlertCreatedEvent\x12&\n" + + "\x05alert\x18\x01 \x01(\v2\x10.events.v2.AlertR\x05alert\"}\n" + + "\x12AlertResolvedEvent\x12-\n" + + "\x05alert\x18\x01 \x01(\v2\x17.events.v2.GroupedAlertR\x05alert\x128\n" + + "\n" + + "group_info\x18\x02 \x01(\v2\x19.events.v2.AlertGroupInfoR\tgroupInfo\"|\n" + + "\x11AlertGroupedEvent\x12-\n" + + "\x05alert\x18\x01 \x01(\v2\x17.events.v2.GroupedAlertR\x05alert\x128\n" + + "\n" + + "group_info\x18\x02 \x01(\v2\x19.events.v2.AlertGroupInfoR\tgroupInfo\"7\n" + + "\vIntegration\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\x14\n" + + "\x05index\x18\x02 \x01(\x03R\x05index\"\x84\x04\n" + + "\x11NotificationEvent\x12/\n" + + "\x06alerts\x18\x01 \x03(\v2\x17.events.v2.GroupedAlertR\x06alerts\x12<\n" + + "\rfiring_alerts\x18\x02 \x03(\v2\x17.events.v2.GroupedAlertR\ffiringAlerts\x12@\n" + + "\x0fresolved_alerts\x18\x03 \x03(\v2\x17.events.v2.GroupedAlertR\x0eresolvedAlerts\x12:\n" + + "\fmuted_alerts\x18\x04 \x03(\v2\x17.events.v2.GroupedAlertR\vmutedAlerts\x128\n" + + "\n" + + "group_info\x18\x05 \x01(\v2\x19.events.v2.AlertGroupInfoR\tgroupInfo\x12B\n" + + "\x0frepeat_interval\x18\x06 \x01(\v2\x19.google.protobuf.DurationR\x0erepeatInterval\x12/\n" + + "\x06reason\x18\a \x01(\x0e2\x17.events.v2.NotifyReasonR\x06reason\x12\x19\n" + + "\bflush_id\x18\b \x01(\x04R\aflushId\x128\n" + + "\vintegration\x18\t \x01(\v2\x16.events.v2.IntegrationR\vintegration\"\xb7\x04\n" + + "\aSilence\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12.\n" + + "\bmatchers\x18\x02 \x03(\v2\x12.events.v2.MatcherR\bmatchers\x12E\n" + + "\vannotations\x18\x03 \x03(\v2#.events.v2.Silence.AnnotationsEntryR\vannotations\x127\n" + + "\tstarts_at\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\bstartsAt\x123\n" + + "\aends_at\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\x06endsAt\x129\n" + + "\n" + + "updated_at\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\tupdatedAt\x12\x1d\n" + + "\n" + + "created_by\x18\a \x01(\tR\tcreatedBy\x12\x18\n" + + "\acomment\x18\b \x01(\tR\acomment\x128\n" + + "\fmatcher_sets\x18\t \x03(\v2\x15.events.v2.MatcherSetR\vmatcherSets\x12I\n" + + "\x15receiver_matcher_sets\x18\n" + + " \x03(\v2\x15.events.v2.MatcherSetR\x13receiverMatcherSets\x1a>\n" + + "\x10AnnotationsEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xe8\x01\n" + + "\aMatcher\x12+\n" + + "\x04type\x18\x01 \x01(\x0e2\x17.events.v2.Matcher.TypeR\x04type\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12\x18\n" + + "\apattern\x18\x03 \x01(\tR\apattern\x12\x1a\n" + + "\brendered\x18\x04 \x01(\tR\brendered\"f\n" + + "\x04Type\x12\x14\n" + + "\x10TYPE_UNSPECIFIED\x10\x00\x12\x0e\n" + + "\n" + + "TYPE_EQUAL\x10\x01\x12\x0f\n" + + "\vTYPE_REGEXP\x10\x02\x12\x12\n" + + "\x0eTYPE_NOT_EQUAL\x10\x03\x12\x13\n" + + "\x0fTYPE_NOT_REGEXP\x10\x04\"<\n" + + "\n" + + "MatcherSet\x12.\n" + + "\bmatchers\x18\x01 \x03(\v2\x12.events.v2.MatcherR\bmatchers\"C\n" + + "\x13SilenceCreatedEvent\x12,\n" + + "\asilence\x18\x01 \x01(\v2\x12.events.v2.SilenceR\asilence\"C\n" + + "\x13SilenceUpdatedEvent\x12,\n" + + "\asilence\x18\x01 \x01(\v2\x12.events.v2.SilenceR\asilence\"\xa4\x01\n" + + "\n" + + "MutedAlert\x129\n" + + "\x06labels\x18\x01 \x03(\v2!.events.v2.MutedAlert.LabelsEntryR\x06labels\x12 \n" + + "\vfingerprint\x18\x02 \x01(\x04R\vfingerprint\x1a9\n" + + "\vLabelsEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"~\n" + + "\x16SilenceMutedAlertEvent\x12,\n" + + "\asilence\x18\x01 \x01(\v2\x12.events.v2.SilenceR\asilence\x126\n" + + "\vmuted_alert\x18\x02 \x01(\v2\x15.events.v2.MutedAlertR\n" + + "mutedAlert\"\xbe\x01\n" + + "\vInhibitRule\x12;\n" + + "\x0fsource_matchers\x18\x01 \x03(\v2\x12.events.v2.MatcherR\x0esourceMatchers\x12;\n" + + "\x0ftarget_matchers\x18\x02 \x03(\v2\x12.events.v2.MatcherR\x0etargetMatchers\x12!\n" + + "\fequal_labels\x18\x03 \x03(\tR\vequalLabels\x12\x12\n" + + "\x04name\x18\x04 \x01(\tR\x04name\"\xc9\x01\n" + + "\x19InhibitionMutedAlertEvent\x12;\n" + + "\rinhibit_rules\x18\x01 \x03(\v2\x16.events.v2.InhibitRuleR\finhibitRules\x126\n" + + "\vmuted_alert\x18\x02 \x01(\v2\x15.events.v2.MutedAlertR\n" + + "mutedAlert\x127\n" + + "\x17inhibiting_fingerprints\x18\x03 \x03(\x04R\x16inhibitingFingerprints*\xf3\x01\n" + + "\fNotifyReason\x12\x1d\n" + + "\x19NOTIFY_REASON_UNSPECIFIED\x10\x00\x12$\n" + + " NOTIFY_REASON_FIRST_NOTIFICATION\x10\x01\x12%\n" + + "!NOTIFY_REASON_NEW_ALERTS_IN_GROUP\x10\x02\x12%\n" + + "!NOTIFY_REASON_NEW_RESOLVED_ALERTS\x10\x03\x12%\n" + + "!NOTIFY_REASON_ALL_ALERTS_RESOLVED\x10\x04\x12)\n" + + "%NOTIFY_REASON_REPEAT_INTERVAL_ELAPSED\x10\x05BEZCgithub.com/prometheus/alertmanager/eventrecorder/events/v2;eventsv2b\x06proto3" + +var ( + file_events_v2_events_proto_rawDescOnce sync.Once + file_events_v2_events_proto_rawDescData []byte +) + +func file_events_v2_events_proto_rawDescGZIP() []byte { + file_events_v2_events_proto_rawDescOnce.Do(func() { + file_events_v2_events_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_events_v2_events_proto_rawDesc), len(file_events_v2_events_proto_rawDesc))) + }) + return file_events_v2_events_proto_rawDescData +} + +var file_events_v2_events_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_events_v2_events_proto_msgTypes = make([]protoimpl.MessageInfo, 26) +var file_events_v2_events_proto_goTypes = []any{ + (NotifyReason)(0), // 0: events.v2.NotifyReason + (Matcher_Type)(0), // 1: events.v2.Matcher.Type + (*Event)(nil), // 2: events.v2.Event + (*EventData)(nil), // 3: events.v2.EventData + (*AlertmanagerStartupEvent)(nil), // 4: events.v2.AlertmanagerStartupEvent + (*AlertmanagerShutdownEvent)(nil), // 5: events.v2.AlertmanagerShutdownEvent + (*Alert)(nil), // 6: events.v2.Alert + (*GroupedAlert)(nil), // 7: events.v2.GroupedAlert + (*AlertGroupInfo)(nil), // 8: events.v2.AlertGroupInfo + (*AlertCreatedEvent)(nil), // 9: events.v2.AlertCreatedEvent + (*AlertResolvedEvent)(nil), // 10: events.v2.AlertResolvedEvent + (*AlertGroupedEvent)(nil), // 11: events.v2.AlertGroupedEvent + (*Integration)(nil), // 12: events.v2.Integration + (*NotificationEvent)(nil), // 13: events.v2.NotificationEvent + (*Silence)(nil), // 14: events.v2.Silence + (*Matcher)(nil), // 15: events.v2.Matcher + (*MatcherSet)(nil), // 16: events.v2.MatcherSet + (*SilenceCreatedEvent)(nil), // 17: events.v2.SilenceCreatedEvent + (*SilenceUpdatedEvent)(nil), // 18: events.v2.SilenceUpdatedEvent + (*MutedAlert)(nil), // 19: events.v2.MutedAlert + (*SilenceMutedAlertEvent)(nil), // 20: events.v2.SilenceMutedAlertEvent + (*InhibitRule)(nil), // 21: events.v2.InhibitRule + (*InhibitionMutedAlertEvent)(nil), // 22: events.v2.InhibitionMutedAlertEvent + nil, // 23: events.v2.Alert.LabelsEntry + nil, // 24: events.v2.Alert.AnnotationsEntry + nil, // 25: events.v2.AlertGroupInfo.GroupLabelsEntry + nil, // 26: events.v2.Silence.AnnotationsEntry + nil, // 27: events.v2.MutedAlert.LabelsEntry + (*timestamppb.Timestamp)(nil), // 28: google.protobuf.Timestamp + (*durationpb.Duration)(nil), // 29: google.protobuf.Duration +} +var file_events_v2_events_proto_depIdxs = []int32{ + 28, // 0: events.v2.Event.timestamp:type_name -> google.protobuf.Timestamp + 3, // 1: events.v2.Event.data:type_name -> events.v2.EventData + 4, // 2: events.v2.EventData.alertmanager_startup_event:type_name -> events.v2.AlertmanagerStartupEvent + 5, // 3: events.v2.EventData.alertmanager_shutdown_event:type_name -> events.v2.AlertmanagerShutdownEvent + 9, // 4: events.v2.EventData.alert_created:type_name -> events.v2.AlertCreatedEvent + 10, // 5: events.v2.EventData.alert_resolved:type_name -> events.v2.AlertResolvedEvent + 11, // 6: events.v2.EventData.alert_grouped:type_name -> events.v2.AlertGroupedEvent + 13, // 7: events.v2.EventData.notification:type_name -> events.v2.NotificationEvent + 17, // 8: events.v2.EventData.silence_created:type_name -> events.v2.SilenceCreatedEvent + 18, // 9: events.v2.EventData.silence_updated:type_name -> events.v2.SilenceUpdatedEvent + 20, // 10: events.v2.EventData.silence_muted_alert:type_name -> events.v2.SilenceMutedAlertEvent + 22, // 11: events.v2.EventData.inhibition_muted_alert:type_name -> events.v2.InhibitionMutedAlertEvent + 23, // 12: events.v2.Alert.labels:type_name -> events.v2.Alert.LabelsEntry + 24, // 13: events.v2.Alert.annotations:type_name -> events.v2.Alert.AnnotationsEntry + 28, // 14: events.v2.Alert.starts_at:type_name -> google.protobuf.Timestamp + 28, // 15: events.v2.Alert.ends_at:type_name -> google.protobuf.Timestamp + 6, // 16: events.v2.GroupedAlert.details:type_name -> events.v2.Alert + 25, // 17: events.v2.AlertGroupInfo.group_labels:type_name -> events.v2.AlertGroupInfo.GroupLabelsEntry + 15, // 18: events.v2.AlertGroupInfo.matchers:type_name -> events.v2.Matcher + 6, // 19: events.v2.AlertCreatedEvent.alert:type_name -> events.v2.Alert + 7, // 20: events.v2.AlertResolvedEvent.alert:type_name -> events.v2.GroupedAlert + 8, // 21: events.v2.AlertResolvedEvent.group_info:type_name -> events.v2.AlertGroupInfo + 7, // 22: events.v2.AlertGroupedEvent.alert:type_name -> events.v2.GroupedAlert + 8, // 23: events.v2.AlertGroupedEvent.group_info:type_name -> events.v2.AlertGroupInfo + 7, // 24: events.v2.NotificationEvent.alerts:type_name -> events.v2.GroupedAlert + 7, // 25: events.v2.NotificationEvent.firing_alerts:type_name -> events.v2.GroupedAlert + 7, // 26: events.v2.NotificationEvent.resolved_alerts:type_name -> events.v2.GroupedAlert + 7, // 27: events.v2.NotificationEvent.muted_alerts:type_name -> events.v2.GroupedAlert + 8, // 28: events.v2.NotificationEvent.group_info:type_name -> events.v2.AlertGroupInfo + 29, // 29: events.v2.NotificationEvent.repeat_interval:type_name -> google.protobuf.Duration + 0, // 30: events.v2.NotificationEvent.reason:type_name -> events.v2.NotifyReason + 12, // 31: events.v2.NotificationEvent.integration:type_name -> events.v2.Integration + 15, // 32: events.v2.Silence.matchers:type_name -> events.v2.Matcher + 26, // 33: events.v2.Silence.annotations:type_name -> events.v2.Silence.AnnotationsEntry + 28, // 34: events.v2.Silence.starts_at:type_name -> google.protobuf.Timestamp + 28, // 35: events.v2.Silence.ends_at:type_name -> google.protobuf.Timestamp + 28, // 36: events.v2.Silence.updated_at:type_name -> google.protobuf.Timestamp + 16, // 37: events.v2.Silence.matcher_sets:type_name -> events.v2.MatcherSet + 16, // 38: events.v2.Silence.receiver_matcher_sets:type_name -> events.v2.MatcherSet + 1, // 39: events.v2.Matcher.type:type_name -> events.v2.Matcher.Type + 15, // 40: events.v2.MatcherSet.matchers:type_name -> events.v2.Matcher + 14, // 41: events.v2.SilenceCreatedEvent.silence:type_name -> events.v2.Silence + 14, // 42: events.v2.SilenceUpdatedEvent.silence:type_name -> events.v2.Silence + 27, // 43: events.v2.MutedAlert.labels:type_name -> events.v2.MutedAlert.LabelsEntry + 14, // 44: events.v2.SilenceMutedAlertEvent.silence:type_name -> events.v2.Silence + 19, // 45: events.v2.SilenceMutedAlertEvent.muted_alert:type_name -> events.v2.MutedAlert + 15, // 46: events.v2.InhibitRule.source_matchers:type_name -> events.v2.Matcher + 15, // 47: events.v2.InhibitRule.target_matchers:type_name -> events.v2.Matcher + 21, // 48: events.v2.InhibitionMutedAlertEvent.inhibit_rules:type_name -> events.v2.InhibitRule + 19, // 49: events.v2.InhibitionMutedAlertEvent.muted_alert:type_name -> events.v2.MutedAlert + 50, // [50:50] is the sub-list for method output_type + 50, // [50:50] is the sub-list for method input_type + 50, // [50:50] is the sub-list for extension type_name + 50, // [50:50] is the sub-list for extension extendee + 0, // [0:50] is the sub-list for field type_name +} + +func init() { file_events_v2_events_proto_init() } +func file_events_v2_events_proto_init() { + if File_events_v2_events_proto != nil { + return + } + file_events_v2_events_proto_msgTypes[1].OneofWrappers = []any{ + (*EventData_AlertmanagerStartupEvent)(nil), + (*EventData_AlertmanagerShutdownEvent)(nil), + (*EventData_AlertCreated)(nil), + (*EventData_AlertResolved)(nil), + (*EventData_AlertGrouped)(nil), + (*EventData_Notification)(nil), + (*EventData_SilenceCreated)(nil), + (*EventData_SilenceUpdated)(nil), + (*EventData_SilenceMutedAlert)(nil), + (*EventData_InhibitionMutedAlert)(nil), + } + file_events_v2_events_proto_msgTypes[5].OneofWrappers = []any{} + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_events_v2_events_proto_rawDesc), len(file_events_v2_events_proto_rawDesc)), + NumEnums: 2, + NumMessages: 26, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_events_v2_events_proto_goTypes, + DependencyIndexes: file_events_v2_events_proto_depIdxs, + EnumInfos: file_events_v2_events_proto_enumTypes, + MessageInfos: file_events_v2_events_proto_msgTypes, + }.Build() + File_events_v2_events_proto = out.File + file_events_v2_events_proto_goTypes = nil + file_events_v2_events_proto_depIdxs = nil +} diff --git a/eventrecorder/events_test.go b/eventrecorder/events_test.go index 01983f2fb9..57f36180ad 100644 --- a/eventrecorder/events_test.go +++ b/eventrecorder/events_test.go @@ -14,107 +14,149 @@ package eventrecorder import ( + "encoding/json" "testing" + "time" "github.com/prometheus/common/model" "github.com/stretchr/testify/require" - "github.com/prometheus/alertmanager/eventrecorder/eventrecorderpb" + "github.com/prometheus/alertmanager/alert" + events "github.com/prometheus/alertmanager/eventrecorder/events/v2" "github.com/prometheus/alertmanager/pkg/labels" + "github.com/prometheus/alertmanager/silence/silencepb" ) -func TestExtractEventType(t *testing.T) { - tests := []struct { - name string - event *eventrecorderpb.EventData - expected string - }{ - { - name: "startup", - event: startupEvent(), - expected: "alertmanager_startup_event", - }, - { - name: "shutdown", - event: &eventrecorderpb.EventData{ - EventType: &eventrecorderpb.EventData_AlertmanagerShutdownEvent{}, - }, - expected: "alertmanager_shutdown_event", - }, - { - name: "alert_created", - event: &eventrecorderpb.EventData{ - EventType: &eventrecorderpb.EventData_AlertCreated{}, - }, - expected: "alert_created", - }, - { - name: "unknown", - event: &eventrecorderpb.EventData{}, - expected: "unknown", - }, - { - name: "nil", - event: nil, - expected: "unknown", - }, - } - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - require.Equal(t, tc.expected, extractEventType(tc.event)) - }) - } -} +func TestAlertEventSnapshotsLabels(t *testing.T) { + a := &alert.Alert{Alert: model.Alert{ + Labels: model.LabelSet{"alertname": "Down", "severity": "warning"}, Annotations: model.LabelSet{"summary": "test"}, + StartsAt: time.Now(), EndsAt: time.Now().Add(time.Hour), + }} + event := NewAlertCreatedEvent(a) -func TestLabelSetAsProto(t *testing.T) { - ls := model.LabelSet{"foo": "bar", "baz": "qux"} - proto := LabelSetAsProto(ls) + a.Labels["severity"] = "critical" + a.Annotations["summary"] = "changed" - require.Len(t, proto.Labels, 2) - found := map[string]string{} - for _, lp := range proto.Labels { - found[lp.Key] = lp.Value - } - require.Equal(t, "bar", found["foo"]) - require.Equal(t, "qux", found["baz"]) + got := event.message.GetAlertCreated().Alert + require.Equal(t, "warning", got.Labels["severity"]) + require.Equal(t, "test", got.Annotations["summary"]) } -func TestMatcherAsProto(t *testing.T) { - m, err := labels.NewMatcher(labels.MatchRegexp, "job", "api.*") - require.NoError(t, err) - - proto := MatcherAsProto(m) - require.Equal(t, eventrecorderpb.Matcher_TYPE_REGEXP, proto.Type) - require.Equal(t, "job", proto.Name) - require.Equal(t, "api.*", proto.Pattern) - require.NotEmpty(t, proto.Rendered) -} +func TestSilenceEventSnapshotsAnnotationsAndMatchers(t *testing.T) { + silence := &silencepb.Silence{ + Annotations: map[string]string{"owner": "ops"}, + MatcherSets: []*silencepb.MatcherSet{{Matchers: []*silencepb.Matcher{{ + Type: silencepb.Matcher_EQUAL, Name: "service", Pattern: "api", + }}}}, + ReceiverMatcherSets: []*silencepb.MatcherSet{{Matchers: []*silencepb.Matcher{{ + Type: silencepb.Matcher_EQUAL, Name: "team", Pattern: "platform", + }}}}, + } + event := NewSilenceCreatedEvent(silence) -func TestMatchersAsProto(t *testing.T) { - m1, err := labels.NewMatcher(labels.MatchEqual, "env", "prod") - require.NoError(t, err) - m2, err := labels.NewMatcher(labels.MatchNotEqual, "team", "") - require.NoError(t, err) + silence.Annotations["owner"] = "changed" + silence.MatcherSets[0].Matchers[0].Pattern = "changed" + silence.ReceiverMatcherSets[0].Matchers[0].Pattern = "changed" - protos := MatchersAsProto(labels.Matchers{m1, m2}) - require.Len(t, protos, 2) - require.Equal(t, eventrecorderpb.Matcher_TYPE_EQUAL, protos[0].Type) - require.Equal(t, eventrecorderpb.Matcher_TYPE_NOT_EQUAL, protos[1].Type) + got := event.message.GetSilenceCreated().Silence + require.Equal(t, "ops", got.Annotations["owner"]) + require.Equal(t, "api", got.Matchers[0].Pattern) + require.Equal(t, "platform", got.ReceiverMatcherSets[0].Matchers[0].Pattern) } -func TestInhibitRuleAsProto(t *testing.T) { +func TestInhibitRuleSnapshot(t *testing.T) { source, err := labels.NewMatcher(labels.MatchEqual, "severity", "critical") require.NoError(t, err) target, err := labels.NewMatcher(labels.MatchEqual, "severity", "warning") require.NoError(t, err) equal := map[model.LabelName]struct{}{"cluster": {}, "alertname": {}} - proto := InhibitRuleAsProto("my-rule", labels.Matchers{source}, labels.Matchers{target}, equal) + rule := NewInhibitRule("my-rule", labels.Matchers{source}, labels.Matchers{target}, equal) + delete(equal, "cluster") + + require.Equal(t, "my-rule", rule.message.Name) + require.Equal(t, []string{"alertname", "cluster"}, rule.message.EqualLabels) + require.Equal(t, "severity", rule.message.SourceMatchers[0].Name) +} + +func TestEventTypeName(t *testing.T) { + require.Equal(t, "unknown", (EventData{}).typeName()) + require.Equal(t, "unknown", (Event{}).typeName()) + require.Equal(t, "alert_created", NewAlertCreatedEvent(nil).typeName()) +} + +func TestConstructorsHandleNilMatchers(t *testing.T) { + require.NotPanics(t, func() { + group := NewAlertGroup("", nil, "", "", labels.Matchers{nil}, "") + require.Empty(t, group.message.Matchers) + event := NewSilenceCreatedEvent(&silencepb.Silence{ + Matchers: []*silencepb.Matcher{nil}, + MatcherSets: []*silencepb.MatcherSet{nil, {Matchers: []*silencepb.Matcher{nil}}}, + ReceiverMatcherSets: []*silencepb.MatcherSet{nil, {Matchers: []*silencepb.Matcher{nil}}}, + }) + silence := event.message.GetSilenceCreated().Silence + require.Empty(t, silence.Matchers) + require.Len(t, silence.MatcherSets, 1) + require.Empty(t, silence.MatcherSets[0].Matchers) + require.Len(t, silence.ReceiverMatcherSets, 1) + require.Empty(t, silence.ReceiverMatcherSets[0].Matchers) + enveloped := event.withMetadata(nil, "", 0) + _, err := enveloped.MarshalJSON() + require.NoError(t, err) + _, err = enveloped.MarshalProtobuf() + require.NoError(t, err) + }) +} + +func TestSilenceEventPreservesLegacyMatchers(t *testing.T) { + event := NewSilenceCreatedEvent(&silencepb.Silence{ + Matchers: []*silencepb.Matcher{{Type: silencepb.Matcher_REGEXP, Name: "service", Pattern: "api.*"}}, + MatcherSets: []*silencepb.MatcherSet{{Matchers: []*silencepb.Matcher{{ + Type: silencepb.Matcher_EQUAL, Name: "fallback", Pattern: "ignored", + }}}}, + }) + + got := event.message.GetSilenceCreated().Silence.Matchers + require.Len(t, got, 1) + require.Equal(t, "service", got[0].Name) + require.Equal(t, "api.*", got[0].Pattern) +} + +func TestSilenceMatcherUnknownTypeHasNoRenderedValue(t *testing.T) { + matcher := silenceMatcherToEvents(&silencepb.Matcher{Type: silencepb.Matcher_Type(99), Name: "service", Pattern: "api"}) + require.Equal(t, events.Matcher_TYPE_UNSPECIFIED, matcher.Type) + require.Empty(t, matcher.Rendered) +} - require.Equal(t, "my-rule", proto.Name) - require.Len(t, proto.SourceMatchers, 1) - require.Equal(t, "severity", proto.SourceMatchers[0].Name) - require.Len(t, proto.TargetMatchers, 1) - require.Equal(t, "severity", proto.TargetMatchers[0].Name) - require.Equal(t, []string{"alertname", "cluster"}, proto.EqualLabels) +func TestNilMatchersAreAbsentFromJSON(t *testing.T) { + event := NewAlertGroupedEvent(NewAlertGroup("", nil, "", "", labels.Matchers{nil}, ""), NewGroupedAlertReference(1)).withMetadata(nil, "", 0) + data, err := event.MarshalJSON() + require.NoError(t, err) + + var decoded map[string]any + require.NoError(t, json.Unmarshal(data, &decoded)) + groupInfo := decoded["data"].(map[string]any)["alertGrouped"].(map[string]any)["groupInfo"].(map[string]any) + require.NotContains(t, groupInfo, "matchers") +} + +func TestEventConstructors(t *testing.T) { + group := NewAlertGroup("", nil, "", "", nil, "") + grouped := NewGroupedAlertReference(1) + rule := NewInhibitRule("", nil, nil, nil) + constructed := []EventData{ + NewAlertmanagerStartupEvent("", ""), + NewAlertmanagerShutdownEvent(), + NewAlertCreatedEvent(nil), + NewAlertGroupedEvent(group, grouped), + NewAlertResolvedEvent(group, grouped), + NewNotificationEvent(Notification{Group: group}), + NewSilenceMutedAlertEvent(nil, 0, nil), + NewSilenceCreatedEvent(nil), + NewSilenceUpdatedEvent(nil), + NewInhibitionMutedAlertEvent([]InhibitRule{rule}, 0, nil, nil), + } + + for _, event := range constructed { + require.NotNil(t, event.message.EventType) + } } diff --git a/eventrecorder/file.go b/eventrecorder/file.go index d29572de66..152072da9e 100644 --- a/eventrecorder/file.go +++ b/eventrecorder/file.go @@ -22,9 +22,6 @@ import ( "sync" "github.com/fsnotify/fsnotify" - "google.golang.org/protobuf/encoding/protojson" - - "github.com/prometheus/alertmanager/eventrecorder/eventrecorderpb" ) // FileOutputConfig configures a JSONL file event recorder output. @@ -173,8 +170,8 @@ func (fo *FileOutput) watchLoop(ready chan<- error) { // SendEvent serializes the event as a JSON line and appends it to the // file. It returns the number of bytes written (including the trailing // newline) for the bytes-written metric. -func (fo *FileOutput) SendEvent(event *eventrecorderpb.Event) (int, error) { - data, err := protojson.Marshal(event) +func (fo *FileOutput) SendEvent(event Event) (int, error) { + data, err := event.MarshalJSON() if err != nil { return 0, &serializeError{err: err} } diff --git a/eventrecorder/kafka.go b/eventrecorder/kafka.go index d60f7082b7..3abe955676 100644 --- a/eventrecorder/kafka.go +++ b/eventrecorder/kafka.go @@ -25,10 +25,7 @@ import ( "github.com/prometheus/client_golang/prometheus" commoncfg "github.com/prometheus/common/config" "github.com/twmb/franz-go/pkg/kgo" - "google.golang.org/protobuf/encoding/protojson" - "google.golang.org/protobuf/proto" - "github.com/prometheus/alertmanager/eventrecorder/eventrecorderpb" "github.com/prometheus/alertmanager/kafka" ) @@ -224,15 +221,15 @@ func (ko *KafkaOutput) Name() string { return ko.name } // SendEvent serializes the event in the configured format (JSON or // protobuf) and queues it for asynchronous delivery. It returns the // serialized size (for the bytes-written metric). -func (ko *KafkaOutput) SendEvent(event *eventrecorderpb.Event) (int, error) { +func (ko *KafkaOutput) SendEvent(event Event) (int, error) { var ( data []byte err error ) if ko.format == kafka.FormatProtobuf { - data, err = proto.Marshal(event) + data, err = event.MarshalProtobuf() } else { - data, err = protojson.Marshal(event) + data, err = event.MarshalJSON() } if err != nil { return 0, &serializeError{err: err} diff --git a/eventrecorder/kafka_test.go b/eventrecorder/kafka_test.go index 9fac564542..6e66982592 100644 --- a/eventrecorder/kafka_test.go +++ b/eventrecorder/kafka_test.go @@ -30,7 +30,7 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" "gopkg.in/yaml.v2" - "github.com/prometheus/alertmanager/eventrecorder/eventrecorderpb" + events "github.com/prometheus/alertmanager/eventrecorder/events/v2" "github.com/prometheus/alertmanager/kafka" ) @@ -106,19 +106,19 @@ func counterValue(t *testing.T, c prometheus.Counter) float64 { return m.GetCounter().GetValue() } -func sampleEvent() *eventrecorderpb.Event { - return &eventrecorderpb.Event{ +func sampleEvent() Event { + return Event{message: &events.Event{ Timestamp: timestamppb.New(time.Unix(1700000000, 0)), Instance: "test-host", - Data: &eventrecorderpb.EventData{ - EventType: &eventrecorderpb.EventData_AlertmanagerStartupEvent{ - AlertmanagerStartupEvent: &eventrecorderpb.AlertmanagerStartupEvent{ + Data: &events.EventData{ + EventType: &events.EventData_AlertmanagerStartupEvent{ + AlertmanagerStartupEvent: &events.AlertmanagerStartupEvent{ Version: "v-test", BuildContext: "test-build", }, }, }, - } + }, eventType: "alertmanager_startup_event"} } // --- tests. @@ -142,6 +142,7 @@ func TestKafkaOutput_SendEvent_JSON(t *testing.T) { require.NoError(t, err) ev := sampleEvent() + evpb := ev.protoMessage().(*events.Event) n, err := ko.SendEvent(ev) require.NoError(t, err) require.Positive(t, n) @@ -150,9 +151,9 @@ func TestKafkaOutput_SendEvent_JSON(t *testing.T) { records := readRecords(t, brokers, topic, 1, 5*time.Second) require.Len(t, records, 1) - var got eventrecorderpb.Event + var got events.Event require.NoError(t, protojson.Unmarshal(records[0].Value, &got)) - require.Equal(t, ev.Instance, got.Instance) + require.Equal(t, evpb.Instance, got.Instance) require.Equal(t, "v-test", got.GetData().GetAlertmanagerStartupEvent().GetVersion()) require.Equal(t, "test-host", string(records[0].Key)) } @@ -176,6 +177,7 @@ func TestKafkaOutput_SendEvent_Protobuf(t *testing.T) { require.NoError(t, err) ev := sampleEvent() + evpb := ev.protoMessage().(*events.Event) n, err := ko.SendEvent(ev) require.NoError(t, err) require.Positive(t, n) @@ -184,10 +186,10 @@ func TestKafkaOutput_SendEvent_Protobuf(t *testing.T) { records := readRecords(t, brokers, topic, 1, 5*time.Second) require.Len(t, records, 1) - var got eventrecorderpb.Event + var got events.Event require.NoError(t, proto.Unmarshal(records[0].Value, &got)) - require.Equal(t, ev.Instance, got.Instance) - require.Equal(t, ev.Timestamp.AsTime().Unix(), got.Timestamp.AsTime().Unix()) + require.Equal(t, evpb.Instance, got.Instance) + require.Equal(t, evpb.Timestamp.AsTime().Unix(), got.Timestamp.AsTime().Unix()) require.Equal(t, "v-test", got.GetData().GetAlertmanagerStartupEvent().GetVersion()) require.Equal(t, "test-host", string(records[0].Key)) } diff --git a/eventrecorder/recorder.go b/eventrecorder/recorder.go index ce3161ac36..3c11bc78b8 100644 --- a/eventrecorder/recorder.go +++ b/eventrecorder/recorder.go @@ -33,7 +33,6 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" "github.com/prometheus/alertmanager/cluster" - "github.com/prometheus/alertmanager/eventrecorder/eventrecorderpb" ) const ( @@ -69,12 +68,9 @@ type Recorder struct { } // writeRequest is a single event queued for background serialization -// and writing. It carries the proto message so that the expensive -// protojson.Marshal call happens in the write-loop goroutine, not on -// the caller's hot path. +// and writing. type writeRequest struct { - event *eventrecorderpb.Event - eventType string + event Event } // sharedRecorder holds the mutable state shared by all copies of a @@ -104,7 +100,8 @@ type cfgUpdateMsg struct { // Destination is a single event destination. Each implementation // owns its own serialization: it receives the structured event and is -// responsible for encoding it (e.g. JSON or protobuf) and delivering it. +// responsible for encoding it with Event.MarshalJSON or +// Event.MarshalProtobuf and delivering it. // // Owning serialization per destination — rather than handing every // destination a pre-encoded JSON blob — avoids the footgun of, say, a @@ -119,7 +116,7 @@ type Destination interface { // delivery error. A serialization failure should be returned // wrapped in *serializeError so the recorder can attribute it to // the serialize-errors metric. - SendEvent(event *eventrecorderpb.Event) (size int, err error) + SendEvent(event Event) (size int, err error) io.Closer } @@ -277,57 +274,51 @@ func (c *sharedRecorder) marshalAndSend(req writeRequest, outputs []Destination) size, err := out.SendEvent(req.event) if err != nil { if _, ok := errors.AsType[*serializeError](err); ok { - c.metrics.eventSerializeErrors.WithLabelValues(req.eventType).Inc() + c.metrics.eventSerializeErrors.WithLabelValues(req.event.typeName()).Inc() } - c.metrics.eventsRecorded.WithLabelValues(req.eventType, name, "error").Inc() - c.logger.Error("Failed to write event", "event_type", req.eventType, "output", name, "err", err) + c.metrics.eventsRecorded.WithLabelValues(req.event.typeName(), name, "error").Inc() + c.logger.Error("Failed to write event", "event_type", req.event.typeName(), "output", name, "err", err) continue } - c.metrics.eventsRecorded.WithLabelValues(req.eventType, name, "success").Inc() - c.metrics.eventRecorderBytesWritten.WithLabelValues(req.eventType, name).Add(float64(size)) + c.metrics.eventsRecorded.WithLabelValues(req.event.typeName(), name, "success").Inc() + c.metrics.eventRecorderBytesWritten.WithLabelValues(req.event.typeName(), name).Add(float64(size)) } } -// RecordEvent wraps the event and places it on a bounded queue for -// background serialization and delivery. If the queue is full the -// event is dropped (never blocks the caller). Recording only occurs -// when the context has been decorated with WithEventRecording. +// RecordEvent wraps the event data with metadata and places it on a bounded +// queue for background serialization and delivery. If the queue is full the +// event is dropped (never blocks the caller). Recording only occurs when the +// context has been decorated with WithEventRecording. // -// The event is supplied as a builder function rather than a value so -// that callers on hot read paths do not pay to construct an event -// (protobuf conversions, fingerprint slices, etc.) that would only be -// discarded when recording is disabled. The builder is invoked only +// The event data is supplied as a builder function rather than a value so +// that callers on hot read paths do not pay to snapshot alerts and fingerprints +// for an event that would only be discarded when recording is disabled. The +// builder is invoked only // after the recording gates pass, and exactly once. // // The expensive protojson.Marshal call is deferred to the write-loop -// goroutine so that the caller's hot path only pays for the proto -// wrapping and a channel send. -func (r Recorder) RecordEvent(ctx context.Context, build func() *eventrecorderpb.EventData) { +// goroutine so that the caller's hot path only pays for snapshot construction +// and a channel send. +func (r Recorder) RecordEvent(ctx context.Context, build func() EventData) { if r.core == nil || r.core.events == nil { return } if !EventRecordingEnabled(ctx) { return } - - event := build() - eventType := extractEventType(event) - - wrappedEvent := &eventrecorderpb.Event{ - Timestamp: timestamppb.Now(), - Instance: r.core.instance, - Data: event, - } - + data := build() + clusterPosition := uint64(0) if peer := r.core.peer.Load(); peer != nil { - wrappedEvent.ClusterPosition = uint32(peer.Position()) + clusterPosition = uint64(peer.Position()) } + event := data.withMetadata(timestamppb.Now(), r.core.instance, clusterPosition) + request := writeRequest{event: event} select { - case r.core.events <- writeRequest{event: wrappedEvent, eventType: eventType}: + case r.core.events <- request: default: // Queue full; drop event to avoid blocking alertmanager. - r.core.metrics.eventsDropped.WithLabelValues(eventType).Inc() + r.core.metrics.eventsDropped.WithLabelValues(event.typeName()).Inc() } } diff --git a/eventrecorder/recorder_test.go b/eventrecorder/recorder_test.go index 9dfa797a15..cc3cb3d52e 100644 --- a/eventrecorder/recorder_test.go +++ b/eventrecorder/recorder_test.go @@ -21,15 +21,13 @@ import ( "time" "github.com/stretchr/testify/require" - - "github.com/prometheus/alertmanager/eventrecorder/eventrecorderpb" ) // mockDestination records all events written to it. type mockDestination struct { mu sync.Mutex name string - events []*eventrecorderpb.Event + events []Event } func newMockDestination(name string) *mockDestination { @@ -37,7 +35,7 @@ func newMockDestination(name string) *mockDestination { } func (m *mockDestination) Name() string { return m.name } -func (m *mockDestination) SendEvent(event *eventrecorderpb.Event) (int, error) { +func (m *mockDestination) SendEvent(event Event) (int, error) { m.mu.Lock() defer m.mu.Unlock() m.events = append(m.events, event) @@ -51,17 +49,15 @@ func (m *mockDestination) eventCount() int { return len(m.events) } -func startupEvent() *eventrecorderpb.EventData { - return &eventrecorderpb.EventData{ - EventType: &eventrecorderpb.EventData_AlertmanagerStartupEvent{ - AlertmanagerStartupEvent: &eventrecorderpb.AlertmanagerStartupEvent{ - Version: "test", - }, - }, - } +func startupEvent() EventData { + return NewAlertmanagerStartupEvent("test", "") } func newTestRecorder(outputs ...Destination) Recorder { + return newTestRecorderWithConfig(Config{}, outputs...) +} + +func newTestRecorderWithConfig(cfg Config, outputs ...Destination) Recorder { core := &sharedRecorder{ instance: "test", logger: slog.Default(), @@ -71,7 +67,7 @@ func newTestRecorder(outputs ...Destination) Recorder { done: make(chan struct{}), } core.wg.Add(1) - go core.writeLoop(outputs, Config{}) + go core.writeLoop(outputs, cfg) return Recorder{core: core} } @@ -186,6 +182,37 @@ func TestEventRecorderConfigEqual_TypeMismatch(t *testing.T) { "outputs of different types must compare unequal") } +func TestRecorderOutputSchema(t *testing.T) { + out := newMockDestination("test:mock") + rec := newTestRecorder(out) + defer rec.Close() + + rec.RecordEvent(recordCtx(), startupEvent) + require.Eventually(t, func() bool { + out.mu.Lock() + defer out.mu.Unlock() + if len(out.events) != 1 { + return false + } + return out.events[0].message != nil + }, time.Second, 10*time.Millisecond) +} + +func TestRecordEventBuildsEventFromEventData(t *testing.T) { + out := newMockDestination("test:mock") + rec := newTestRecorder(out) + defer rec.Close() + + built := NewAlertmanagerShutdownEvent() + rec.RecordEvent(recordCtx(), func() EventData { return built }) + require.Eventually(t, func() bool { return out.eventCount() == 1 }, time.Second, 10*time.Millisecond) + + out.mu.Lock() + defer out.mu.Unlock() + require.Same(t, built.message, out.events[0].message.Data) + require.NotNil(t, out.events[0].message.Timestamp) +} + // marshalAndSend hands the structured event to every destination; the // destination owns serialization. Verify a destination receives the // event (and the recorder records it). @@ -199,7 +226,9 @@ func TestMarshalAndSend_DeliversEvent(t *testing.T) { require.Eventually(t, func() bool { out.mu.Lock() defer out.mu.Unlock() - return len(out.events) == 1 && - out.events[0].GetData().GetAlertmanagerStartupEvent() != nil + if len(out.events) != 1 { + return false + } + return out.events[0].message.GetData().GetAlertmanagerStartupEvent() != nil }, time.Second, 10*time.Millisecond) } diff --git a/eventrecorder/stdout.go b/eventrecorder/stdout.go index 1b2652c468..51e4d92fe6 100644 --- a/eventrecorder/stdout.go +++ b/eventrecorder/stdout.go @@ -15,10 +15,6 @@ package eventrecorder import ( "os" - - "google.golang.org/protobuf/encoding/protojson" - - "github.com/prometheus/alertmanager/eventrecorder/eventrecorderpb" ) // StdoutOutputConfig configures a stdout event recorder output. @@ -45,8 +41,8 @@ func (s *StdoutOutput) Name() string { return "stdout" } // It returns the byte count written (including the trailing newline) and // any write error encountered. A serialization failure is wrapped in // serializeError so the recorder attributes it to the correct metric. -func (s *StdoutOutput) SendEvent(event *eventrecorderpb.Event) (int, error) { - data, err := protojson.Marshal(event) +func (s *StdoutOutput) SendEvent(event Event) (int, error) { + data, err := event.MarshalJSON() if err != nil { return 0, &serializeError{err: err} } diff --git a/eventrecorder/webhook.go b/eventrecorder/webhook.go index 1a4972ae1b..0fc36c5fdd 100644 --- a/eventrecorder/webhook.go +++ b/eventrecorder/webhook.go @@ -28,10 +28,8 @@ import ( "github.com/prometheus/client_golang/prometheus" commoncfg "github.com/prometheus/common/config" "github.com/prometheus/common/model" - "google.golang.org/protobuf/encoding/protojson" amcommoncfg "github.com/prometheus/alertmanager/config/common" - "github.com/prometheus/alertmanager/eventrecorder/eventrecorderpb" ) // WebhookOutputConfig configures an HTTP webhook event recorder output. @@ -297,8 +295,8 @@ func (wo *WebhookOutput) Name() string { // a worker. It returns the serialized size (for the bytes-written // metric). If the internal queue is full the event is dropped and // counted via the output-drops metric. -func (wo *WebhookOutput) SendEvent(event *eventrecorderpb.Event) (int, error) { - data, err := protojson.Marshal(event) +func (wo *WebhookOutput) SendEvent(event Event) (int, error) { + data, err := event.MarshalJSON() if err != nil { return 0, &serializeError{err: err} } diff --git a/eventrecorder/webhook_test.go b/eventrecorder/webhook_test.go index 2cbc79f432..37b65ea041 100644 --- a/eventrecorder/webhook_test.go +++ b/eventrecorder/webhook_test.go @@ -194,7 +194,7 @@ func TestWebhookOutput_BatchingByEncodedSize(t *testing.T) { defer srv.Close() event := sampleEvent() - encoded, err := protojson.Marshal(event) + encoded, err := protojson.Marshal(event.protoMessage()) require.NoError(t, err) out, err := NewWebhookOutput(WebhookOutputConfig{ URL: mustParseURL(t, srv.URL), diff --git a/inhibit/inhibit.go b/inhibit/inhibit.go index c441054be6..494322dc64 100644 --- a/inhibit/inhibit.go +++ b/inhibit/inhibit.go @@ -29,7 +29,6 @@ import ( amcommoncfg "github.com/prometheus/alertmanager/config/common" "github.com/prometheus/alertmanager/eventrecorder" - "github.com/prometheus/alertmanager/eventrecorder/eventrecorderpb" "github.com/prometheus/alertmanager/marker" "github.com/prometheus/alertmanager/pkg/labels" "github.com/prometheus/alertmanager/provider" @@ -223,9 +222,9 @@ func (ih *Inhibitor) Mutes(ctx context.Context, lset model.LabelSet) bool { ), ) - ih.recorder.RecordEvent(ctx, func() *eventrecorderpb.EventData { + ih.recorder.RecordEvent(ctx, func() eventrecorder.EventData { return eventrecorder.NewInhibitionMutedAlertEvent( - []*eventrecorderpb.InhibitRule{eventrecorder.InhibitRuleAsProto(r.Name, r.SourceMatchers, r.TargetMatchers, r.Equal)}, + []eventrecorder.InhibitRule{eventrecorder.NewInhibitRule(r.Name, r.SourceMatchers, r.TargetMatchers, r.Equal)}, fp, lset, []model.Fingerprint{inhibitedByFP}, ) diff --git a/notify/event.go b/notify/event.go index 740cd0e77e..e93a47d396 100644 --- a/notify/event.go +++ b/notify/event.go @@ -13,131 +13,102 @@ package notify -// This file contains helpers for constructing event recorder protobuf messages +// This file contains helpers for constructing event recorder events // from the notification pipeline context. It lives in the notify package // because it accesses unexported context keys (keyFiringAlerts, etc.). import ( "context" - "google.golang.org/protobuf/types/known/durationpb" - "github.com/prometheus/alertmanager/eventrecorder" - "github.com/prometheus/alertmanager/eventrecorder/eventrecorderpb" "github.com/prometheus/alertmanager/types" ) -func groupedAlertAsProto(alert *types.Alert) *eventrecorderpb.GroupedAlert { - return &eventrecorderpb.GroupedAlert{ - Hash: hashAlert(alert), - Details: eventrecorder.AlertAsProto(alert), - } +func groupedAlertEvent(alert *types.Alert) eventrecorder.GroupedAlert { + return eventrecorder.NewGroupedAlert(hashAlert(alert), alert) } -func extractAlertGroupInfo(ctx context.Context) *eventrecorderpb.AlertGroupInfo { +func extractAlertGroupInfo(ctx context.Context) eventrecorder.AlertGroup { groupKey, _ := ExtractGroupKey(ctx) receiverName, _ := ReceiverName(ctx) groupLabels, _ := GroupLabels(ctx) groupMatchers, _ := GroupMatchers(ctx) aggrGroupID, _ := AggrGroupID(ctx) - return &eventrecorderpb.AlertGroupInfo{ - GroupKey: groupKey.String(), - GroupLabels: eventrecorder.LabelSetAsProto(groupLabels), - GroupId: groupKey.Hash(), - ReceiverName: receiverName, - Matchers: eventrecorder.MatchersAsProto(groupMatchers), - GroupUuid: aggrGroupID, - } + return eventrecorder.NewAlertGroup( + groupKey.String(), groupLabels, groupKey.Hash(), receiverName, groupMatchers, aggrGroupID, + ) } -func extractGroupedAlerts(ctx context.Context, key notifyKey) []*eventrecorderpb.GroupedAlert { - var result []*eventrecorderpb.GroupedAlert +func extractGroupedAlerts(ctx context.Context, key notifyKey) []eventrecorder.GroupedAlert { + var result []eventrecorder.GroupedAlert if list, ok := ctx.Value(key).([]uint64); ok { for _, hash := range list { - result = append(result, &eventrecorderpb.GroupedAlert{Hash: hash}) + result = append(result, eventrecorder.NewGroupedAlertReference(hash)) } } return result } -func extractMutedGroupedAlerts(ctx context.Context) []*eventrecorderpb.GroupedAlert { - var result []*eventrecorderpb.GroupedAlert +func extractMutedGroupedAlerts(ctx context.Context) []eventrecorder.GroupedAlert { + var result []eventrecorder.GroupedAlert if muted, ok := MutedAlerts(ctx); ok { for hash := range muted { - result = append(result, &eventrecorderpb.GroupedAlert{Hash: hash}) + result = append(result, eventrecorder.NewGroupedAlertReference(hash)) } } return result } -func notifyReasonToProto(reason NotifyReason) eventrecorderpb.NotifyReason { +func notifyReasonToEvent(reason NotifyReason) eventrecorder.NotificationReason { switch reason { case ReasonFirstNotification: - return eventrecorderpb.NotifyReason_NOTIFY_REASON_FIRST_NOTIFICATION + return eventrecorder.NotificationReasonFirstNotification case ReasonNewAlertsInGroup: - return eventrecorderpb.NotifyReason_NOTIFY_REASON_NEW_ALERTS_IN_GROUP + return eventrecorder.NotificationReasonNewAlertsInGroup case ReasonAllAlertsResolved: - return eventrecorderpb.NotifyReason_NOTIFY_REASON_ALL_ALERTS_RESOLVED + return eventrecorder.NotificationReasonAllAlertsResolved case ReasonNewResolvedAlerts: - return eventrecorderpb.NotifyReason_NOTIFY_REASON_NEW_RESOLVED_ALERTS + return eventrecorder.NotificationReasonNewResolvedAlerts case ReasonRepeatIntervalElapsed: - return eventrecorderpb.NotifyReason_NOTIFY_REASON_REPEAT_INTERVAL_ELAPSED + return eventrecorder.NotificationReasonRepeatIntervalElapsed default: - return eventrecorderpb.NotifyReason_NOTIFY_REASON_UNSPECIFIED + return eventrecorder.NotificationReasonUnspecified } } -// NewNotificationEvent constructs a NotificationEvent from the pipeline +// NewNotificationEvent constructs notification event data from the pipeline // context after a successful notification delivery. -func NewNotificationEvent(ctx context.Context, alerts []*types.Alert, integration Integration) *eventrecorderpb.EventData { - groupedAlerts := make([]*eventrecorderpb.GroupedAlert, 0, len(alerts)) +func NewNotificationEvent(ctx context.Context, alerts []*types.Alert, integration Integration) eventrecorder.EventData { + groupedAlerts := make([]eventrecorder.GroupedAlert, 0, len(alerts)) for _, alert := range alerts { - groupedAlerts = append(groupedAlerts, groupedAlertAsProto(alert)) + groupedAlerts = append(groupedAlerts, groupedAlertEvent(alert)) } notifyReason, _ := NotificationReason(ctx) repeatInterval, _ := RepeatInterval(ctx) flushID, _ := FlushID(ctx) - notification := &eventrecorderpb.NotificationEvent{ + return eventrecorder.NewNotificationEvent(eventrecorder.Notification{ Alerts: groupedAlerts, FiringAlerts: extractGroupedAlerts(ctx, keyFiringAlerts), ResolvedAlerts: extractGroupedAlerts(ctx, keyResolvedAlerts), MutedAlerts: extractMutedGroupedAlerts(ctx), - GroupInfo: extractAlertGroupInfo(ctx), - RepeatInterval: durationpb.New(repeatInterval), - Reason: notifyReasonToProto(notifyReason), - FlushId: flushID, - Integration: &eventrecorderpb.Integration{ - Name: integration.Name(), - Index: int64(integration.Index()), - }, - } - - return &eventrecorderpb.EventData{ - EventType: &eventrecorderpb.EventData_Notification{Notification: notification}, - } + Group: extractAlertGroupInfo(ctx), + RepeatInterval: repeatInterval, + Reason: notifyReasonToEvent(notifyReason), + FlushID: flushID, + Integration: integration.Name(), + IntegrationIdx: int64(integration.Index()), + }) } -func NewAlertResolvedEvent(groupInfo *eventrecorderpb.AlertGroupInfo, alert *types.Alert) *eventrecorderpb.EventData { - return &eventrecorderpb.EventData{ - EventType: &eventrecorderpb.EventData_AlertResolved{ - AlertResolved: &eventrecorderpb.AlertResolvedEvent{ - Alert: groupedAlertAsProto(alert), - GroupInfo: groupInfo, - }, - }, - } +// NewAlertResolvedEvent constructs alert-resolved event data. +func NewAlertResolvedEvent(groupInfo eventrecorder.AlertGroup, alert *types.Alert) eventrecorder.EventData { + return eventrecorder.NewAlertResolvedEvent(groupInfo, groupedAlertEvent(alert)) } -func NewAlertGroupedEvent(groupInfo *eventrecorderpb.AlertGroupInfo, alert *types.Alert) *eventrecorderpb.EventData { - return &eventrecorderpb.EventData{ - EventType: &eventrecorderpb.EventData_AlertGrouped{ - AlertGrouped: &eventrecorderpb.AlertGroupedEvent{ - Alert: groupedAlertAsProto(alert), - GroupInfo: groupInfo, - }, - }, - } +// NewAlertGroupedEvent constructs alert-grouped event data. +func NewAlertGroupedEvent(groupInfo eventrecorder.AlertGroup, alert *types.Alert) eventrecorder.EventData { + return eventrecorder.NewAlertGroupedEvent(groupInfo, groupedAlertEvent(alert)) } diff --git a/notify/retry_stage.go b/notify/retry_stage.go index d535042067..fb3b93ef0c 100644 --- a/notify/retry_stage.go +++ b/notify/retry_stage.go @@ -27,7 +27,6 @@ import ( "github.com/prometheus/alertmanager/alert" "github.com/prometheus/alertmanager/eventrecorder" - "github.com/prometheus/alertmanager/eventrecorder/eventrecorderpb" ) // RetryStage notifies via passed integration with exponential backoff until it @@ -179,7 +178,7 @@ func (r RetryStage) exec(ctx context.Context, l *slog.Logger, alerts ...*alert.A l.Info("Notify success") } - r.recorder.RecordEvent(ctx, func() *eventrecorderpb.EventData { + r.recorder.RecordEvent(ctx, func() eventrecorder.EventData { return NewNotificationEvent(ctx, sent, r.integration) }) return ctx, alerts, nil diff --git a/proto/eventrecorder/events/v2/events.proto b/proto/eventrecorder/events/v2/events.proto new file mode 100644 index 0000000000..5d1ef36c46 --- /dev/null +++ b/proto/eventrecorder/events/v2/events.proto @@ -0,0 +1,186 @@ +syntax = "proto3"; + +package events.v2; + +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; + +option go_package = "github.com/prometheus/alertmanager/eventrecorder/events/v2;eventsv2"; + +// Event is the top-level envelope written to each event recorder output. +message Event { + google.protobuf.Timestamp timestamp = 1 [json_name = "@timestamp"]; + string instance = 2; + EventData data = 3; + uint64 cluster_position = 4; +} + +// EventData carries the payload for a single event recorder entry. +message EventData { + oneof event_type { + AlertmanagerStartupEvent alertmanager_startup_event = 1; + AlertmanagerShutdownEvent alertmanager_shutdown_event = 2; + AlertCreatedEvent alert_created = 3; + AlertResolvedEvent alert_resolved = 4; + AlertGroupedEvent alert_grouped = 5; + NotificationEvent notification = 6; + SilenceCreatedEvent silence_created = 7; + SilenceUpdatedEvent silence_updated = 8; + SilenceMutedAlertEvent silence_muted_alert = 9; + InhibitionMutedAlertEvent inhibition_muted_alert = 10; + } +} + +// AlertmanagerStartupEvent is emitted once when the process starts. +message AlertmanagerStartupEvent { + string version = 1; + string build_context = 2; +} + +// AlertmanagerShutdownEvent is emitted when the process shuts down gracefully. +message AlertmanagerShutdownEvent {} + +// Alert represents a snapshot of an alert at the time the event was recorded. +message Alert { + uint64 fingerprint = 1; + string name = 2; + map labels = 3; + map annotations = 4; + google.protobuf.Timestamp starts_at = 5; + google.protobuf.Timestamp ends_at = 6; + bool resolved = 7; +} + +// GroupedAlert is a reference to an alert within an aggregation group. +message GroupedAlert { + uint64 hash = 1; + optional Alert details = 2; +} + +// AlertGroupInfo describes an alert's aggregation group context. +message AlertGroupInfo { + string group_key = 1; + map group_labels = 2; + string group_id = 3; + string receiver_name = 4; + repeated Matcher matchers = 5; + string group_uuid = 6; +} + +// AlertCreatedEvent is emitted when a new alert is inserted. +message AlertCreatedEvent { + Alert alert = 1; +} + +// AlertResolvedEvent is emitted when a resolved alert leaves its group. +message AlertResolvedEvent { + GroupedAlert alert = 1; + AlertGroupInfo group_info = 2; +} + +// AlertGroupedEvent is emitted when an alert first enters a group. +message AlertGroupedEvent { + GroupedAlert alert = 1; + AlertGroupInfo group_info = 2; +} + +// NotifyReason describes why a notification was sent. +enum NotifyReason { + NOTIFY_REASON_UNSPECIFIED = 0; + NOTIFY_REASON_FIRST_NOTIFICATION = 1; + NOTIFY_REASON_NEW_ALERTS_IN_GROUP = 2; + NOTIFY_REASON_NEW_RESOLVED_ALERTS = 3; + NOTIFY_REASON_ALL_ALERTS_RESOLVED = 4; + NOTIFY_REASON_REPEAT_INTERVAL_ELAPSED = 5; +} + +// Integration identifies a notification integration. +message Integration { + string name = 1; + int64 index = 2; +} + +// NotificationEvent is emitted after a notification is delivered. +message NotificationEvent { + repeated GroupedAlert alerts = 1; + repeated GroupedAlert firing_alerts = 2; + repeated GroupedAlert resolved_alerts = 3; + repeated GroupedAlert muted_alerts = 4; + AlertGroupInfo group_info = 5; + google.protobuf.Duration repeat_interval = 6; + NotifyReason reason = 7; + uint64 flush_id = 8; + Integration integration = 9; +} + +// Silence is a snapshot of a silence definition. +message Silence { + string id = 1; + repeated Matcher matchers = 2; + map annotations = 3; + google.protobuf.Timestamp starts_at = 4; + google.protobuf.Timestamp ends_at = 5; + google.protobuf.Timestamp updated_at = 6; + string created_by = 7; + string comment = 8; + repeated MatcherSet matcher_sets = 9; + repeated MatcherSet receiver_matcher_sets = 10; +} + +// Matcher defines a single label matching rule. +message Matcher { + enum Type { + TYPE_UNSPECIFIED = 0; + TYPE_EQUAL = 1; + TYPE_REGEXP = 2; + TYPE_NOT_EQUAL = 3; + TYPE_NOT_REGEXP = 4; + } + + Type type = 1; + string name = 2; + string pattern = 3; + string rendered = 4; +} + +// MatcherSet is a conjunction of matchers. +message MatcherSet { + repeated Matcher matchers = 1; +} + +// SilenceCreatedEvent is emitted when a silence is created. +message SilenceCreatedEvent { + Silence silence = 1; +} + +// SilenceUpdatedEvent is emitted when a silence is modified. +message SilenceUpdatedEvent { + Silence silence = 1; +} + +// MutedAlert identifies an alert suppressed by a silence or inhibition rule. +message MutedAlert { + map labels = 1; + uint64 fingerprint = 2; +} + +// SilenceMutedAlertEvent is emitted when a silence suppresses an alert. +message SilenceMutedAlertEvent { + Silence silence = 1; + MutedAlert muted_alert = 2; +} + +// InhibitRule is a snapshot of an inhibition rule definition. +message InhibitRule { + repeated Matcher source_matchers = 1; + repeated Matcher target_matchers = 2; + repeated string equal_labels = 3; + string name = 4; +} + +// InhibitionMutedAlertEvent is emitted when inhibition suppresses an alert. +message InhibitionMutedAlertEvent { + repeated InhibitRule inhibit_rules = 1; + MutedAlert muted_alert = 2; + repeated uint64 inhibiting_fingerprints = 3; +} diff --git a/provider/mem/mem.go b/provider/mem/mem.go index 7646eb9fdf..f392a0c70d 100644 --- a/provider/mem/mem.go +++ b/provider/mem/mem.go @@ -29,7 +29,6 @@ import ( "go.opentelemetry.io/otel/trace" "github.com/prometheus/alertmanager/eventrecorder" - "github.com/prometheus/alertmanager/eventrecorder/eventrecorderpb" "github.com/prometheus/alertmanager/featurecontrol" "github.com/prometheus/alertmanager/provider" "github.com/prometheus/alertmanager/store" @@ -348,7 +347,7 @@ func (a *Alerts) Put(ctx context.Context, alerts ...*types.Alert) error { a.callback.PostStore(alert, existing) if !existing { - a.recorder.RecordEvent(ctx, func() *eventrecorderpb.EventData { + a.recorder.RecordEvent(ctx, func() eventrecorder.EventData { return eventrecorder.NewAlertCreatedEvent(alert) }) } diff --git a/silence/silence.go b/silence/silence.go index c0d089c2e1..26d21567f7 100644 --- a/silence/silence.go +++ b/silence/silence.go @@ -47,7 +47,6 @@ import ( "github.com/prometheus/alertmanager/alert" "github.com/prometheus/alertmanager/cluster" "github.com/prometheus/alertmanager/eventrecorder" - "github.com/prometheus/alertmanager/eventrecorder/eventrecorderpb" "github.com/prometheus/alertmanager/marker" "github.com/prometheus/alertmanager/matcher/compat" "github.com/prometheus/alertmanager/pkg/labels" @@ -285,9 +284,9 @@ func (s *Silencer) Mutes(ctx context.Context, lset model.LabelSet) bool { activeIDs = append(activeIDs, sil.Id) allIDs = append(allIDs, sil.Id) - s.recorder.RecordEvent(ctx, func() *eventrecorderpb.EventData { + s.recorder.RecordEvent(ctx, func() eventrecorder.EventData { return eventrecorder.NewSilenceMutedAlertEvent( - eventrecorder.SilenceAsProto(sil), fp, lset, + sil, fp, lset, ) }) default: @@ -876,10 +875,8 @@ func (s *Silences) Set(ctx context.Context, sil *pb.Silence) error { return err } if changed { - s.recorder.RecordEvent(ctx, func() *eventrecorderpb.EventData { - return eventrecorder.NewSilenceUpdatedEvent( - eventrecorder.SilenceAsProto(sil), - ) + s.recorder.RecordEvent(ctx, func() eventrecorder.EventData { + return eventrecorder.NewSilenceUpdatedEvent(sil) }) } return nil @@ -926,10 +923,8 @@ func (s *Silences) Set(ctx context.Context, sil *pb.Silence) error { return err } if added { - s.recorder.RecordEvent(ctx, func() *eventrecorderpb.EventData { - return eventrecorder.NewSilenceCreatedEvent( - eventrecorder.SilenceAsProto(sil), - ) + s.recorder.RecordEvent(ctx, func() eventrecorder.EventData { + return eventrecorder.NewSilenceCreatedEvent(sil) }) } return nil