feat: add tpl & status api

This commit is contained in:
710leo 2021-07-09 20:13:28 +08:00
parent 39de0892f1
commit 258e9738f7
7 changed files with 338 additions and 0 deletions

View File

@ -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 {

176
etc/alert_rule/linux_host Normal file
View File

@ -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
}
]

42
etc/dashboard/linux_host Normal file
View File

@ -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
}
]
}
]
}
]

View File

@ -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)

42
http/router_status.go Normal file
View File

@ -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)
}

58
http/router_tpl.go Normal file
View File

@ -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)
}

View File

@ -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")
}