chore: Add metric and status package. (#585)
This commit is contained in:
		
							parent
							
								
									35e1998cc5
								
							
						
					
					
						commit
						2cd46ad690
					
				| 
						 | 
					@ -2,7 +2,6 @@ package gorush
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"github.com/appleboy/gorush/config"
 | 
						"github.com/appleboy/gorush/config"
 | 
				
			||||||
	"github.com/appleboy/gorush/storage"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/appleboy/go-fcm"
 | 
						"github.com/appleboy/go-fcm"
 | 
				
			||||||
	"github.com/msalihkarakasli/go-hms-push/push/core"
 | 
						"github.com/msalihkarakasli/go-hms-push/push/core"
 | 
				
			||||||
| 
						 | 
					@ -20,8 +19,6 @@ var (
 | 
				
			||||||
	FCMClient *fcm.Client
 | 
						FCMClient *fcm.Client
 | 
				
			||||||
	// HMSClient is Huawei push client
 | 
						// HMSClient is Huawei push client
 | 
				
			||||||
	HMSClient *core.HMSClient
 | 
						HMSClient *core.HMSClient
 | 
				
			||||||
	// StatStorage implements the storage interface
 | 
					 | 
				
			||||||
	StatStorage storage.Storage
 | 
					 | 
				
			||||||
	// MaxConcurrentIOSPushes pool to limit the number of concurrent iOS pushes
 | 
						// MaxConcurrentIOSPushes pool to limit the number of concurrent iOS pushes
 | 
				
			||||||
	MaxConcurrentIOSPushes chan struct{}
 | 
						MaxConcurrentIOSPushes chan struct{}
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,6 +8,7 @@ import (
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/appleboy/gorush/config"
 | 
						"github.com/appleboy/gorush/config"
 | 
				
			||||||
	"github.com/appleboy/gorush/logx"
 | 
						"github.com/appleboy/gorush/logx"
 | 
				
			||||||
 | 
						"github.com/appleboy/gorush/status"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestMain(m *testing.M) {
 | 
					func TestMain(m *testing.M) {
 | 
				
			||||||
| 
						 | 
					@ -21,12 +22,16 @@ func TestMain(m *testing.M) {
 | 
				
			||||||
		log.Fatal(err)
 | 
							log.Fatal(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := status.InitAppStatus(PushConf); err != nil {
 | 
				
			||||||
 | 
							log.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx, cancel := context.WithCancel(context.Background())
 | 
						ctx, cancel := context.WithCancel(context.Background())
 | 
				
			||||||
	wg := &sync.WaitGroup{}
 | 
						wg := &sync.WaitGroup{}
 | 
				
			||||||
	wg.Add(int(PushConf.Core.WorkerNum))
 | 
						wg.Add(int(PushConf.Core.WorkerNum))
 | 
				
			||||||
	InitWorkers(ctx, wg, PushConf.Core.WorkerNum, PushConf.Core.QueueNum)
 | 
						InitWorkers(ctx, wg, PushConf.Core.WorkerNum, PushConf.Core.QueueNum)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := InitAppStatus(); err != nil {
 | 
						if err := status.InitAppStatus(PushConf); err != nil {
 | 
				
			||||||
		log.Fatal(err)
 | 
							log.Fatal(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,6 +13,7 @@ import (
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/appleboy/gorush/core"
 | 
						"github.com/appleboy/gorush/core"
 | 
				
			||||||
	"github.com/appleboy/gorush/logx"
 | 
						"github.com/appleboy/gorush/logx"
 | 
				
			||||||
 | 
						"github.com/appleboy/gorush/status"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/mitchellh/mapstructure"
 | 
						"github.com/mitchellh/mapstructure"
 | 
				
			||||||
	"github.com/sideshow/apns2"
 | 
						"github.com/sideshow/apns2"
 | 
				
			||||||
| 
						 | 
					@ -428,7 +429,7 @@ Retry:
 | 
				
			||||||
					}(logx.LogError, createLogPushEntry(core.FailedPush, token, req, err), PushConf.Core.FeedbackURL, PushConf.Core.FeedbackTimeout)
 | 
										}(logx.LogError, createLogPushEntry(core.FailedPush, token, req, err), PushConf.Core.FeedbackURL, PushConf.Core.FeedbackTimeout)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				StatStorage.AddIosError(1)
 | 
									status.StatStorage.AddIosError(1)
 | 
				
			||||||
				// We should retry only "retryable" statuses. More info about response:
 | 
									// We should retry only "retryable" statuses. More info about response:
 | 
				
			||||||
				// https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/handling_notification_responses_from_apns
 | 
									// https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/handling_notification_responses_from_apns
 | 
				
			||||||
				if res != nil && res.StatusCode >= http.StatusInternalServerError {
 | 
									if res != nil && res.StatusCode >= http.StatusInternalServerError {
 | 
				
			||||||
| 
						 | 
					@ -438,7 +439,7 @@ Retry:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if res != nil && res.Sent() {
 | 
								if res != nil && res.Sent() {
 | 
				
			||||||
				logPush(core.SucceededPush, token, req, nil)
 | 
									logPush(core.SucceededPush, token, req, nil)
 | 
				
			||||||
				StatStorage.AddIosSuccess(1)
 | 
									status.StatStorage.AddIosSuccess(1)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			// free push slot
 | 
								// free push slot
 | 
				
			||||||
			<-MaxConcurrentIOSPushes
 | 
								<-MaxConcurrentIOSPushes
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,6 +12,7 @@ import (
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/appleboy/gorush/config"
 | 
						"github.com/appleboy/gorush/config"
 | 
				
			||||||
	"github.com/appleboy/gorush/core"
 | 
						"github.com/appleboy/gorush/core"
 | 
				
			||||||
 | 
						"github.com/appleboy/gorush/status"
 | 
				
			||||||
	"github.com/buger/jsonparser"
 | 
						"github.com/buger/jsonparser"
 | 
				
			||||||
	"github.com/sideshow/apns2"
 | 
						"github.com/sideshow/apns2"
 | 
				
			||||||
	"github.com/stretchr/testify/assert"
 | 
						"github.com/stretchr/testify/assert"
 | 
				
			||||||
| 
						 | 
					@ -761,7 +762,7 @@ func TestPushToIOS(t *testing.T) {
 | 
				
			||||||
	PushConf.Ios.KeyPath = "../certificate/certificate-valid.pem"
 | 
						PushConf.Ios.KeyPath = "../certificate/certificate-valid.pem"
 | 
				
			||||||
	err := InitAPNSClient()
 | 
						err := InitAPNSClient()
 | 
				
			||||||
	assert.Nil(t, err)
 | 
						assert.Nil(t, err)
 | 
				
			||||||
	err = InitAppStatus()
 | 
						err = status.InitAppStatus(PushConf)
 | 
				
			||||||
	assert.Nil(t, err)
 | 
						assert.Nil(t, err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	req := PushNotification{
 | 
						req := PushNotification{
 | 
				
			||||||
| 
						 | 
					@ -781,7 +782,7 @@ func TestApnsHostFromRequest(t *testing.T) {
 | 
				
			||||||
	PushConf.Ios.KeyPath = "../certificate/certificate-valid.pem"
 | 
						PushConf.Ios.KeyPath = "../certificate/certificate-valid.pem"
 | 
				
			||||||
	err := InitAPNSClient()
 | 
						err := InitAPNSClient()
 | 
				
			||||||
	assert.Nil(t, err)
 | 
						assert.Nil(t, err)
 | 
				
			||||||
	err = InitAppStatus()
 | 
						err = status.InitAppStatus(PushConf)
 | 
				
			||||||
	assert.Nil(t, err)
 | 
						assert.Nil(t, err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	req := PushNotification{
 | 
						req := PushNotification{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,7 @@ import (
 | 
				
			||||||
	"github.com/appleboy/go-fcm"
 | 
						"github.com/appleboy/go-fcm"
 | 
				
			||||||
	"github.com/appleboy/gorush/core"
 | 
						"github.com/appleboy/gorush/core"
 | 
				
			||||||
	"github.com/appleboy/gorush/logx"
 | 
						"github.com/appleboy/gorush/logx"
 | 
				
			||||||
 | 
						"github.com/appleboy/gorush/status"
 | 
				
			||||||
	"github.com/sirupsen/logrus"
 | 
						"github.com/sirupsen/logrus"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -154,7 +155,7 @@ Retry:
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}(logx.LogError, createLogPushEntry(core.FailedPush, req.To, req, err), PushConf.Core.FeedbackURL, PushConf.Core.FeedbackTimeout)
 | 
									}(logx.LogError, createLogPushEntry(core.FailedPush, req.To, req, err), PushConf.Core.FeedbackURL, PushConf.Core.FeedbackTimeout)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			StatStorage.AddAndroidError(1)
 | 
								status.StatStorage.AddAndroidError(1)
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			for _, token := range req.Tokens {
 | 
								for _, token := range req.Tokens {
 | 
				
			||||||
				if PushConf.Core.Sync {
 | 
									if PushConf.Core.Sync {
 | 
				
			||||||
| 
						 | 
					@ -168,7 +169,7 @@ Retry:
 | 
				
			||||||
					}(logx.LogError, createLogPushEntry(core.FailedPush, token, req, err), PushConf.Core.FeedbackURL, PushConf.Core.FeedbackTimeout)
 | 
										}(logx.LogError, createLogPushEntry(core.FailedPush, token, req, err), PushConf.Core.FeedbackURL, PushConf.Core.FeedbackTimeout)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			StatStorage.AddAndroidError(int64(len(req.Tokens)))
 | 
								status.StatStorage.AddAndroidError(int64(len(req.Tokens)))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -177,8 +178,8 @@ Retry:
 | 
				
			||||||
		logx.LogAccess.Debug(fmt.Sprintf("Android Success count: %d, Failure count: %d", res.Success, res.Failure))
 | 
							logx.LogAccess.Debug(fmt.Sprintf("Android Success count: %d, Failure count: %d", res.Success, res.Failure))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	StatStorage.AddAndroidSuccess(int64(res.Success))
 | 
						status.StatStorage.AddAndroidSuccess(int64(res.Success))
 | 
				
			||||||
	StatStorage.AddAndroidError(int64(res.Failure))
 | 
						status.StatStorage.AddAndroidError(int64(res.Failure))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var newTokens []string
 | 
						var newTokens []string
 | 
				
			||||||
	// result from Send messages to specific devices
 | 
						// result from Send messages to specific devices
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,7 @@ import (
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/appleboy/gorush/logx"
 | 
						"github.com/appleboy/gorush/logx"
 | 
				
			||||||
 | 
						"github.com/appleboy/gorush/status"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/msalihkarakasli/go-hms-push/push/config"
 | 
						"github.com/msalihkarakasli/go-hms-push/push/config"
 | 
				
			||||||
	"github.com/msalihkarakasli/go-hms-push/push/core"
 | 
						"github.com/msalihkarakasli/go-hms-push/push/core"
 | 
				
			||||||
| 
						 | 
					@ -206,11 +207,11 @@ Retry:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Huawei Push Send API does not support exact results for each token
 | 
						// Huawei Push Send API does not support exact results for each token
 | 
				
			||||||
	if res.Code == "80000000" {
 | 
						if res.Code == "80000000" {
 | 
				
			||||||
		StatStorage.AddHuaweiSuccess(int64(1))
 | 
							status.StatStorage.AddHuaweiSuccess(int64(1))
 | 
				
			||||||
		logx.LogAccess.Debug("Huwaei Send Notification is completed successfully!")
 | 
							logx.LogAccess.Debug("Huwaei Send Notification is completed successfully!")
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		isError = true
 | 
							isError = true
 | 
				
			||||||
		StatStorage.AddHuaweiError(int64(1))
 | 
							status.StatStorage.AddHuaweiError(int64(1))
 | 
				
			||||||
		logx.LogAccess.Debug("Huawei Send Notification is failed! Code: " + res.Code)
 | 
							logx.LogAccess.Debug("Huawei Send Notification is failed! Code: " + res.Code)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,9 @@ import (
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/appleboy/gorush/metric"
 | 
				
			||||||
 | 
						"github.com/appleboy/gorush/status"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	api "github.com/appleboy/gin-status-api"
 | 
						api "github.com/appleboy/gin-status-api"
 | 
				
			||||||
	"github.com/appleboy/gorush/logx"
 | 
						"github.com/appleboy/gorush/logx"
 | 
				
			||||||
	"github.com/gin-contrib/logger"
 | 
						"github.com/gin-contrib/logger"
 | 
				
			||||||
| 
						 | 
					@ -17,6 +20,7 @@ import (
 | 
				
			||||||
	"github.com/prometheus/client_golang/prometheus/promhttp"
 | 
						"github.com/prometheus/client_golang/prometheus/promhttp"
 | 
				
			||||||
	"github.com/rs/zerolog"
 | 
						"github.com/rs/zerolog"
 | 
				
			||||||
	"github.com/rs/zerolog/log"
 | 
						"github.com/rs/zerolog/log"
 | 
				
			||||||
 | 
						"github.com/thoas/stats"
 | 
				
			||||||
	"golang.org/x/crypto/acme/autocert"
 | 
						"golang.org/x/crypto/acme/autocert"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,7 +28,9 @@ var isTerm bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	// Support metrics
 | 
						// Support metrics
 | 
				
			||||||
	m := NewMetrics()
 | 
						m := metric.NewMetrics(func() int {
 | 
				
			||||||
 | 
							return len(QueueNotification)
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
	prometheus.MustRegister(m)
 | 
						prometheus.MustRegister(m)
 | 
				
			||||||
	isTerm = isatty.IsTerminal(os.Stdout.Fd())
 | 
						isTerm = isatty.IsTerminal(os.Stdout.Fd())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -109,6 +115,36 @@ func metricsHandler(c *gin.Context) {
 | 
				
			||||||
	promhttp.Handler().ServeHTTP(c.Writer, c.Request)
 | 
						promhttp.Handler().ServeHTTP(c.Writer, c.Request)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func appStatusHandler(c *gin.Context) {
 | 
				
			||||||
 | 
						result := status.App{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						result.Version = GetVersion()
 | 
				
			||||||
 | 
						result.QueueMax = cap(QueueNotification)
 | 
				
			||||||
 | 
						result.QueueUsage = len(QueueNotification)
 | 
				
			||||||
 | 
						result.TotalCount = status.StatStorage.GetTotalCount()
 | 
				
			||||||
 | 
						result.Ios.PushSuccess = status.StatStorage.GetIosSuccess()
 | 
				
			||||||
 | 
						result.Ios.PushError = status.StatStorage.GetIosError()
 | 
				
			||||||
 | 
						result.Android.PushSuccess = status.StatStorage.GetAndroidSuccess()
 | 
				
			||||||
 | 
						result.Android.PushError = status.StatStorage.GetAndroidError()
 | 
				
			||||||
 | 
						result.Huawei.PushSuccess = status.StatStorage.GetHuaweiSuccess()
 | 
				
			||||||
 | 
						result.Huawei.PushError = status.StatStorage.GetHuaweiError()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						c.JSON(http.StatusOK, result)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func sysStatsHandler(c *gin.Context) {
 | 
				
			||||||
 | 
						c.JSON(http.StatusOK, status.Stats.Data())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// StatMiddleware response time, status code count, etc.
 | 
				
			||||||
 | 
					func StatMiddleware() gin.HandlerFunc {
 | 
				
			||||||
 | 
						return func(c *gin.Context) {
 | 
				
			||||||
 | 
							beginning, recorder := status.Stats.Begin(c.Writer)
 | 
				
			||||||
 | 
							c.Next()
 | 
				
			||||||
 | 
							status.Stats.End(beginning, stats.WithRecorder(recorder))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func autoTLSServer() *http.Server {
 | 
					func autoTLSServer() *http.Server {
 | 
				
			||||||
	m := autocert.Manager{
 | 
						m := autocert.Manager{
 | 
				
			||||||
		Prompt:     autocert.AcceptTOS,
 | 
							Prompt:     autocert.AcceptTOS,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,7 @@ import (
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/appleboy/gorush/core"
 | 
						"github.com/appleboy/gorush/core"
 | 
				
			||||||
	"github.com/appleboy/gorush/logx"
 | 
						"github.com/appleboy/gorush/logx"
 | 
				
			||||||
 | 
						"github.com/appleboy/gorush/status"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// InitWorkers for initialize all workers.
 | 
					// InitWorkers for initialize all workers.
 | 
				
			||||||
| 
						 | 
					@ -105,7 +106,7 @@ func queueNotification(ctx context.Context, req RequestPush) (int, []logx.LogPus
 | 
				
			||||||
		wg.Wait()
 | 
							wg.Wait()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	StatStorage.AddTotalCount(int64(count))
 | 
						status.StatStorage.AddTotalCount(int64(count))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return count, log
 | 
						return count, log
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										11
									
								
								main.go
								
								
								
								
							
							
						
						
									
										11
									
								
								main.go
								
								
								
								
							| 
						 | 
					@ -20,6 +20,7 @@ import (
 | 
				
			||||||
	"github.com/appleboy/gorush/gorush"
 | 
						"github.com/appleboy/gorush/gorush"
 | 
				
			||||||
	"github.com/appleboy/gorush/logx"
 | 
						"github.com/appleboy/gorush/logx"
 | 
				
			||||||
	"github.com/appleboy/gorush/rpc"
 | 
						"github.com/appleboy/gorush/rpc"
 | 
				
			||||||
 | 
						"github.com/appleboy/gorush/status"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"golang.org/x/sync/errgroup"
 | 
						"golang.org/x/sync/errgroup"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					@ -212,7 +213,7 @@ func main() {
 | 
				
			||||||
			logx.LogError.Fatal(err)
 | 
								logx.LogError.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := gorush.InitAppStatus(); err != nil {
 | 
							if err := status.InitAppStatus(gorush.PushConf); err != nil {
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -245,7 +246,7 @@ func main() {
 | 
				
			||||||
			logx.LogError.Fatal(err)
 | 
								logx.LogError.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := gorush.InitAppStatus(); err != nil {
 | 
							if err := status.InitAppStatus(gorush.PushConf); err != nil {
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -282,7 +283,7 @@ func main() {
 | 
				
			||||||
			logx.LogError.Fatal(err)
 | 
								logx.LogError.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := gorush.InitAppStatus(); err != nil {
 | 
							if err := status.InitAppStatus(gorush.PushConf); err != nil {
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -308,7 +309,7 @@ func main() {
 | 
				
			||||||
		logx.LogError.Fatal(err)
 | 
							logx.LogError.Fatal(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err = gorush.InitAppStatus(); err != nil {
 | 
						if err = status.InitAppStatus(gorush.PushConf); err != nil {
 | 
				
			||||||
		logx.LogError.Fatal(err)
 | 
							logx.LogError.Fatal(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -323,7 +324,7 @@ func main() {
 | 
				
			||||||
		close(finished)
 | 
							close(finished)
 | 
				
			||||||
		// close the connection with storage
 | 
							// close the connection with storage
 | 
				
			||||||
		logx.LogAccess.Info("close the storage connection: ", gorush.PushConf.Stat.Engine)
 | 
							logx.LogAccess.Info("close the storage connection: ", gorush.PushConf.Stat.Engine)
 | 
				
			||||||
		if err := gorush.StatStorage.Close(); err != nil {
 | 
							if err := status.StatStorage.Close(); err != nil {
 | 
				
			||||||
			logx.LogError.Fatal("can't close the storage connection: ", err.Error())
 | 
								logx.LogError.Fatal("can't close the storage connection: ", err.Error())
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,8 @@
 | 
				
			||||||
package gorush
 | 
					package metric
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/appleboy/gorush/status"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/prometheus/client_golang/prometheus"
 | 
						"github.com/prometheus/client_golang/prometheus"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,11 +19,14 @@ type Metrics struct {
 | 
				
			||||||
	HuaweiSuccess  *prometheus.Desc
 | 
						HuaweiSuccess  *prometheus.Desc
 | 
				
			||||||
	HuaweiError    *prometheus.Desc
 | 
						HuaweiError    *prometheus.Desc
 | 
				
			||||||
	QueueUsage     *prometheus.Desc
 | 
						QueueUsage     *prometheus.Desc
 | 
				
			||||||
 | 
						GetQueueUsage  func() int
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var getGetQueueUsage = func() int { return 0 }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewMetrics returns a new Metrics with all prometheus.Desc initialized
 | 
					// NewMetrics returns a new Metrics with all prometheus.Desc initialized
 | 
				
			||||||
func NewMetrics() Metrics {
 | 
					func NewMetrics(c ...func() int) Metrics {
 | 
				
			||||||
	return Metrics{
 | 
						m := Metrics{
 | 
				
			||||||
		TotalPushCount: prometheus.NewDesc(
 | 
							TotalPushCount: prometheus.NewDesc(
 | 
				
			||||||
			namespace+"total_push_count",
 | 
								namespace+"total_push_count",
 | 
				
			||||||
			"Number of push count",
 | 
								"Number of push count",
 | 
				
			||||||
| 
						 | 
					@ -62,7 +67,14 @@ func NewMetrics() Metrics {
 | 
				
			||||||
			"Length of internal queue",
 | 
								"Length of internal queue",
 | 
				
			||||||
			nil, nil,
 | 
								nil, nil,
 | 
				
			||||||
		),
 | 
							),
 | 
				
			||||||
 | 
							GetQueueUsage: getGetQueueUsage,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(c) > 0 {
 | 
				
			||||||
 | 
							m.GetQueueUsage = c[0]
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return m
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Describe returns all possible prometheus.Desc
 | 
					// Describe returns all possible prometheus.Desc
 | 
				
			||||||
| 
						 | 
					@ -82,41 +94,41 @@ func (c Metrics) Collect(ch chan<- prometheus.Metric) {
 | 
				
			||||||
	ch <- prometheus.MustNewConstMetric(
 | 
						ch <- prometheus.MustNewConstMetric(
 | 
				
			||||||
		c.TotalPushCount,
 | 
							c.TotalPushCount,
 | 
				
			||||||
		prometheus.CounterValue,
 | 
							prometheus.CounterValue,
 | 
				
			||||||
		float64(StatStorage.GetTotalCount()),
 | 
							float64(status.StatStorage.GetTotalCount()),
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	ch <- prometheus.MustNewConstMetric(
 | 
						ch <- prometheus.MustNewConstMetric(
 | 
				
			||||||
		c.IosSuccess,
 | 
							c.IosSuccess,
 | 
				
			||||||
		prometheus.CounterValue,
 | 
							prometheus.CounterValue,
 | 
				
			||||||
		float64(StatStorage.GetIosSuccess()),
 | 
							float64(status.StatStorage.GetIosSuccess()),
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	ch <- prometheus.MustNewConstMetric(
 | 
						ch <- prometheus.MustNewConstMetric(
 | 
				
			||||||
		c.IosError,
 | 
							c.IosError,
 | 
				
			||||||
		prometheus.CounterValue,
 | 
							prometheus.CounterValue,
 | 
				
			||||||
		float64(StatStorage.GetIosError()),
 | 
							float64(status.StatStorage.GetIosError()),
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	ch <- prometheus.MustNewConstMetric(
 | 
						ch <- prometheus.MustNewConstMetric(
 | 
				
			||||||
		c.AndroidSuccess,
 | 
							c.AndroidSuccess,
 | 
				
			||||||
		prometheus.CounterValue,
 | 
							prometheus.CounterValue,
 | 
				
			||||||
		float64(StatStorage.GetAndroidSuccess()),
 | 
							float64(status.StatStorage.GetAndroidSuccess()),
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	ch <- prometheus.MustNewConstMetric(
 | 
						ch <- prometheus.MustNewConstMetric(
 | 
				
			||||||
		c.AndroidError,
 | 
							c.AndroidError,
 | 
				
			||||||
		prometheus.CounterValue,
 | 
							prometheus.CounterValue,
 | 
				
			||||||
		float64(StatStorage.GetAndroidError()),
 | 
							float64(status.StatStorage.GetAndroidError()),
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	ch <- prometheus.MustNewConstMetric(
 | 
						ch <- prometheus.MustNewConstMetric(
 | 
				
			||||||
		c.HuaweiSuccess,
 | 
							c.HuaweiSuccess,
 | 
				
			||||||
		prometheus.CounterValue,
 | 
							prometheus.CounterValue,
 | 
				
			||||||
		float64(StatStorage.GetHuaweiSuccess()),
 | 
							float64(status.StatStorage.GetHuaweiSuccess()),
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	ch <- prometheus.MustNewConstMetric(
 | 
						ch <- prometheus.MustNewConstMetric(
 | 
				
			||||||
		c.HuaweiError,
 | 
							c.HuaweiError,
 | 
				
			||||||
		prometheus.CounterValue,
 | 
							prometheus.CounterValue,
 | 
				
			||||||
		float64(StatStorage.GetHuaweiError()),
 | 
							float64(status.StatStorage.GetHuaweiError()),
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	ch <- prometheus.MustNewConstMetric(
 | 
						ch <- prometheus.MustNewConstMetric(
 | 
				
			||||||
		c.QueueUsage,
 | 
							c.QueueUsage,
 | 
				
			||||||
		prometheus.GaugeValue,
 | 
							prometheus.GaugeValue,
 | 
				
			||||||
		float64(len(QueueNotification)),
 | 
							float64(c.GetQueueUsage()),
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,15 @@
 | 
				
			||||||
 | 
					package metric
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/stretchr/testify/assert"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestNewMetrics(t *testing.T) {
 | 
				
			||||||
 | 
						m := NewMetrics()
 | 
				
			||||||
 | 
						assert.Equal(t, 0, m.GetQueueUsage())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						m = NewMetrics(func() int { return 1 })
 | 
				
			||||||
 | 
						assert.Equal(t, 1, m.GetQueueUsage())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,10 +1,11 @@
 | 
				
			||||||
package gorush
 | 
					package status
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"net/http"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/appleboy/gorush/config"
 | 
				
			||||||
	"github.com/appleboy/gorush/logx"
 | 
						"github.com/appleboy/gorush/logx"
 | 
				
			||||||
 | 
						"github.com/appleboy/gorush/storage"
 | 
				
			||||||
	"github.com/appleboy/gorush/storage/badger"
 | 
						"github.com/appleboy/gorush/storage/badger"
 | 
				
			||||||
	"github.com/appleboy/gorush/storage/boltdb"
 | 
						"github.com/appleboy/gorush/storage/boltdb"
 | 
				
			||||||
	"github.com/appleboy/gorush/storage/buntdb"
 | 
						"github.com/appleboy/gorush/storage/buntdb"
 | 
				
			||||||
| 
						 | 
					@ -12,15 +13,17 @@ import (
 | 
				
			||||||
	"github.com/appleboy/gorush/storage/memory"
 | 
						"github.com/appleboy/gorush/storage/memory"
 | 
				
			||||||
	"github.com/appleboy/gorush/storage/redis"
 | 
						"github.com/appleboy/gorush/storage/redis"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/gin-gonic/gin"
 | 
					 | 
				
			||||||
	"github.com/thoas/stats"
 | 
						"github.com/thoas/stats"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Stats provide response time, status code count, etc.
 | 
					// Stats provide response time, status code count, etc.
 | 
				
			||||||
var Stats = stats.New()
 | 
					var Stats = stats.New()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// StatusApp is app status structure
 | 
					// StatStorage implements the storage interface
 | 
				
			||||||
type StatusApp struct {
 | 
					var StatStorage storage.Storage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// App is status structure
 | 
				
			||||||
 | 
					type App struct {
 | 
				
			||||||
	Version    string        `json:"version"`
 | 
						Version    string        `json:"version"`
 | 
				
			||||||
	QueueMax   int           `json:"queue_max"`
 | 
						QueueMax   int           `json:"queue_max"`
 | 
				
			||||||
	QueueUsage int           `json:"queue_usage"`
 | 
						QueueUsage int           `json:"queue_usage"`
 | 
				
			||||||
| 
						 | 
					@ -49,21 +52,21 @@ type HuaweiStatus struct {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// InitAppStatus for initialize app status
 | 
					// InitAppStatus for initialize app status
 | 
				
			||||||
func InitAppStatus() error {
 | 
					func InitAppStatus(conf config.ConfYaml) error {
 | 
				
			||||||
	logx.LogAccess.Info("Init App Status Engine as ", PushConf.Stat.Engine)
 | 
						logx.LogAccess.Info("Init App Status Engine as ", conf.Stat.Engine)
 | 
				
			||||||
	switch PushConf.Stat.Engine {
 | 
						switch conf.Stat.Engine {
 | 
				
			||||||
	case "memory":
 | 
						case "memory":
 | 
				
			||||||
		StatStorage = memory.New()
 | 
							StatStorage = memory.New()
 | 
				
			||||||
	case "redis":
 | 
						case "redis":
 | 
				
			||||||
		StatStorage = redis.New(PushConf)
 | 
							StatStorage = redis.New(conf)
 | 
				
			||||||
	case "boltdb":
 | 
						case "boltdb":
 | 
				
			||||||
		StatStorage = boltdb.New(PushConf)
 | 
							StatStorage = boltdb.New(conf)
 | 
				
			||||||
	case "buntdb":
 | 
						case "buntdb":
 | 
				
			||||||
		StatStorage = buntdb.New(PushConf)
 | 
							StatStorage = buntdb.New(conf)
 | 
				
			||||||
	case "leveldb":
 | 
						case "leveldb":
 | 
				
			||||||
		StatStorage = leveldb.New(PushConf)
 | 
							StatStorage = leveldb.New(conf)
 | 
				
			||||||
	case "badger":
 | 
						case "badger":
 | 
				
			||||||
		StatStorage = badger.New(PushConf)
 | 
							StatStorage = badger.New(conf)
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		logx.LogError.Error("storage error: can't find storage driver")
 | 
							logx.LogError.Error("storage error: can't find storage driver")
 | 
				
			||||||
		return errors.New("can't find storage driver")
 | 
							return errors.New("can't find storage driver")
 | 
				
			||||||
| 
						 | 
					@ -77,33 +80,3 @@ func InitAppStatus() error {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
func appStatusHandler(c *gin.Context) {
 | 
					 | 
				
			||||||
	result := StatusApp{}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	result.Version = GetVersion()
 | 
					 | 
				
			||||||
	result.QueueMax = cap(QueueNotification)
 | 
					 | 
				
			||||||
	result.QueueUsage = len(QueueNotification)
 | 
					 | 
				
			||||||
	result.TotalCount = StatStorage.GetTotalCount()
 | 
					 | 
				
			||||||
	result.Ios.PushSuccess = StatStorage.GetIosSuccess()
 | 
					 | 
				
			||||||
	result.Ios.PushError = StatStorage.GetIosError()
 | 
					 | 
				
			||||||
	result.Android.PushSuccess = StatStorage.GetAndroidSuccess()
 | 
					 | 
				
			||||||
	result.Android.PushError = StatStorage.GetAndroidError()
 | 
					 | 
				
			||||||
	result.Huawei.PushSuccess = StatStorage.GetHuaweiSuccess()
 | 
					 | 
				
			||||||
	result.Huawei.PushError = StatStorage.GetHuaweiError()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	c.JSON(http.StatusOK, result)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func sysStatsHandler(c *gin.Context) {
 | 
					 | 
				
			||||||
	c.JSON(http.StatusOK, Stats.Data())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// StatMiddleware response time, status code count, etc.
 | 
					 | 
				
			||||||
func StatMiddleware() gin.HandlerFunc {
 | 
					 | 
				
			||||||
	return func(c *gin.Context) {
 | 
					 | 
				
			||||||
		beginning, recorder := Stats.Begin(c.Writer)
 | 
					 | 
				
			||||||
		c.Next()
 | 
					 | 
				
			||||||
		Stats.End(beginning, stats.WithRecorder(recorder))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,15 +1,34 @@
 | 
				
			||||||
package gorush
 | 
					package status
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"log"
 | 
				
			||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/appleboy/gorush/config"
 | 
				
			||||||
 | 
						"github.com/appleboy/gorush/logx"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/stretchr/testify/assert"
 | 
						"github.com/stretchr/testify/assert"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestMain(m *testing.M) {
 | 
				
			||||||
 | 
						PushConf, _ := config.LoadConf("")
 | 
				
			||||||
 | 
						if err := logx.InitLog(
 | 
				
			||||||
 | 
							PushConf.Log.AccessLevel,
 | 
				
			||||||
 | 
							PushConf.Log.AccessLog,
 | 
				
			||||||
 | 
							PushConf.Log.ErrorLevel,
 | 
				
			||||||
 | 
							PushConf.Log.ErrorLog,
 | 
				
			||||||
 | 
						); err != nil {
 | 
				
			||||||
 | 
							log.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						m.Run()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestStorageDriverExist(t *testing.T) {
 | 
					func TestStorageDriverExist(t *testing.T) {
 | 
				
			||||||
 | 
						PushConf, _ := config.LoadConf("")
 | 
				
			||||||
	PushConf.Stat.Engine = "Test"
 | 
						PushConf.Stat.Engine = "Test"
 | 
				
			||||||
	err := InitAppStatus()
 | 
						err := InitAppStatus(PushConf)
 | 
				
			||||||
	assert.Error(t, err)
 | 
						assert.Error(t, err)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,8 +37,9 @@ func TestStatForMemoryEngine(t *testing.T) {
 | 
				
			||||||
	time.Sleep(5 * time.Second)
 | 
						time.Sleep(5 * time.Second)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var val int64
 | 
						var val int64
 | 
				
			||||||
 | 
						PushConf, _ := config.LoadConf("")
 | 
				
			||||||
	PushConf.Stat.Engine = "memory"
 | 
						PushConf.Stat.Engine = "memory"
 | 
				
			||||||
	err := InitAppStatus()
 | 
						err := InitAppStatus(PushConf)
 | 
				
			||||||
	assert.Nil(t, err)
 | 
						assert.Nil(t, err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	StatStorage.AddTotalCount(100)
 | 
						StatStorage.AddTotalCount(100)
 | 
				
			||||||
| 
						 | 
					@ -41,28 +61,31 @@ func TestStatForMemoryEngine(t *testing.T) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestRedisServerSuccess(t *testing.T) {
 | 
					func TestRedisServerSuccess(t *testing.T) {
 | 
				
			||||||
 | 
						PushConf, _ := config.LoadConf("")
 | 
				
			||||||
	PushConf.Stat.Engine = "redis"
 | 
						PushConf.Stat.Engine = "redis"
 | 
				
			||||||
	PushConf.Stat.Redis.Addr = "redis:6379"
 | 
						PushConf.Stat.Redis.Addr = "redis:6379"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err := InitAppStatus()
 | 
						err := InitAppStatus(PushConf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	assert.NoError(t, err)
 | 
						assert.NoError(t, err)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestRedisServerError(t *testing.T) {
 | 
					func TestRedisServerError(t *testing.T) {
 | 
				
			||||||
 | 
						PushConf, _ := config.LoadConf("")
 | 
				
			||||||
	PushConf.Stat.Engine = "redis"
 | 
						PushConf.Stat.Engine = "redis"
 | 
				
			||||||
	PushConf.Stat.Redis.Addr = "redis:6370"
 | 
						PushConf.Stat.Redis.Addr = "redis:6370"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err := InitAppStatus()
 | 
						err := InitAppStatus(PushConf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	assert.Error(t, err)
 | 
						assert.Error(t, err)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestStatForRedisEngine(t *testing.T) {
 | 
					func TestStatForRedisEngine(t *testing.T) {
 | 
				
			||||||
	var val int64
 | 
						var val int64
 | 
				
			||||||
 | 
						PushConf, _ := config.LoadConf("")
 | 
				
			||||||
	PushConf.Stat.Engine = "redis"
 | 
						PushConf.Stat.Engine = "redis"
 | 
				
			||||||
	PushConf.Stat.Redis.Addr = "redis:6379"
 | 
						PushConf.Stat.Redis.Addr = "redis:6379"
 | 
				
			||||||
	err := InitAppStatus()
 | 
						err := InitAppStatus(PushConf)
 | 
				
			||||||
	assert.Nil(t, err)
 | 
						assert.Nil(t, err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	StatStorage.Init()
 | 
						StatStorage.Init()
 | 
				
			||||||
| 
						 | 
					@ -89,7 +112,8 @@ func TestStatForRedisEngine(t *testing.T) {
 | 
				
			||||||
func TestDefaultEngine(t *testing.T) {
 | 
					func TestDefaultEngine(t *testing.T) {
 | 
				
			||||||
	var val int64
 | 
						var val int64
 | 
				
			||||||
	// defaul engine as memory
 | 
						// defaul engine as memory
 | 
				
			||||||
	err := InitAppStatus()
 | 
						PushConf, _ := config.LoadConf("")
 | 
				
			||||||
 | 
						err := InitAppStatus(PushConf)
 | 
				
			||||||
	assert.Nil(t, err)
 | 
						assert.Nil(t, err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	StatStorage.Reset()
 | 
						StatStorage.Reset()
 | 
				
			||||||
| 
						 | 
					@ -114,8 +138,10 @@ func TestDefaultEngine(t *testing.T) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestStatForBoltDBEngine(t *testing.T) {
 | 
					func TestStatForBoltDBEngine(t *testing.T) {
 | 
				
			||||||
	var val int64
 | 
						var val int64
 | 
				
			||||||
 | 
						PushConf, _ := config.LoadConf("")
 | 
				
			||||||
	PushConf.Stat.Engine = "boltdb"
 | 
						PushConf.Stat.Engine = "boltdb"
 | 
				
			||||||
	InitAppStatus()
 | 
						err := InitAppStatus(PushConf)
 | 
				
			||||||
 | 
						assert.Nil(t, err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	StatStorage.Reset()
 | 
						StatStorage.Reset()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,7 +4,7 @@ import (
 | 
				
			||||||
	"sync/atomic"
 | 
						"sync/atomic"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// StatusApp is app status structure
 | 
					// statApp is app status structure
 | 
				
			||||||
type statApp struct {
 | 
					type statApp struct {
 | 
				
			||||||
	TotalCount int64         `json:"total_count"`
 | 
						TotalCount int64         `json:"total_count"`
 | 
				
			||||||
	Ios        IosStatus     `json:"ios"`
 | 
						Ios        IosStatus     `json:"ios"`
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue