feat: get error logs from fail notifications. (#213)

This commit is contained in:
Bo-Yi Wu 2017-04-10 11:46:48 +08:00 committed by GitHub
parent b6997ea792
commit 0c9aad538c
4 changed files with 71 additions and 38 deletions

View File

@ -39,21 +39,6 @@ type LogPushEntry struct {
Token string `json:"token"` Token string `json:"token"`
Message string `json:"message"` Message string `json:"message"`
Error string `json:"error"` Error string `json:"error"`
// Android
To string `json:"to,omitempty"`
CollapseKey string `json:"collapse_key,omitempty"`
DelayWhileIdle bool `json:"delay_while_idle,omitempty"`
TimeToLive uint `json:"time_to_live,omitempty"`
RestrictedPackageName string `json:"restricted_package_name,omitempty"`
DryRun bool `json:"dry_run,omitempty"`
// iOS
ApnsID string `json:"apns_id,omitempty"`
Topic string `json:"topic,omitempty"`
Badge int `json:"badge,omitempty"`
Sound string `json:"sound,omitempty"`
Category string `json:"category,omitempty"`
} }
var isTerm bool var isTerm bool
@ -212,17 +197,11 @@ func hideToken(token string, markLen int) string {
return result return result
} }
// LogPush record user push request and server response. func getLogPushEntry(status, token string, req PushNotification, errPush error) LogPushEntry {
func LogPush(status, token string, req PushNotification, errPush error) { var errMsg string
var plat, platColor, resetColor, output string
if isTerm { plat := typeForPlatForm(req.Platform)
platColor = colorForPlatForm(req.Platform)
plat = typeForPlatForm(req.Platform)
resetColor = reset
}
errMsg := ""
if errPush != nil { if errPush != nil {
errMsg = errPush.Error() errMsg = errPush.Error()
} }
@ -231,13 +210,25 @@ func LogPush(status, token string, req PushNotification, errPush error) {
token = hideToken(token, 10) token = hideToken(token, 10)
} }
log := &LogPushEntry{ return LogPushEntry{
Type: status, Type: status,
Platform: plat, Platform: plat,
Token: token, Token: token,
Message: req.Message, Message: req.Message,
Error: errMsg, Error: errMsg,
} }
}
// LogPush record user push request and server response.
func LogPush(status, token string, req PushNotification, errPush error) {
var platColor, resetColor, output string
if isTerm {
platColor = colorForPlatForm(req.Platform)
resetColor = reset
}
log := getLogPushEntry(status, token, req, errPush)
if PushConf.Log.Format == "json" { if PushConf.Log.Format == "json" {
logJSON, _ := json.Marshal(log) logJSON, _ := json.Marshal(log)

View File

@ -65,6 +65,7 @@ type PushNotification struct {
Data D `json:"data,omitempty"` Data D `json:"data,omitempty"`
Retry int `json:"retry,omitempty"` Retry int `json:"retry,omitempty"`
wg *sync.WaitGroup wg *sync.WaitGroup
log *[]LogPushEntry
// Android // Android
APIKey string `json:"api_key,omitempty"` APIKey string `json:"api_key,omitempty"`
@ -87,13 +88,27 @@ type PushNotification struct {
MutableContent bool `json:"mutable-content,omitempty"` MutableContent bool `json:"mutable-content,omitempty"`
} }
// Done decrements the WaitGroup counter. // WaitDone decrements the WaitGroup counter.
func (p *PushNotification) Done() { func (p *PushNotification) WaitDone() {
if p.wg != nil { if p.wg != nil {
p.wg.Done() p.wg.Done()
} }
} }
// AddWaitCount increments the WaitGroup counter.
func (p *PushNotification) AddWaitCount() {
if p.wg != nil {
p.wg.Add(1)
}
}
// AddLog record fail log of notification
func (p *PushNotification) AddLog(log LogPushEntry) {
if p.log != nil {
*p.log = append(*p.log, log)
}
}
// CheckMessage for check request message // CheckMessage for check request message
func CheckMessage(req PushNotification) error { func CheckMessage(req PushNotification) error {
var msg string var msg string
@ -221,9 +236,10 @@ func startWorker() {
} }
// queueNotification add notification to queue list. // queueNotification add notification to queue list.
func queueNotification(req RequestPush) int { func queueNotification(req RequestPush) (int, []LogPushEntry) {
var count int var count int
wg := sync.WaitGroup{} wg := sync.WaitGroup{}
newNotification := []PushNotification{}
for _, notification := range req.Notifications { for _, notification := range req.Notifications {
switch notification.Platform { switch notification.Platform {
case PlatFormIos: case PlatFormIos:
@ -235,8 +251,16 @@ func queueNotification(req RequestPush) int {
continue continue
} }
} }
wg.Add(1) newNotification = append(newNotification, notification)
}
log := make([]LogPushEntry, 0, count)
for _, notification := range newNotification {
if PushConf.Core.Sync {
notification.wg = &wg notification.wg = &wg
notification.log = &log
notification.AddWaitCount()
}
QueueNotification <- notification QueueNotification <- notification
count += len(notification.Tokens) count += len(notification.Tokens)
} }
@ -247,7 +271,7 @@ func queueNotification(req RequestPush) int {
StatStorage.AddTotalCount(int64(count)) StatStorage.AddTotalCount(int64(count))
return count return count, log
} }
func iosAlertDictionary(payload *payload.Payload, req PushNotification) *payload.Payload { func iosAlertDictionary(payload *payload.Payload, req PushNotification) *payload.Payload {
@ -366,7 +390,9 @@ func GetIOSNotification(req PushNotification) *apns.Notification {
// PushToIOS provide send notification to APNs server. // PushToIOS provide send notification to APNs server.
func PushToIOS(req PushNotification) bool { func PushToIOS(req PushNotification) bool {
LogAccess.Debug("Start push notification for iOS") LogAccess.Debug("Start push notification for iOS")
defer req.Done() if PushConf.Core.Sync {
defer req.WaitDone()
}
var retryCount = 0 var retryCount = 0
var maxRetry = PushConf.Ios.MaxRetry var maxRetry = PushConf.Ios.MaxRetry
@ -389,6 +415,9 @@ Retry:
if err != nil { if err != nil {
// apns server error // apns server error
LogPush(FailedPush, token, req, err) LogPush(FailedPush, token, req, err)
if PushConf.Core.Sync {
req.AddLog(getLogPushEntry(FailedPush, token, req, err))
}
StatStorage.AddIosError(1) StatStorage.AddIosError(1)
newTokens = append(newTokens, token) newTokens = append(newTokens, token)
isError = true isError = true
@ -399,6 +428,9 @@ Retry:
// error message: // error message:
// ref: https://github.com/sideshow/apns2/blob/master/response.go#L14-L65 // ref: https://github.com/sideshow/apns2/blob/master/response.go#L14-L65
LogPush(FailedPush, token, req, errors.New(res.Reason)) LogPush(FailedPush, token, req, errors.New(res.Reason))
if PushConf.Core.Sync {
req.AddLog(getLogPushEntry(FailedPush, token, req, errors.New(res.Reason)))
}
StatStorage.AddIosError(1) StatStorage.AddIosError(1)
newTokens = append(newTokens, token) newTokens = append(newTokens, token)
isError = true isError = true
@ -471,7 +503,9 @@ func GetAndroidNotification(req PushNotification) gcm.HttpMessage {
// PushToAndroid provide send notification to Android server. // PushToAndroid provide send notification to Android server.
func PushToAndroid(req PushNotification) bool { func PushToAndroid(req PushNotification) bool {
LogAccess.Debug("Start push notification for Android") LogAccess.Debug("Start push notification for Android")
defer req.Done() if PushConf.Core.Sync {
defer req.WaitDone()
}
var APIKey string var APIKey string
var retryCount = 0 var retryCount = 0
var maxRetry = PushConf.Android.MaxRetry var maxRetry = PushConf.Android.MaxRetry
@ -514,6 +548,9 @@ Retry:
isError = true isError = true
newTokens = append(newTokens, req.Tokens[k]) newTokens = append(newTokens, req.Tokens[k])
LogPush(FailedPush, req.Tokens[k], req, errors.New(result.Error)) LogPush(FailedPush, req.Tokens[k], req, errors.New(result.Error))
if PushConf.Core.Sync {
req.AddLog(getLogPushEntry(FailedPush, req.Tokens[k], req, errors.New(result.Error)))
}
continue continue
} }

View File

@ -567,8 +567,9 @@ func TestSenMultipleNotifications(t *testing.T) {
}, },
} }
count := queueNotification(req) count, logs := queueNotification(req)
assert.Equal(t, 3, count) assert.Equal(t, 3, count)
assert.Equal(t, 0, len(logs))
} }
func TestDisabledAndroidNotifications(t *testing.T) { func TestDisabledAndroidNotifications(t *testing.T) {
@ -600,8 +601,9 @@ func TestDisabledAndroidNotifications(t *testing.T) {
}, },
} }
count := queueNotification(req) count, logs := queueNotification(req)
assert.Equal(t, 1, count) assert.Equal(t, 1, count)
assert.Equal(t, 0, len(logs))
} }
func TestSyncModeForNotifications(t *testing.T) { func TestSyncModeForNotifications(t *testing.T) {
@ -636,8 +638,9 @@ func TestSyncModeForNotifications(t *testing.T) {
}, },
} }
count := queueNotification(req) count, logs := queueNotification(req)
assert.Equal(t, 3, count) assert.Equal(t, 3, count)
assert.Equal(t, 2, len(logs))
} }
func TestDisabledIosNotifications(t *testing.T) { func TestDisabledIosNotifications(t *testing.T) {
@ -669,8 +672,9 @@ func TestDisabledIosNotifications(t *testing.T) {
}, },
} }
count := queueNotification(req) count, logs := queueNotification(req)
assert.Equal(t, 2, count) assert.Equal(t, 2, count)
assert.Equal(t, 0, len(logs))
} }
func TestWrongIosCertificateExt(t *testing.T) { func TestWrongIosCertificateExt(t *testing.T) {

View File

@ -56,11 +56,12 @@ func pushHandler(c *gin.Context) {
return return
} }
counts := queueNotification(form) counts, logs := queueNotification(form)
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{
"success": "ok", "success": "ok",
"counts": counts, "counts": counts,
"logs": logs,
}) })
} }