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