feat: Monitor groups and chart information
This commit is contained in:
@@ -1085,6 +1085,10 @@
|
||||
"enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"group": {
|
||||
"description": "Group is a display-only label. It buckets rows on the monitors page and\nhas no effect on scheduling, alerting or scope; an empty group means the\nmonitor is listed on its own under \"Ungrouped\".",
|
||||
"type": "string"
|
||||
},
|
||||
"instance_id": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -4208,6 +4212,9 @@
|
||||
"enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"group": {
|
||||
"type": "string"
|
||||
},
|
||||
"interval_sec": {
|
||||
"type": "integer"
|
||||
},
|
||||
|
||||
@@ -111,7 +111,7 @@ func getMonitor(c *gin.Context) {
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "Monitor ID"
|
||||
// @Param body body object{name=string,type=string,target=models.MonitorTarget,interval_sec=int,runner=string,retries=int,enabled=bool,channel_ids=[]string} true "Fields to update"
|
||||
// @Param body body object{name=string,group=string,type=string,target=models.MonitorTarget,interval_sec=int,runner=string,retries=int,enabled=bool,channel_ids=[]string} true "Fields to update"
|
||||
// @Success 204
|
||||
// @Failure 400 {object} ErrorResponse
|
||||
// @Failure 500 {object} ErrorResponse
|
||||
@@ -121,6 +121,7 @@ func getMonitor(c *gin.Context) {
|
||||
func updateMonitor(c *gin.Context) {
|
||||
var body struct {
|
||||
Name *string `json:"name"`
|
||||
Group *string `json:"group"`
|
||||
Type *string `json:"type"`
|
||||
Target *models.MonitorTarget `json:"target"`
|
||||
IntervalSec *int `json:"interval_sec"`
|
||||
@@ -137,6 +138,9 @@ func updateMonitor(c *gin.Context) {
|
||||
if body.Name != nil {
|
||||
upd["name"] = *body.Name
|
||||
}
|
||||
if body.Group != nil {
|
||||
upd["group"] = *body.Group
|
||||
}
|
||||
if body.Type != nil {
|
||||
upd["type"] = *body.Type
|
||||
}
|
||||
|
||||
@@ -43,10 +43,14 @@ type MonitorState struct {
|
||||
}
|
||||
|
||||
type Monitor struct {
|
||||
ID bson.ObjectID `bson:"_id,omitempty" json:"_id,omitempty"`
|
||||
InstanceID string `bson:"instance_id" json:"instance_id"`
|
||||
MonitorID string `bson:"monitor_id" json:"monitor_id"`
|
||||
Name string `bson:"name" json:"name"`
|
||||
ID bson.ObjectID `bson:"_id,omitempty" json:"_id,omitempty"`
|
||||
InstanceID string `bson:"instance_id" json:"instance_id"`
|
||||
MonitorID string `bson:"monitor_id" json:"monitor_id"`
|
||||
Name string `bson:"name" json:"name"`
|
||||
// Group is a display-only label. It buckets rows on the monitors page and
|
||||
// has no effect on scheduling, alerting or scope; an empty group means the
|
||||
// monitor is listed on its own under "Ungrouped".
|
||||
Group string `bson:"group,omitempty" json:"group,omitempty"`
|
||||
Type string `bson:"type" json:"type"`
|
||||
Target MonitorTarget `bson:"target" json:"target"`
|
||||
IntervalSec int `bson:"interval_sec" json:"interval_sec"`
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/checker"
|
||||
@@ -21,6 +22,22 @@ func monCtx() (context.Context, context.CancelFunc) {
|
||||
return context.WithTimeout(context.Background(), 5*time.Second)
|
||||
}
|
||||
|
||||
// MaxMonitorGroupLen bounds the display-only group label. It is a heading on
|
||||
// the monitors page, not an identifier, so the cap is about the layout rather
|
||||
// than storage.
|
||||
const MaxMonitorGroupLen = 48
|
||||
|
||||
// normaliseGroup collapses the ways two people write the same group. Grouping
|
||||
// is by exact string, so " Production " and "Production" must not become two
|
||||
// headings.
|
||||
func normaliseGroup(g string) (string, error) {
|
||||
g = strings.Join(strings.Fields(g), " ")
|
||||
if len([]rune(g)) > MaxMonitorGroupLen {
|
||||
return "", fmt.Errorf("group must be %d characters or fewer", MaxMonitorGroupLen)
|
||||
}
|
||||
return g, nil
|
||||
}
|
||||
|
||||
func SpecFor(m *models.Monitor) checker.Spec {
|
||||
return checker.Spec{
|
||||
Type: m.Type,
|
||||
@@ -126,6 +143,11 @@ func CreateMonitor(instanceID string, m *models.Monitor) (*models.Monitor, error
|
||||
if err := validateRunner(instanceID, m.Runner); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
group, err := normaliseGroup(m.Group)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m.Group = group
|
||||
m.InstanceID = instanceID
|
||||
m.MonitorID = uuid.NewString()
|
||||
m.CreatedAt = time.Now()
|
||||
@@ -158,6 +180,17 @@ func UpdateMonitor(instanceID, monitorID string, upd bson.M) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if raw, present := upd["group"]; present {
|
||||
g, ok := raw.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("group must be a string")
|
||||
}
|
||||
group, err := normaliseGroup(g)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
upd["group"] = group
|
||||
}
|
||||
if raw, present := upd["runner"]; present {
|
||||
runner, ok := raw.(string)
|
||||
if !ok {
|
||||
|
||||
Reference in New Issue
Block a user