feat: add tpl & status api
This commit is contained in:
parent
39de0892f1
commit
258e9738f7
|
@ -30,6 +30,12 @@ type ConfigStruct struct {
|
|||
Trans transSection `yaml:"trans"`
|
||||
ContactKeys []contactKey `yaml:"contactKeys"`
|
||||
NotifyChannels []string `yaml:"notifyChannels"`
|
||||
Tpl tplSection `yaml:"tpl"`
|
||||
}
|
||||
|
||||
type tplSection struct {
|
||||
AlertRulePath string `yaml:"alertRulePath"`
|
||||
DashboardPath string `yaml:"dashboardPath"`
|
||||
}
|
||||
|
||||
type alertSection struct {
|
||||
|
@ -116,6 +122,8 @@ func Parse() error {
|
|||
viper.SetDefault("trans.backend.prometheus.maxConcurrentQuery", 30)
|
||||
viper.SetDefault("trans.backend.prometheus.maxSamples", 50000000)
|
||||
viper.SetDefault("trans.backend.prometheus.maxFetchAllSeriesLimitMinute", 5)
|
||||
viper.SetDefault("tpl.alertRulePath", "./etc/alert_rule")
|
||||
viper.SetDefault("tpl.dashboardPath", "./etc/dashboard")
|
||||
|
||||
err = viper.Unmarshal(&Config)
|
||||
if err != nil {
|
||||
|
|
|
@ -0,0 +1,176 @@
|
|||
[
|
||||
{
|
||||
"name": "内存利用率大于75%",
|
||||
"type": 0,
|
||||
"expression": {
|
||||
"trigger_conditions": [
|
||||
{
|
||||
"optr": ">",
|
||||
"func": "all",
|
||||
"metric": "system_mem_pct_used",
|
||||
"params": [],
|
||||
"threshold": 75
|
||||
}
|
||||
],
|
||||
"tags_filters": []
|
||||
},
|
||||
"status": 0,
|
||||
"enable_stime": "00:00",
|
||||
"enable_etime": "23:59",
|
||||
"enable_days_of_week": "1 2 3 4 5 6 7",
|
||||
"recovery_notify": 0,
|
||||
"priority": 2,
|
||||
"notify_channels": "sms email",
|
||||
"runbook_url": "",
|
||||
"note": "",
|
||||
"create_at": 1625831623,
|
||||
"alert_duration": 60,
|
||||
"notify_users_detail": null,
|
||||
"notify_groups_detail": null
|
||||
},
|
||||
{
|
||||
"name": "机器loadavg大于16",
|
||||
"type": 0,
|
||||
"expression": {
|
||||
"trigger_conditions": [
|
||||
{
|
||||
"optr": ">",
|
||||
"func": "all",
|
||||
"metric": "node_load1",
|
||||
"params": [],
|
||||
"threshold": 16
|
||||
}
|
||||
],
|
||||
"tags_filters": []
|
||||
},
|
||||
"status": 0,
|
||||
"enable_stime": "00:00",
|
||||
"enable_etime": "23:59",
|
||||
"enable_days_of_week": "1 2 3 4 5 6 7",
|
||||
"recovery_notify": 0,
|
||||
"priority": 1,
|
||||
"notify_channels": "sms email",
|
||||
"runbook_url": "",
|
||||
"note": "",
|
||||
"create_at": 1625831689,
|
||||
"alert_duration": 60,
|
||||
"notify_users_detail": null,
|
||||
"notify_groups_detail": null
|
||||
},
|
||||
{
|
||||
"name": "磁盘利用率达到85%",
|
||||
"type": 0,
|
||||
"expression": {
|
||||
"trigger_conditions": [
|
||||
{
|
||||
"optr": ">",
|
||||
"func": "all",
|
||||
"metric": "system_disk_in_use",
|
||||
"params": [],
|
||||
"threshold": 85
|
||||
}
|
||||
],
|
||||
"tags_filters": []
|
||||
},
|
||||
"status": 0,
|
||||
"enable_stime": "00:00",
|
||||
"enable_etime": "23:59",
|
||||
"enable_days_of_week": "1 2 3 4 5 6 7",
|
||||
"recovery_notify": 0,
|
||||
"priority": 3,
|
||||
"notify_channels": "email",
|
||||
"runbook_url": "",
|
||||
"note": "",
|
||||
"create_at": 1625831738,
|
||||
"alert_duration": 60,
|
||||
"notify_users_detail": null,
|
||||
"notify_groups_detail": null
|
||||
},
|
||||
{
|
||||
"name": "磁盘利用率达到88%",
|
||||
"type": 0,
|
||||
"expression": {
|
||||
"trigger_conditions": [
|
||||
{
|
||||
"optr": ">",
|
||||
"func": "all",
|
||||
"metric": "system_disk_in_use",
|
||||
"params": [],
|
||||
"threshold": 88
|
||||
}
|
||||
],
|
||||
"tags_filters": []
|
||||
},
|
||||
"status": 0,
|
||||
"enable_stime": "00:00",
|
||||
"enable_etime": "23:59",
|
||||
"enable_days_of_week": "1 2 3 4 5 6 7",
|
||||
"recovery_notify": 0,
|
||||
"priority": 2,
|
||||
"notify_channels": "email sms",
|
||||
"runbook_url": "",
|
||||
"note": "",
|
||||
"create_at": 1625831774,
|
||||
"alert_duration": 60,
|
||||
"notify_users_detail": null,
|
||||
"notify_groups_detail": null
|
||||
},
|
||||
{
|
||||
"name": "磁盘利用率达到92%",
|
||||
"type": 0,
|
||||
"expression": {
|
||||
"trigger_conditions": [
|
||||
{
|
||||
"optr": ">",
|
||||
"func": "all",
|
||||
"metric": "system_disk_in_use",
|
||||
"params": [],
|
||||
"threshold": 88
|
||||
}
|
||||
],
|
||||
"tags_filters": []
|
||||
},
|
||||
"status": 0,
|
||||
"enable_stime": "00:00",
|
||||
"enable_etime": "23:59",
|
||||
"enable_days_of_week": "1 2 3 4 5 6 7",
|
||||
"recovery_notify": 0,
|
||||
"priority": 1,
|
||||
"notify_channels": "email sms voice",
|
||||
"runbook_url": "",
|
||||
"note": "",
|
||||
"create_at": 1625831752,
|
||||
"alert_duration": 60,
|
||||
"notify_users_detail": null,
|
||||
"notify_groups_detail": null
|
||||
},
|
||||
{
|
||||
"name": "端口挂了",
|
||||
"type": 0,
|
||||
"expression": {
|
||||
"trigger_conditions": [
|
||||
{
|
||||
"optr": "<",
|
||||
"func": "all",
|
||||
"metric": "proc_port_listen",
|
||||
"params": [],
|
||||
"threshold": 1
|
||||
}
|
||||
],
|
||||
"tags_filters": []
|
||||
},
|
||||
"status": 0,
|
||||
"enable_stime": "00:00",
|
||||
"enable_etime": "23:59",
|
||||
"enable_days_of_week": "1 2 3 4 5 6 7",
|
||||
"recovery_notify": 0,
|
||||
"priority": 2,
|
||||
"notify_channels": "sms email",
|
||||
"runbook_url": "",
|
||||
"note": "",
|
||||
"create_at": 1625831564,
|
||||
"alert_duration": 60,
|
||||
"notify_users_detail": null,
|
||||
"notify_groups_detail": null
|
||||
}
|
||||
]
|
|
@ -0,0 +1,42 @@
|
|||
[
|
||||
{
|
||||
"id": 0,
|
||||
"name": "日常巡检大盘",
|
||||
"tags": "",
|
||||
"configs": "",
|
||||
"chart_groups": [
|
||||
{
|
||||
"id": 0,
|
||||
"dashboard_id": 0,
|
||||
"name": "Default chart group",
|
||||
"weight": 0,
|
||||
"charts": [
|
||||
{
|
||||
"id": 158,
|
||||
"group_id": 60,
|
||||
"configs": "{\"name\":\"CPU使用率\",\"mode\":\"nightingale\",\"metric\":[\"system_cpu_used\"],\"tags\":{},\"layout\":{\"h\":2,\"w\":2,\"x\":0,\"y\":0,\"i\":\"0\"}}",
|
||||
"weight": 0
|
||||
},
|
||||
{
|
||||
"id": 159,
|
||||
"group_id": 60,
|
||||
"configs": "{\"name\":\"硬盘使用率\",\"mode\":\"nightingale\",\"metric\":[\"system_disk_in_use\"],\"tags\":{},\"layout\":{\"h\":2,\"w\":2,\"x\":6,\"y\":0,\"i\":\"1\"}}",
|
||||
"weight": 0
|
||||
},
|
||||
{
|
||||
"id": 160,
|
||||
"group_id": 60,
|
||||
"configs": "{\"name\":\"内存使用率\",\"mode\":\"nightingale\",\"metric\":[\"system_mem_pct_used\"],\"tags\":{},\"layout\":{\"h\":2,\"w\":2,\"x\":2,\"y\":0,\"i\":\"2\"}}",
|
||||
"weight": 0
|
||||
},
|
||||
{
|
||||
"id": 161,
|
||||
"group_id": 60,
|
||||
"configs": "{\"name\":\"IO使用率\",\"mode\":\"nightingale\",\"metric\":[\"system_io_util\"],\"tags\":{},\"layout\":{\"h\":2,\"w\":2,\"x\":4,\"y\":0,\"i\":\"3\"}}",
|
||||
"weight": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -158,11 +158,17 @@ func configRoutes(r *gin.Engine) {
|
|||
pages.GET("/contact-channels", contactChannelsGet)
|
||||
pages.GET("/notify-channels", notifyChannelsGet)
|
||||
|
||||
pages.GET("/tpl/list", tplNameGets)
|
||||
pages.GET("/tpl/content", tplGet)
|
||||
|
||||
pages.GET("/status", Status)
|
||||
|
||||
pages.POST("/query", GetData)
|
||||
pages.POST("/tag-keys", GetTagKeys)
|
||||
pages.POST("/tag-values", GetTagValues)
|
||||
pages.POST("/tag-metrics", GetMetrics)
|
||||
pages.POST("/tag-pairs", GetTagPairs)
|
||||
|
||||
}
|
||||
|
||||
// for thirdparty, do not expose location in nginx.conf
|
||||
|
@ -279,6 +285,8 @@ func configRoutes(r *gin.Engine) {
|
|||
|
||||
v1.POST("/push", PushData)
|
||||
|
||||
v1.GET("/status", Status)
|
||||
|
||||
v1.POST("/query", GetData)
|
||||
v1.GET("/check-promql", checkPromeQl)
|
||||
v1.POST("/tag-keys", GetTagKeys)
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
package http
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/didi/nightingale/v5/models"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func Status(c *gin.Context) {
|
||||
var err error
|
||||
data := make(map[string]int64)
|
||||
data["user_total"], err = models.UserTotal("")
|
||||
dangerous(err)
|
||||
|
||||
data["user_group_total"], err = models.UserGroupTotal("")
|
||||
dangerous(err)
|
||||
|
||||
data["resource_total"], err = models.ResourceTotal("")
|
||||
dangerous(err)
|
||||
|
||||
data["alert_rule_total"], err = models.AlertRuleTotal("")
|
||||
dangerous(err)
|
||||
|
||||
data["dashboard_total"], err = models.DashboardCount("")
|
||||
dangerous(err)
|
||||
|
||||
now := time.Now().Unix()
|
||||
stime := now - 24*3600
|
||||
data["event_total_day"], err = models.AlertEventTotal(stime, now, "", -1, -1)
|
||||
dangerous(err)
|
||||
|
||||
stime = now - 7*24*3600
|
||||
data["event_total_week"], err = models.AlertEventTotal(stime, now, "", -1, -1)
|
||||
dangerous(err)
|
||||
|
||||
stime = now - 30*24*3600
|
||||
data["event_total_month"], err = models.AlertEventTotal(stime, now, "", -1, -1)
|
||||
dangerous(err)
|
||||
|
||||
renderData(c, data, nil)
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
package http
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"path"
|
||||
|
||||
"github.com/didi/nightingale/v5/config"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/toolkits/pkg/file"
|
||||
)
|
||||
|
||||
func tplNameGets(c *gin.Context) {
|
||||
tplType := queryStr(c, "tpl_type")
|
||||
|
||||
var files []string
|
||||
var err error
|
||||
switch tplType {
|
||||
case "alert_rule":
|
||||
files, err = file.FilesUnder(config.Config.Tpl.AlertRulePath)
|
||||
dangerous(err)
|
||||
case "dashboard":
|
||||
files, err = file.FilesUnder(config.Config.Tpl.DashboardPath)
|
||||
dangerous(err)
|
||||
default:
|
||||
bomb(http.StatusBadRequest, "tpl type not found")
|
||||
}
|
||||
|
||||
renderData(c, files, err)
|
||||
}
|
||||
|
||||
func tplGet(c *gin.Context) {
|
||||
tplName := path.Base(queryStr(c, "tpl_name"))
|
||||
tplType := queryStr(c, "tpl_type")
|
||||
|
||||
var filePath string
|
||||
switch tplType {
|
||||
case "alert_rule":
|
||||
filePath = config.Config.Tpl.AlertRulePath + "/" + tplName
|
||||
case "dashboard":
|
||||
filePath = config.Config.Tpl.DashboardPath + "/" + tplName
|
||||
default:
|
||||
bomb(http.StatusBadRequest, "tpl type not found")
|
||||
}
|
||||
|
||||
if !file.IsExist(filePath) {
|
||||
bomb(http.StatusBadRequest, "tpl not found")
|
||||
}
|
||||
|
||||
b, err := ioutil.ReadFile(filePath)
|
||||
dangerous(err)
|
||||
|
||||
var content interface{}
|
||||
err = json.Unmarshal(b, &content)
|
||||
renderData(c, content, err)
|
||||
}
|
|
@ -26,6 +26,10 @@ func (d *Dashboard) TableName() string {
|
|||
}
|
||||
|
||||
func (d *Dashboard) Validate() error {
|
||||
if d.Name == "" {
|
||||
return _e("Dashboard name is empty")
|
||||
}
|
||||
|
||||
if str.Dangerous(d.Name) {
|
||||
return _e("Dashboard name has invalid characters")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue