mirror of
https://github.com/wahyd4/badger.git
synced 2026-08-09 05:15:58 +10:00
Use db to store view count
This commit is contained in:
+61
-21
@@ -54,7 +54,7 @@ const (
|
||||
|
||||
type Metric struct {
|
||||
Label string
|
||||
Value float64
|
||||
Value int
|
||||
Time time.Time
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ func (handler *BadgesHandler) generateSVG(c *gin.Context, colorScheme ColorSchem
|
||||
|
||||
prometheusOptions := badge.OptionStruct.(*models.PrometheusOptions)
|
||||
|
||||
metric, _ := queryMetric(handler.PrometheusAPIClient, prometheusOptions)
|
||||
metric, _ := handler.queryMetric(badge, handler.PrometheusAPIClient, prometheusOptions)
|
||||
|
||||
metricValue := int(metric.Value)
|
||||
label := metric.Label
|
||||
@@ -149,7 +149,7 @@ func (handler *BadgesHandler) generateSVG(c *gin.Context, colorScheme ColorSchem
|
||||
|
||||
canvas.Rect(0, 0, int(labelContainerWidth), badgeHeight, string(colorScheme))
|
||||
|
||||
//when there is metric label then use default label
|
||||
//when there is a metric label then use default label
|
||||
if len(prometheusOptions.ValueField) == 0 {
|
||||
label = badge.Label
|
||||
}
|
||||
@@ -247,26 +247,66 @@ func (handler *BadgesHandler) CreateBadge(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"id": newID})
|
||||
}
|
||||
|
||||
func queryMetric(client api.Client, options *models.PrometheusOptions) (*Metric, error) {
|
||||
v1api := v1.NewAPI(client)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), metricRequestTimeout)
|
||||
defer cancel()
|
||||
|
||||
result, warnings, err := v1api.Query(ctx, options.Query, time.Now())
|
||||
func (handler *BadgesHandler) queryMetric(badge *models.Badge, client api.Client, options *models.PrometheusOptions) (*Metric, error) {
|
||||
viewCount, err := handler.fetchViewCountFromDB(badge)
|
||||
if err != nil {
|
||||
sentry.CaptureException(err)
|
||||
return nil, fmt.Errorf("error querying Prometheus: %w", err)
|
||||
return nil, err
|
||||
}
|
||||
if len(warnings) > 0 {
|
||||
fmt.Printf("Warnings: %v\n", warnings)
|
||||
}
|
||||
var metric Metric
|
||||
for _, v := range result.(model.Vector) {
|
||||
metric = Metric{
|
||||
Label: string(v.Metric[model.LabelName(options.ValueField)]),
|
||||
Value: float64(v.Value),
|
||||
Time: v.Timestamp.Time(),
|
||||
|
||||
if viewCount.Count == 0 {
|
||||
v1api := v1.NewAPI(client)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), metricRequestTimeout)
|
||||
defer cancel()
|
||||
|
||||
result, warnings, err := v1api.Query(ctx, options.Query, time.Now())
|
||||
if err != nil {
|
||||
sentry.CaptureException(err)
|
||||
return nil, fmt.Errorf("error querying Prometheus: %w", err)
|
||||
}
|
||||
if len(warnings) > 0 {
|
||||
logrus.Warnf("Warnings: %v\n", warnings)
|
||||
}
|
||||
|
||||
for _, v := range result.(model.Vector) {
|
||||
viewCount.Count = int(float64(v.Value))
|
||||
}
|
||||
}
|
||||
return &metric, nil
|
||||
|
||||
if err = handler.updateMetric(viewCount); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Metric{
|
||||
Label: viewCount.BadgeULID,
|
||||
Value: viewCount.Count,
|
||||
Time: viewCount.UpdatedAt,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (handler *BadgesHandler) fetchViewCountFromDB(badge *models.Badge) (*models.BadgeViewCount, error) {
|
||||
var viewCount models.BadgeViewCount
|
||||
err := handler.DB.Find(&viewCount, "ulid = ?", badge.ULID).Error
|
||||
if err != nil {
|
||||
if err != gorm.ErrRecordNotFound {
|
||||
return nil, err
|
||||
}
|
||||
logrus.Infof("no db viewcount for %s", badge.ULID)
|
||||
return &models.BadgeViewCount{
|
||||
BadgeULID: badge.ULID,
|
||||
Count: 0,
|
||||
}, nil
|
||||
}
|
||||
return &viewCount, nil
|
||||
}
|
||||
|
||||
func (handler *BadgesHandler) updateMetric(viewCount *models.BadgeViewCount) error {
|
||||
viewCount.Count++
|
||||
err := handler.DB.Save(&viewCount).Error
|
||||
if err != nil {
|
||||
sentry.CaptureException(err)
|
||||
logrus.Errorf("failed to update badge %s viewcount %v", viewCount.BadgeULID, err)
|
||||
return err
|
||||
}
|
||||
handler.DB.Save(&models.ViewRecord{ULID: viewCount.BadgeULID})
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -55,7 +55,12 @@ func main() {
|
||||
defer db.Close()
|
||||
|
||||
// Migrate the schema
|
||||
db.AutoMigrate(&models.Badge{}, &models.Token{}, &models.User{})
|
||||
db.AutoMigrate(
|
||||
&models.Badge{},
|
||||
&models.Token{},
|
||||
&models.User{},
|
||||
&models.ViewRecord{},
|
||||
&models.BadgeViewCount{})
|
||||
|
||||
client, err := api.NewClient(api.Config{
|
||||
Address: "https://prometheus-api.home.toozhao.com",
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package models
|
||||
|
||||
import "github.com/jinzhu/gorm"
|
||||
|
||||
type BadgeViewCount struct {
|
||||
gorm.Model
|
||||
BadgeULID string `gorm:"column:ulid;type:varchar;not null;unique_index" json:"ulid"`
|
||||
Count int `json:"count" gorm:"not null;"`
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
type ViewRecord struct {
|
||||
gorm.Model
|
||||
ULID string `gorm:"column:ulid;type:varchar;not null;" json:"ulid"`
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
kind: Role
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
namespace: apps
|
||||
name: badger-ops
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
||||
- apiGroups: ["monitoring.coreos.com"]
|
||||
resources: ["servicemonitors"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
||||
|
||||
---
|
||||
|
||||
kind: RoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: badger-role-binding
|
||||
namespace: apps
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: cd-robot
|
||||
namespace: apps
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: badger-ops
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
@@ -161,14 +161,6 @@
|
||||
>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row>
|
||||
<b-col>
|
||||
<p class="warnning">
|
||||
Note: The page view count data may take up to 3 minutes to be
|
||||
initialized.
|
||||
</p>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user