introduce telemetry alerts

Introduces a new type of alert- internal_telemetry- which can be used separately from user-visible alerts to provide more precise contextual identification.
This commit is contained in:
ryanfkeepers 2024-02-12 14:00:24 -07:00
parent 03048a6ca8
commit 4249e4168f
3 changed files with 63 additions and 5 deletions

View File

@ -75,6 +75,8 @@ func LogFaultErrors(ctx context.Context, fe *fault.Errors, prefix string) {
} }
for i, alert := range fe.Alerts { for i, alert := range fe.Alerts {
if alert.Type == fault.AlertTypeUserVisible {
log.With("alert", alert).Infof("%s alert %d of %d: %s", pfxMsg, i+1, la, alert.Message) log.With("alert", alert).Infof("%s alert %d of %d: %s", pfxMsg, i+1, la, alert.Message)
} }
} }
}

View File

@ -8,6 +8,14 @@ const (
AlertPreviousPathCollision = "previous_path_collision" AlertPreviousPathCollision = "previous_path_collision"
) )
type alertType string
const (
AlertTypeUnknown = ""
AlertTypeUserVisible = "user_visible"
AlertTypeInternalTelemetry = "internal_telemetry"
)
var _ print.Printable = &Alert{} var _ print.Printable = &Alert{}
// Alerts are informational-only notifications. The purpose of alerts is to // Alerts are informational-only notifications. The purpose of alerts is to
@ -17,6 +25,7 @@ var _ print.Printable = &Alert{}
// be in use. IE: Errors do not also get alerts, since the error itself is a // be in use. IE: Errors do not also get alerts, since the error itself is a
// form of end-user communication already. // form of end-user communication already.
type Alert struct { type Alert struct {
Type alertType `json:"type"`
Item Item `json:"item"` Item Item `json:"item"`
Message string `json:"message"` Message string `json:"message"`
} }
@ -62,12 +71,39 @@ func (a Alert) Values(bool) []string {
return []string{"Alert", a.Message, cn, a.Item.Name, a.Item.ID} return []string{"Alert", a.Message, cn, a.Item.Name, a.Item.ID}
} }
func NewAlert(message, namespace, itemID, name string, addtl map[string]any) *Alert { // NewAlert produces a USER VISIBLE alert. Use this if you want the end user
// to see the alert at the end of the run.
func NewAlert(
message, namespace, entityID, name string,
addtl map[string]any,
) *Alert {
return &Alert{ return &Alert{
Type: AlertTypeUserVisible,
Message: message, Message: message,
Item: Item{ Item: Item{
Namespace: namespace, Namespace: namespace,
ID: itemID, ID: entityID,
Name: name,
Additional: addtl,
},
}
}
// NewTelemetryAlert produces a NON-USER VISIBLE alert. Use this if you want
// to create an alert event for additional tracking and telemetry without the
// user seeing the details at the end of the run. Note that this data is still
// accessible from the backup metadata, so it will be possible for users to
// see it, if wanted/necessary. But they do have to go looking for it specifically.
func NewTelemetryAlert(
message, namespace, entityID, name string,
addtl map[string]any,
) *Alert {
return &Alert{
Type: AlertTypeInternalTelemetry,
Message: message,
Item: Item{
Namespace: namespace,
ID: entityID,
Name: name, Name: name,
Additional: addtl, Additional: addtl,
}, },

View File

@ -48,6 +48,26 @@ func (suite *AlertUnitSuite) TestNewAlert() {
a := fault.NewAlert("message-to-show", "ns", "item_id", "item_name", addtl) a := fault.NewAlert("message-to-show", "ns", "item_id", "item_name", addtl)
expect := fault.Alert{ expect := fault.Alert{
Type: fault.AlertTypeUserVisible,
Item: fault.Item{
Namespace: "ns",
ID: "item_id",
Name: "item_name",
Additional: addtl,
},
Message: "message-to-show",
}
assert.Equal(t, expect, *a)
}
func (suite *AlertUnitSuite) TestNewTelemetryAlert() {
t := suite.T()
addtl := map[string]any{"foo": "bar"}
a := fault.NewTelemetryAlert("message-to-show", "ns", "item_id", "item_name", addtl)
expect := fault.Alert{
Type: fault.AlertTypeInternalTelemetry,
Item: fault.Item{ Item: fault.Item{
Namespace: "ns", Namespace: "ns",
ID: "item_id", ID: "item_id",