[MM-57066][MM-57329] Added metrics for all notification stopping points, consolidated categories between metrics and logging (#26799)
* [MM-57066] Add metric counters for notification events * Some small changes * Account for Metrics() sometimes being nil * Fix test (again) * Fix more tests * A few changes from testing - added success counter * Missed a mock * Lint * Add feature flag for notification monitoring
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
0ce5def8e2
Коммит
02e23a3275
@@ -24,22 +24,12 @@ import (
|
||||
)
|
||||
|
||||
type notificationType string
|
||||
type notifyPropsReason string
|
||||
type statusReason string
|
||||
|
||||
const (
|
||||
notificationTypeClear notificationType = "clear"
|
||||
notificationTypeMessage notificationType = "message"
|
||||
notificationTypeUpdateBadge notificationType = "update_badge"
|
||||
notificationTypeDummy notificationType = "dummy"
|
||||
|
||||
NotifyPropsReasonChannelMuted notifyPropsReason = "channel_muted"
|
||||
NotifyPropsReasonSystemMessage notifyPropsReason = "system_message"
|
||||
NotifyPropsReasonSetToNone notifyPropsReason = "notify_props_set_to_note"
|
||||
NotifyPropsReasonSetToMention notifyPropsReason = "notify_props_set_to_mention_and_was_not_mentioned"
|
||||
|
||||
StatusReasonDNDOrOOO statusReason = "status_is_dnd_or_ooo"
|
||||
StatusReasonIsActive statusReason = "user_is_active_on_channel"
|
||||
)
|
||||
|
||||
type PushNotificationsHub struct {
|
||||
@@ -107,10 +97,12 @@ func (a *App) sendPushNotificationToAllSessions(msg *model.PushNotification, use
|
||||
|
||||
if rejectionReason != "" {
|
||||
// Notifications rejected by a plugin should not be considered errors
|
||||
a.NotificationsLog().Info("Notification rejected by plugin",
|
||||
mlog.String("type", model.TypePush),
|
||||
mlog.String("status", model.StatusNotSent),
|
||||
mlog.String("reason", rejectionReason),
|
||||
// This is likely normal operation so no need for metrics here
|
||||
a.NotificationsLog().Debug("Notification rejected by plugin",
|
||||
mlog.String("type", model.NotificationTypePush),
|
||||
mlog.String("status", model.NotificationStatusNotSent),
|
||||
mlog.String("reason", model.NotificationReasonRejectedByPlugin),
|
||||
mlog.String("rejection_reason", rejectionReason),
|
||||
mlog.String("user_id", userID),
|
||||
)
|
||||
return nil
|
||||
@@ -118,10 +110,11 @@ func (a *App) sendPushNotificationToAllSessions(msg *model.PushNotification, use
|
||||
|
||||
sessions, err := a.getMobileAppSessions(userID)
|
||||
if err != nil {
|
||||
a.CountNotificationReason(model.NotificationStatusError, model.NotificationTypePush, model.NotificationReasonFetchError)
|
||||
a.NotificationsLog().Error("Failed to send mobile app sessions",
|
||||
mlog.String("type", model.TypePush),
|
||||
mlog.String("status", model.StatusServerError),
|
||||
mlog.String("reason", model.ReasonFetchError),
|
||||
mlog.String("type", model.NotificationTypePush),
|
||||
mlog.String("status", model.NotificationStatusError),
|
||||
mlog.String("reason", model.NotificationReasonFetchError),
|
||||
mlog.String("user_id", userID),
|
||||
mlog.Err(err),
|
||||
)
|
||||
@@ -129,10 +122,11 @@ func (a *App) sendPushNotificationToAllSessions(msg *model.PushNotification, use
|
||||
}
|
||||
|
||||
if msg == nil {
|
||||
a.CountNotificationReason(model.NotificationStatusError, model.NotificationTypePush, model.NotificationReasonParseError)
|
||||
a.NotificationsLog().Error("Failed to parse push notification",
|
||||
mlog.String("type", model.TypePush),
|
||||
mlog.String("status", model.StatusServerError),
|
||||
mlog.String("reason", model.ReasonServerError),
|
||||
mlog.String("type", model.NotificationTypePush),
|
||||
mlog.String("status", model.NotificationStatusError),
|
||||
mlog.String("reason", model.NotificationReasonParseError),
|
||||
mlog.String("user_id", userID),
|
||||
)
|
||||
return model.NewAppError(
|
||||
@@ -147,10 +141,11 @@ func (a *App) sendPushNotificationToAllSessions(msg *model.PushNotification, use
|
||||
for _, session := range sessions {
|
||||
// Don't send notifications to this session if it's expired or we want to skip it
|
||||
if session.IsExpired() || (skipSessionId != "" && skipSessionId == session.Id) {
|
||||
a.CountNotificationReason(model.NotificationStatusNotSent, model.NotificationTypePush, model.NotificationReasonSessionExpired)
|
||||
a.NotificationsLog().Debug("Session expired or skipped",
|
||||
mlog.String("type", model.TypePush),
|
||||
mlog.String("status", model.StatusNotSent),
|
||||
mlog.String("reason", model.ReasonUserStatus),
|
||||
mlog.String("type", model.NotificationTypePush),
|
||||
mlog.String("status", model.NotificationStatusNotSent),
|
||||
mlog.String("reason", model.NotificationReasonSessionExpired),
|
||||
mlog.String("user_id", session.UserId),
|
||||
mlog.String("session_id", session.Id),
|
||||
)
|
||||
@@ -164,10 +159,11 @@ func (a *App) sendPushNotificationToAllSessions(msg *model.PushNotification, use
|
||||
|
||||
err := a.sendToPushProxy(tmpMessage, session)
|
||||
if err != nil {
|
||||
a.CountNotificationReason(model.NotificationStatusError, model.NotificationTypePush, model.NotificationReasonPushProxySendError)
|
||||
a.NotificationsLog().Error("Failed to send to push proxy",
|
||||
mlog.String("type", model.TypePush),
|
||||
mlog.String("status", model.StatusNotSent),
|
||||
mlog.String("reason", model.ReasonPushProxyError),
|
||||
mlog.String("type", model.NotificationTypePush),
|
||||
mlog.String("status", model.NotificationStatusNotSent),
|
||||
mlog.String("reason", model.NotificationReasonPushProxySendError),
|
||||
mlog.String("ack_id", tmpMessage.AckId),
|
||||
mlog.String("push_type", tmpMessage.Type),
|
||||
mlog.String("user_id", session.UserId),
|
||||
@@ -178,7 +174,7 @@ func (a *App) sendPushNotificationToAllSessions(msg *model.PushNotification, use
|
||||
}
|
||||
|
||||
a.NotificationsLog().Trace("Notification sent to push proxy",
|
||||
mlog.String("type", model.TypePush),
|
||||
mlog.String("type", model.NotificationTypePush),
|
||||
mlog.String("ack_id", tmpMessage.AckId),
|
||||
mlog.String("push_type", tmpMessage.Type),
|
||||
mlog.String("user_id", session.UserId),
|
||||
@@ -477,7 +473,7 @@ func (a *App) sendToPushProxy(msg *model.PushNotification, session *model.Sessio
|
||||
msg.ServerId = a.TelemetryId()
|
||||
|
||||
a.NotificationsLog().Trace("Notification will be sent",
|
||||
mlog.String("type", model.TypePush),
|
||||
mlog.String("type", model.NotificationTypePush),
|
||||
mlog.String("ack_id", msg.AckId),
|
||||
mlog.String("push_type", msg.Type),
|
||||
mlog.String("user_id", session.UserId),
|
||||
@@ -507,7 +503,7 @@ func (a *App) SendAckToPushProxy(ack *model.PushNotificationAck) error {
|
||||
}
|
||||
|
||||
a.NotificationsLog().Trace("Notification successfully received",
|
||||
mlog.String("type", model.TypePush),
|
||||
mlog.String("type", model.NotificationTypePush),
|
||||
mlog.String("ack_id", ack.Id),
|
||||
mlog.String("push_type", ack.NotificationType),
|
||||
mlog.String("post_id", ack.PostId),
|
||||
@@ -553,12 +549,12 @@ func (a *App) getMobileAppSessions(userID string) ([]*model.Session, *model.AppE
|
||||
|
||||
func (a *App) ShouldSendPushNotification(user *model.User, channelNotifyProps model.StringMap, wasMentioned bool, status *model.Status, post *model.Post, isGM bool) bool {
|
||||
if notifyPropsAllowedReason := DoesNotifyPropsAllowPushNotification(user, channelNotifyProps, post, wasMentioned, isGM); notifyPropsAllowedReason != "" {
|
||||
a.CountNotificationReason(model.NotificationStatusNotSent, model.NotificationTypePush, notifyPropsAllowedReason)
|
||||
a.NotificationsLog().Debug("Notification not sent - notify props",
|
||||
mlog.String("type", model.TypePush),
|
||||
mlog.String("type", model.NotificationTypePush),
|
||||
mlog.String("post_id", post.Id),
|
||||
mlog.String("status", model.StatusNotSent),
|
||||
mlog.String("reason", model.ReasonUserConfig),
|
||||
mlog.String("notify_props_reason", notifyPropsAllowedReason),
|
||||
mlog.String("status", model.NotificationStatusNotSent),
|
||||
mlog.String("reason", notifyPropsAllowedReason),
|
||||
mlog.String("sender_id", post.UserId),
|
||||
mlog.String("receiver_id", user.Id),
|
||||
)
|
||||
@@ -566,12 +562,12 @@ func (a *App) ShouldSendPushNotification(user *model.User, channelNotifyProps mo
|
||||
}
|
||||
|
||||
if statusAllowedReason := DoesStatusAllowPushNotification(user.NotifyProps, status, post.ChannelId); statusAllowedReason != "" {
|
||||
a.CountNotificationReason(model.NotificationStatusNotSent, model.NotificationTypePush, statusAllowedReason)
|
||||
a.NotificationsLog().Debug("Notification not sent - status",
|
||||
mlog.String("type", model.TypePush),
|
||||
mlog.String("type", model.NotificationTypePush),
|
||||
mlog.String("post_id", post.Id),
|
||||
mlog.String("status", model.StatusNotSent),
|
||||
mlog.String("reason", model.ReasonUserConfig),
|
||||
mlog.String("status_reason", statusAllowedReason),
|
||||
mlog.String("status", model.NotificationStatusNotSent),
|
||||
mlog.String("reason", statusAllowedReason),
|
||||
mlog.String("sender_id", post.UserId),
|
||||
mlog.String("receiver_id", user.Id),
|
||||
mlog.String("receiver_status", status.Status),
|
||||
@@ -582,7 +578,7 @@ func (a *App) ShouldSendPushNotification(user *model.User, channelNotifyProps mo
|
||||
return true
|
||||
}
|
||||
|
||||
func DoesNotifyPropsAllowPushNotification(user *model.User, channelNotifyProps model.StringMap, post *model.Post, wasMentioned, isGM bool) notifyPropsReason {
|
||||
func DoesNotifyPropsAllowPushNotification(user *model.User, channelNotifyProps model.StringMap, post *model.Post, wasMentioned, isGM bool) model.NotificationReason {
|
||||
userNotifyProps := user.NotifyProps
|
||||
userNotify := userNotifyProps[model.PushNotifyProp]
|
||||
channelNotify, ok := channelNotifyProps[model.PushNotifyProp]
|
||||
@@ -600,19 +596,19 @@ func DoesNotifyPropsAllowPushNotification(user *model.User, channelNotifyProps m
|
||||
|
||||
// If the channel is muted do not send push notifications
|
||||
if channelNotifyProps[model.MarkUnreadNotifyProp] == model.ChannelMarkUnreadMention {
|
||||
return NotifyPropsReasonChannelMuted
|
||||
return model.NotificationReasonChannelMuted
|
||||
}
|
||||
|
||||
if post.IsSystemMessage() {
|
||||
return NotifyPropsReasonSystemMessage
|
||||
return model.NotificationReasonSystemMessage
|
||||
}
|
||||
|
||||
if notify == model.ChannelNotifyNone {
|
||||
return NotifyPropsReasonSetToNone
|
||||
return model.NotificationReasonLevelSetToNone
|
||||
}
|
||||
|
||||
if notify == model.ChannelNotifyMention && !wasMentioned {
|
||||
return NotifyPropsReasonSetToMention
|
||||
return model.NotificationReasonNotMentioned
|
||||
}
|
||||
|
||||
if (notify == model.ChannelNotifyAll) &&
|
||||
@@ -623,10 +619,10 @@ func DoesNotifyPropsAllowPushNotification(user *model.User, channelNotifyProps m
|
||||
return ""
|
||||
}
|
||||
|
||||
func DoesStatusAllowPushNotification(userNotifyProps model.StringMap, status *model.Status, channelID string) statusReason {
|
||||
func DoesStatusAllowPushNotification(userNotifyProps model.StringMap, status *model.Status, channelID string) model.NotificationReason {
|
||||
// If User status is DND or OOO return false right away
|
||||
if status.Status == model.StatusDnd || status.Status == model.StatusOutOfOffice {
|
||||
return StatusReasonDNDOrOOO
|
||||
return model.NotificationReasonUserStatus
|
||||
}
|
||||
|
||||
pushStatus, ok := userNotifyProps[model.PushStatusNotifyProp]
|
||||
@@ -642,7 +638,7 @@ func DoesStatusAllowPushNotification(userNotifyProps model.StringMap, status *mo
|
||||
return ""
|
||||
}
|
||||
|
||||
return StatusReasonIsActive
|
||||
return model.NotificationReasonUserIsActive
|
||||
}
|
||||
|
||||
func (a *App) BuildPushNotificationMessage(c request.CTX, contentsConfig string, post *model.Post, user *model.User, channel *model.Channel, channelName string, senderName string,
|
||||
@@ -689,11 +685,12 @@ func (a *App) SendTestPushNotification(deviceID string) string {
|
||||
|
||||
pushResponse, err := a.rawSendToPushProxy(msg)
|
||||
if err != nil {
|
||||
a.CountNotificationReason(model.NotificationStatusError, model.NotificationTypePush, model.NotificationReasonPushProxySendError)
|
||||
a.NotificationsLog().Error("Failed to send test notification to push proxy",
|
||||
mlog.String("type", model.TypePush),
|
||||
mlog.String("type", model.NotificationTypePush),
|
||||
mlog.String("push_type", msg.Type),
|
||||
mlog.String("status", model.StatusServerError),
|
||||
mlog.String("reason", model.ReasonPushProxyError),
|
||||
mlog.String("status", model.NotificationStatusError),
|
||||
mlog.String("reason", model.NotificationReasonPushProxySendError),
|
||||
mlog.String("device_id", msg.DeviceId),
|
||||
mlog.Err(err),
|
||||
)
|
||||
@@ -704,11 +701,12 @@ func (a *App) SendTestPushNotification(deviceID string) string {
|
||||
case model.PushStatusRemove:
|
||||
return "false"
|
||||
case model.PushStatusFail:
|
||||
a.CountNotificationReason(model.NotificationStatusError, model.NotificationTypePush, model.NotificationReasonPushProxyError)
|
||||
a.NotificationsLog().Error("Push proxy failed to send test notification",
|
||||
mlog.String("type", model.TypePush),
|
||||
mlog.String("type", model.NotificationTypePush),
|
||||
mlog.String("push_type", msg.Type),
|
||||
mlog.String("status", model.StatusServerError),
|
||||
mlog.String("reason", model.ReasonPushProxyError),
|
||||
mlog.String("status", model.NotificationStatusError),
|
||||
mlog.String("reason", model.NotificationReasonPushProxyError),
|
||||
mlog.String("device_id", msg.DeviceId),
|
||||
mlog.Err(errors.New(pushResponse[model.PushStatusErrorMsg])),
|
||||
)
|
||||
|
||||
Ссылка в новой задаче
Block a user