mirror of
https://github.com/ccfos/nightingale.git
synced 2026-03-07 08:29:10 +00:00
Compare commits
14 Commits
build
...
refactor-e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
10cc8c2ae8 | ||
|
|
da54173bd0 | ||
|
|
9dc20fc674 | ||
|
|
16430550d1 | ||
|
|
b34b66785d | ||
|
|
2cf38b6027 | ||
|
|
e1b4edaa68 | ||
|
|
97f3f70d57 | ||
|
|
cee0ce6620 | ||
|
|
89b659695f | ||
|
|
d52848ab1b | ||
|
|
314a8d71ef | ||
|
|
bfa85cd8f1 | ||
|
|
2254cb1f87 |
@@ -149,6 +149,11 @@ ops:
|
||||
- "/user-groups/put"
|
||||
- "/user-groups/del"
|
||||
|
||||
- name: permissions
|
||||
cname: 权限管理
|
||||
ops:
|
||||
- "/permissions"
|
||||
|
||||
- name: busi-groups
|
||||
cname: 业务分组管理
|
||||
ops:
|
||||
@@ -160,6 +165,7 @@ ops:
|
||||
- name: system
|
||||
cname: 系统信息
|
||||
ops:
|
||||
- "/help/variable-configs"
|
||||
- "/help/version"
|
||||
- "/help/servers"
|
||||
- "/help/source"
|
||||
|
||||
@@ -367,7 +367,7 @@ func (rt *Router) Config(r *gin.Engine) {
|
||||
pages.PUT("/role/:id/ops", rt.auth(), rt.admin(), rt.roleBindOperation)
|
||||
pages.GET("/operation", rt.operations)
|
||||
|
||||
pages.GET("/notify-tpls", rt.auth(), rt.admin(), rt.notifyTplGets)
|
||||
pages.GET("/notify-tpls", rt.auth(), rt.user(), rt.perm("/help/notification-tpls"), rt.notifyTplGets)
|
||||
pages.PUT("/notify-tpl/content", rt.auth(), rt.admin(), rt.notifyTplUpdateContent)
|
||||
pages.PUT("/notify-tpl", rt.auth(), rt.admin(), rt.notifyTplUpdate)
|
||||
pages.POST("/notify-tpl", rt.auth(), rt.admin(), rt.notifyTplAdd)
|
||||
@@ -377,19 +377,19 @@ func (rt *Router) Config(r *gin.Engine) {
|
||||
pages.GET("/sso-configs", rt.auth(), rt.admin(), rt.ssoConfigGets)
|
||||
pages.PUT("/sso-config", rt.auth(), rt.admin(), rt.ssoConfigUpdate)
|
||||
|
||||
pages.GET("/webhooks", rt.auth(), rt.admin(), rt.webhookGets)
|
||||
pages.GET("/webhooks", rt.auth(), rt.user(), rt.webhookGets)
|
||||
pages.PUT("/webhooks", rt.auth(), rt.admin(), rt.webhookPuts)
|
||||
|
||||
pages.GET("/notify-script", rt.auth(), rt.admin(), rt.notifyScriptGet)
|
||||
pages.GET("/notify-script", rt.auth(), rt.user(), rt.perm("/help/notification-settings"), rt.notifyScriptGet)
|
||||
pages.PUT("/notify-script", rt.auth(), rt.admin(), rt.notifyScriptPut)
|
||||
|
||||
pages.GET("/notify-channel", rt.auth(), rt.admin(), rt.notifyChannelGets)
|
||||
pages.GET("/notify-channel", rt.auth(), rt.user(), rt.perm("/help/notification-settings"), rt.notifyChannelGets)
|
||||
pages.PUT("/notify-channel", rt.auth(), rt.admin(), rt.notifyChannelPuts)
|
||||
|
||||
pages.GET("/notify-contact", rt.auth(), rt.admin(), rt.notifyContactGets)
|
||||
pages.GET("/notify-contact", rt.auth(), rt.user(), rt.perm("/help/notification-settings"), rt.notifyContactGets)
|
||||
pages.PUT("/notify-contact", rt.auth(), rt.admin(), rt.notifyContactPuts)
|
||||
|
||||
pages.GET("/notify-config", rt.auth(), rt.admin(), rt.notifyConfigGet)
|
||||
pages.GET("/notify-config", rt.auth(), rt.user(), rt.perm("/help/notification-settings"), rt.notifyConfigGet)
|
||||
pages.PUT("/notify-config", rt.auth(), rt.admin(), rt.notifyConfigPut)
|
||||
pages.PUT("/smtp-config-test", rt.auth(), rt.admin(), rt.attemptSendEmail)
|
||||
|
||||
@@ -399,10 +399,10 @@ func (rt *Router) Config(r *gin.Engine) {
|
||||
pages.PUT("/es-index-pattern", rt.auth(), rt.admin(), rt.esIndexPatternPut)
|
||||
pages.DELETE("/es-index-pattern", rt.auth(), rt.admin(), rt.esIndexPatternDel)
|
||||
|
||||
pages.GET("/user-variable-configs", rt.auth(), rt.admin(), rt.userVariableConfigGets)
|
||||
pages.POST("/user-variable-config", rt.auth(), rt.admin(), rt.userVariableConfigAdd)
|
||||
pages.PUT("/user-variable-config/:id", rt.auth(), rt.admin(), rt.userVariableConfigPut)
|
||||
pages.DELETE("/user-variable-config/:id", rt.auth(), rt.admin(), rt.userVariableConfigDel)
|
||||
pages.GET("/user-variable-configs", rt.auth(), rt.user(), rt.perm("/help/variable-configs"), rt.userVariableConfigGets)
|
||||
pages.POST("/user-variable-config", rt.auth(), rt.user(), rt.perm("/help/variable-configs"), rt.userVariableConfigAdd)
|
||||
pages.PUT("/user-variable-config/:id", rt.auth(), rt.user(), rt.perm("/help/variable-configs"), rt.userVariableConfigPut)
|
||||
pages.DELETE("/user-variable-config/:id", rt.auth(), rt.user(), rt.perm("/help/variable-configs"), rt.userVariableConfigDel)
|
||||
|
||||
pages.GET("/config", rt.auth(), rt.admin(), rt.configGetByKey)
|
||||
pages.PUT("/config", rt.auth(), rt.admin(), rt.configPutByKey)
|
||||
|
||||
@@ -163,7 +163,7 @@ func (rt *Router) notifyConfigPut(c *gin.Context) {
|
||||
var f models.Configs
|
||||
ginx.BindJSON(c, &f)
|
||||
userVariableMap := rt.NotifyConfigCache.ConfigCache.Get()
|
||||
text := tplx.ReplaceMacroVariables(f.Ckey, f.Cval, userVariableMap)
|
||||
text := tplx.ReplaceTemplateUseText(f.Ckey, f.Cval, userVariableMap)
|
||||
switch f.Ckey {
|
||||
case models.SMTP:
|
||||
var smtp aconf.SMTPConfig
|
||||
@@ -221,7 +221,7 @@ func (rt *Router) attemptSendEmail(c *gin.Context) {
|
||||
ginx.Bomb(200, "config(%v) invalid", f)
|
||||
}
|
||||
userVariableMap := rt.NotifyConfigCache.ConfigCache.Get()
|
||||
text := tplx.ReplaceMacroVariables(f.Ckey, f.Cval, userVariableMap)
|
||||
text := tplx.ReplaceTemplateUseText(f.Ckey, f.Cval, userVariableMap)
|
||||
smtp, err := SmtpValidate(text)
|
||||
ginx.Dangerous(err)
|
||||
|
||||
|
||||
@@ -167,8 +167,10 @@ func (rt *Router) dsProxy(c *gin.Context) {
|
||||
|
||||
modifyResponse := func(r *http.Response) error {
|
||||
if r.StatusCode == http.StatusUnauthorized {
|
||||
logger.Warningf("proxy path:%s unauthorized access ", c.Request.URL.Path)
|
||||
return fmt.Errorf("unauthorized access")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -180,6 +182,7 @@ func (rt *Router) dsProxy(c *gin.Context) {
|
||||
}
|
||||
|
||||
proxy.ServeHTTP(c.Writer, c.Request)
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/ccfos/nightingale/v6/center/cconf"
|
||||
"github.com/ccfos/nightingale/v6/models"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -17,6 +18,15 @@ func (rt *Router) rolesGets(c *gin.Context) {
|
||||
|
||||
func (rt *Router) permsGets(c *gin.Context) {
|
||||
user := c.MustGet("user").(*models.User)
|
||||
if user.IsAdmin() {
|
||||
var lst []string
|
||||
for _, ops := range cconf.Operations.Ops {
|
||||
lst = append(lst, ops.Ops...)
|
||||
}
|
||||
ginx.NewRender(c).Data(lst, nil)
|
||||
return
|
||||
}
|
||||
|
||||
lst, err := models.OperationsOfRole(rt.Ctx, strings.Fields(user.Roles))
|
||||
ginx.NewRender(c).Data(lst, err)
|
||||
}
|
||||
|
||||
@@ -34,10 +34,15 @@ func (rt *Router) userVariableConfigPut(context *gin.Context) {
|
||||
ginx.BindJSON(context, &f)
|
||||
f.Id = ginx.UrlParamInt64(context, "id")
|
||||
f.Ckey = strings.TrimSpace(f.Ckey)
|
||||
//update external config. needs to make sure not plaintext for an encrypted type config
|
||||
//updating with struct it will update all fields ("ckey", "cval", "note", "encrypted", "update_by", "update_at"), not non-zero fields.
|
||||
f.UpdateBy = context.MustGet("username").(string)
|
||||
f.UpdateAt = time.Now().Unix()
|
||||
|
||||
user := context.MustGet("user").(*models.User)
|
||||
if !user.IsAdmin() && f.CreateBy != user.Username {
|
||||
// only admin or creator can update
|
||||
ginx.Bomb(403, "no permission")
|
||||
}
|
||||
|
||||
ginx.NewRender(context).Message(models.ConfigsUserVariableUpdate(rt.Ctx, f))
|
||||
}
|
||||
|
||||
@@ -46,6 +51,12 @@ func (rt *Router) userVariableConfigDel(context *gin.Context) {
|
||||
configs, err := models.ConfigGet(rt.Ctx, id)
|
||||
ginx.Dangerous(err)
|
||||
|
||||
user := context.MustGet("user").(*models.User)
|
||||
if !user.IsAdmin() && configs.CreateBy != user.Username {
|
||||
// only admin or creator can delete
|
||||
ginx.Bomb(403, "no permission")
|
||||
}
|
||||
|
||||
if configs != nil && configs.External == models.ConfigExternal {
|
||||
ginx.NewRender(context).Message(models.ConfigsDel(rt.Ctx, []int64{id}))
|
||||
} else {
|
||||
|
||||
@@ -1,475 +0,0 @@
|
||||
{
|
||||
"name": "MSE监控大盘",
|
||||
"tags": "",
|
||||
"ident": "MSE-Monitor",
|
||||
"configs": {
|
||||
"var": [
|
||||
{
|
||||
"name": "datasource",
|
||||
"type": "datasource",
|
||||
"definition": "prometheus",
|
||||
"defaultValue": ""
|
||||
},
|
||||
{
|
||||
"name": "envoy_clusterid",
|
||||
"label": "envoy_clusterid",
|
||||
"type": "query",
|
||||
"hide": false,
|
||||
"definition": "label_values(envoy_cluster_bind_errors, envoy_clusterid)",
|
||||
"multi": false,
|
||||
"datasource": {
|
||||
"cate": "prometheus",
|
||||
"value": "${datasource}"
|
||||
}
|
||||
}
|
||||
],
|
||||
"panels": [
|
||||
{
|
||||
"type": "stat",
|
||||
"id": "aba69dc0-5a11-4bcd-add9-335b5a677bee",
|
||||
"layout": {
|
||||
"h": 5,
|
||||
"w": 6,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"i": "aba69dc0-5a11-4bcd-add9-335b5a677bee",
|
||||
"isResizable": true
|
||||
},
|
||||
"version": "3.0.0",
|
||||
"datasourceCate": "prometheus",
|
||||
"datasourceValue": 7,
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"expr": "sum(delta(envoy_http_rq_total{envoy_clusterid=\"$envoy_clusterid\"}[1m]))"
|
||||
}
|
||||
],
|
||||
"transformations": [
|
||||
{
|
||||
"id": "organize",
|
||||
"options": {}
|
||||
}
|
||||
],
|
||||
"name": "PV(一分钟)",
|
||||
"maxPerRow": 4,
|
||||
"custom": {
|
||||
"textMode": "valueAndName",
|
||||
"graphMode": "none",
|
||||
"colorMode": "value",
|
||||
"calc": "lastNotNull",
|
||||
"valueField": "Value",
|
||||
"colSpan": 1,
|
||||
"textSize": {}
|
||||
},
|
||||
"options": {
|
||||
"thresholds": {
|
||||
"steps": [
|
||||
{
|
||||
"color": "#634CD9",
|
||||
"value": null,
|
||||
"type": "base"
|
||||
}
|
||||
]
|
||||
},
|
||||
"standardOptions": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "pie",
|
||||
"id": "e34a272e-6125-4afa-a2c1-80d7d9078673",
|
||||
"layout": {
|
||||
"h": 5,
|
||||
"w": 18,
|
||||
"x": 6,
|
||||
"y": 0,
|
||||
"i": "116a5607-5860-426e-a560-d3241da88b57",
|
||||
"isResizable": true
|
||||
},
|
||||
"version": "3.0.0",
|
||||
"datasourceCate": "prometheus",
|
||||
"datasourceValue": 7,
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"expr": "sum(delta(envoy_http_downstream_rq{envoy_clusterid=\"$envoy_clusterid\"}[3m])) by (response_code_class)",
|
||||
"legend": ""
|
||||
}
|
||||
],
|
||||
"transformations": [
|
||||
{
|
||||
"id": "organize",
|
||||
"options": {}
|
||||
}
|
||||
],
|
||||
"name": "请求成功率",
|
||||
"maxPerRow": 4,
|
||||
"custom": {
|
||||
"calc": "lastNotNull",
|
||||
"legengPosition": "right",
|
||||
"detailName": "详情"
|
||||
},
|
||||
"options": {
|
||||
"standardOptions": {
|
||||
"util": "percentUnit",
|
||||
"decimals": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "timeseries",
|
||||
"id": "a8917108-58a6-479a-8ec4-571f1b5a79c2",
|
||||
"layout": {
|
||||
"h": 5,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 5,
|
||||
"i": "9be66a1f-c0bb-47dc-a3c0-ad43b588789b",
|
||||
"isResizable": true
|
||||
},
|
||||
"version": "3.0.0",
|
||||
"datasourceCate": "prometheus",
|
||||
"datasourceValue": 7,
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"expr": "sum(delta(envoy_http_downstream_cx_rx_bytes_total{envoy_clusterid=\"$envoy_clusterid\"}[1m]))",
|
||||
"legend": ""
|
||||
}
|
||||
],
|
||||
"transformations": [
|
||||
{
|
||||
"id": "organize",
|
||||
"options": {}
|
||||
}
|
||||
],
|
||||
"name": "请求量(一分钟)",
|
||||
"maxPerRow": 4,
|
||||
"options": {
|
||||
"tooltip": {
|
||||
"mode": "all",
|
||||
"sort": "none"
|
||||
},
|
||||
"legend": {
|
||||
"displayMode": "list"
|
||||
},
|
||||
"standardOptions": {
|
||||
"util": "bytesSI"
|
||||
},
|
||||
"thresholds": {
|
||||
"steps": [
|
||||
{
|
||||
"color": "#634CD9",
|
||||
"value": null,
|
||||
"type": "base"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"custom": {
|
||||
"drawStyle": "lines",
|
||||
"lineInterpolation": "smooth",
|
||||
"spanNulls": false,
|
||||
"lineWidth": 1,
|
||||
"fillOpacity": 0.5,
|
||||
"gradientMode": "none",
|
||||
"stack": "off",
|
||||
"scaleDistribution": {
|
||||
"type": "linear"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "timeseries",
|
||||
"id": "9062d707-d8a7-4a93-82e5-46f6059e8d70",
|
||||
"layout": {
|
||||
"h": 5,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 5,
|
||||
"i": "d36246b9-4a9c-4ab0-9171-c5ac330be0ca",
|
||||
"isResizable": true
|
||||
},
|
||||
"version": "3.0.0",
|
||||
"datasourceCate": "prometheus",
|
||||
"datasourceValue": 7,
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"expr": "sum(irate(envoy_http_downstream_rq{envoy_clusterid=\"$envoy_clusterid\"}[2m]))",
|
||||
"legend": ""
|
||||
}
|
||||
],
|
||||
"transformations": [
|
||||
{
|
||||
"id": "organize",
|
||||
"options": {}
|
||||
}
|
||||
],
|
||||
"name": "QPS",
|
||||
"maxPerRow": 4,
|
||||
"options": {
|
||||
"tooltip": {
|
||||
"mode": "all",
|
||||
"sort": "none"
|
||||
},
|
||||
"legend": {
|
||||
"displayMode": "list"
|
||||
},
|
||||
"standardOptions": {
|
||||
"util": "none"
|
||||
},
|
||||
"thresholds": {
|
||||
"steps": [
|
||||
{
|
||||
"color": "#634CD9",
|
||||
"value": null,
|
||||
"type": "base"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"custom": {
|
||||
"drawStyle": "lines",
|
||||
"lineInterpolation": "smooth",
|
||||
"spanNulls": false,
|
||||
"lineWidth": 1,
|
||||
"fillOpacity": 0.5,
|
||||
"gradientMode": "none",
|
||||
"stack": "off",
|
||||
"scaleDistribution": {
|
||||
"type": "linear"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "timeseries",
|
||||
"id": "1b102bee-ccc9-49a0-a1d1-cc097bb6a987",
|
||||
"layout": {
|
||||
"h": 6,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 10,
|
||||
"i": "1b102bee-ccc9-49a0-a1d1-cc097bb6a987",
|
||||
"isResizable": true
|
||||
},
|
||||
"version": "3.0.0",
|
||||
"datasourceCate": "prometheus",
|
||||
"datasourceValue": 7,
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"expr": "sum(rate(envoy_http_downstream_rq_time_sum{envoy_clusterid=\"$envoy_clusterid\"}[10m])) / sum(rate(envoy_http_downstream_rq_time_count{envoy_clusterid=\"$envoy_clusterid\"}[10m]))",
|
||||
"legend": ""
|
||||
}
|
||||
],
|
||||
"transformations": [
|
||||
{
|
||||
"id": "organize",
|
||||
"options": {}
|
||||
}
|
||||
],
|
||||
"name": "平均延迟",
|
||||
"maxPerRow": 4,
|
||||
"options": {
|
||||
"tooltip": {
|
||||
"mode": "all",
|
||||
"sort": "none"
|
||||
},
|
||||
"legend": {
|
||||
"displayMode": "list"
|
||||
},
|
||||
"standardOptions": {
|
||||
"util": "milliseconds"
|
||||
},
|
||||
"thresholds": {
|
||||
"steps": [
|
||||
{
|
||||
"color": "#634CD9",
|
||||
"value": null,
|
||||
"type": "base"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"custom": {
|
||||
"drawStyle": "lines",
|
||||
"lineInterpolation": "smooth",
|
||||
"spanNulls": false,
|
||||
"lineWidth": 1,
|
||||
"fillOpacity": 0.5,
|
||||
"gradientMode": "none",
|
||||
"stack": "off",
|
||||
"scaleDistribution": {
|
||||
"type": "linear"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "timeseries",
|
||||
"id": "b432fc11-2f9d-4b72-826b-6ca787401859",
|
||||
"layout": {
|
||||
"h": 6,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 10,
|
||||
"i": "ea4c1073-07d3-4adc-a4d3-4812cc55ad7c",
|
||||
"isResizable": true
|
||||
},
|
||||
"version": "3.0.0",
|
||||
"datasourceCate": "prometheus",
|
||||
"datasourceValue": 7,
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"expr": "histogram_quantile(0.95, sum(rate(envoy_http_downstream_rq_time_bucket{envoy_clusterid=\"$envoy_clusterid\"}[10m])) by (le, service))",
|
||||
"legend": ""
|
||||
}
|
||||
],
|
||||
"transformations": [
|
||||
{
|
||||
"id": "organize",
|
||||
"options": {}
|
||||
}
|
||||
],
|
||||
"name": "P95",
|
||||
"maxPerRow": 4,
|
||||
"options": {
|
||||
"tooltip": {
|
||||
"mode": "all",
|
||||
"sort": "none"
|
||||
},
|
||||
"legend": {
|
||||
"displayMode": "list"
|
||||
},
|
||||
"standardOptions": {
|
||||
"util": "milliseconds"
|
||||
},
|
||||
"thresholds": {
|
||||
"steps": [
|
||||
{
|
||||
"color": "#634CD9",
|
||||
"value": null,
|
||||
"type": "base"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"custom": {
|
||||
"drawStyle": "lines",
|
||||
"lineInterpolation": "smooth",
|
||||
"spanNulls": false,
|
||||
"lineWidth": 1,
|
||||
"fillOpacity": 0.5,
|
||||
"gradientMode": "none",
|
||||
"stack": "off",
|
||||
"scaleDistribution": {
|
||||
"type": "linear"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "barGauge",
|
||||
"id": "c3f64cfd-adb2-4316-bb84-55f88ed513a3",
|
||||
"layout": {
|
||||
"h": 6,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 16,
|
||||
"i": "807c34f9-bd61-4da3-ad88-41bb3e045605",
|
||||
"isResizable": true
|
||||
},
|
||||
"version": "3.0.0",
|
||||
"datasourceCate": "prometheus",
|
||||
"datasourceValue": 7,
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"expr": "label_replace(label_replace(topk(10, sum(delta(envoy_cluster_upstream_rq_total{envoy_clusterid=\"$envoy_clusterid\", cluster_name=~\"outbound_([0-9]+)_(.*)_(.*).svc.cluster.local$\", cluster_name!~\".*waf-proxy.static\", cluster_name!~\"outbound_([0-9]+)_(.*)_kubernetes.default.svc.cluster.local\", cluster_name!~\"outbound_([0-9]+)_(.*)_(.*).kube-system.svc.cluster.local\", cluster_name!~\"outbound_([0-9]+)_(.*)_(.*).arms-prom.svc.cluster.local\"}[1m])) by (cluster_name)), \"service_name\", \"$3\", \"cluster_name\", \"outbound_([0-9]+)_(.*)_(.*).svc.cluster.local$\"), \"port\", \"$1\", \"cluster_name\", \"outbound_([0-9]+)_(.*)_(.*).svc.cluster.local$\")",
|
||||
"legend": "{{service_name}}:{{port}}"
|
||||
}
|
||||
],
|
||||
"transformations": [
|
||||
{
|
||||
"id": "organize",
|
||||
"options": {}
|
||||
}
|
||||
],
|
||||
"name": "Top Service Request",
|
||||
"maxPerRow": 4,
|
||||
"custom": {
|
||||
"calc": "lastNotNull",
|
||||
"baseColor": "#9470FF",
|
||||
"serieWidth": 40,
|
||||
"sortOrder": "desc"
|
||||
},
|
||||
"options": {
|
||||
"standardOptions": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "timeseries",
|
||||
"id": "8df57678-ff19-4b63-b768-4dad3f12222b",
|
||||
"layout": {
|
||||
"h": 5,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 22,
|
||||
"i": "44f413ba-3262-4ccf-a4b1-c1165bafaaff",
|
||||
"isResizable": true
|
||||
},
|
||||
"version": "3.0.0",
|
||||
"datasourceCate": "prometheus",
|
||||
"datasourceValue": 7,
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"expr": "label_replace(label_replace(avg(delta(envoy_cluster_upstream_rq_time_sum{envoy_clusterid=\"$envoy_clusterid\", cluster_name=~\"outbound_([0-9]+)_(.*)_(.*)$\"}[3m])) by (cluster_name) / avg(delta(envoy_cluster_upstream_rq_time_count{envoy_clusterid=\"$envoy_clusterid\", cluster_name=~\"outbound_([0-9]+)_(.*)_(.*)$\"}[1m])) by (cluster_name), \"service_name\", \"$3\", \"cluster_name\", \"outbound_([0-9]+)_(.*)_(.*)$\"), \"port\", \"$1\", \"cluster_name\", \"outbound_([0-9]+)_(.*)_(.*)$\")",
|
||||
"legend": "{{service_name}}:{{port}}"
|
||||
}
|
||||
],
|
||||
"transformations": [
|
||||
{
|
||||
"id": "organize",
|
||||
"options": {}
|
||||
}
|
||||
],
|
||||
"name": "Top Service RT",
|
||||
"maxPerRow": 4,
|
||||
"options": {
|
||||
"tooltip": {
|
||||
"mode": "all",
|
||||
"sort": "none"
|
||||
},
|
||||
"legend": {
|
||||
"displayMode": "hidden"
|
||||
},
|
||||
"standardOptions": {
|
||||
"util": "milliseconds"
|
||||
},
|
||||
"thresholds": {
|
||||
"steps": [
|
||||
{
|
||||
"color": "#634CD9",
|
||||
"value": null,
|
||||
"type": "base"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"custom": {
|
||||
"drawStyle": "lines",
|
||||
"lineInterpolation": "smooth",
|
||||
"spanNulls": false,
|
||||
"lineWidth": 1,
|
||||
"fillOpacity": 0.5,
|
||||
"gradientMode": "none",
|
||||
"stack": "off",
|
||||
"scaleDistribution": {
|
||||
"type": "linear"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"version": "3.0.0"
|
||||
}
|
||||
}
|
||||
@@ -17,25 +17,62 @@
|
||||
],
|
||||
"panels": [
|
||||
{
|
||||
"type": "hexbin",
|
||||
"custom": {
|
||||
"calc": "lastNotNull",
|
||||
"colorRange": [
|
||||
"thresholds"
|
||||
],
|
||||
"detailUrl": "/dashboards/linux-host-by-categraf?ident=${__field.labels.ident}",
|
||||
"textMode": "valueAndName"
|
||||
},
|
||||
"datasourceCate": "prometheus",
|
||||
"datasourceValue": "${prom}",
|
||||
"id": "21b8b3ab-26aa-47cb-b814-f310f2d143aa",
|
||||
"layout": {
|
||||
"h": 5,
|
||||
"i": "21b8b3ab-26aa-47cb-b814-f310f2d143aa",
|
||||
"isResizable": true,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"i": "21b8b3ab-26aa-47cb-b814-f310f2d143aa",
|
||||
"isResizable": true
|
||||
"y": 0
|
||||
},
|
||||
"maxPerRow": 4,
|
||||
"name": "CPU利用率",
|
||||
"options": {
|
||||
"standardOptions": {
|
||||
"util": "percent"
|
||||
},
|
||||
"thresholds": {
|
||||
"steps": [
|
||||
{
|
||||
"color": "#ef3c3c",
|
||||
"type": "",
|
||||
"value": 95
|
||||
},
|
||||
{
|
||||
"color": "#ff656b",
|
||||
"type": "",
|
||||
"value": 85
|
||||
},
|
||||
{
|
||||
"color": "#ffae39",
|
||||
"type": "",
|
||||
"value": 75
|
||||
},
|
||||
{
|
||||
"color": "#2c9d3d",
|
||||
"type": "base",
|
||||
"value": null
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"version": "3.0.0",
|
||||
"datasourceCate": "prometheus",
|
||||
"datasourceValue": "${prom}",
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"expr": "cpu_usage_active{cpu=\"cpu-total\", ident=~\"$ident\"}",
|
||||
"instant": true,
|
||||
"legend": "{{ident}}",
|
||||
"instant": true
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"transformations": [
|
||||
@@ -44,66 +81,66 @@
|
||||
"options": {}
|
||||
}
|
||||
],
|
||||
"name": "CPU利用率",
|
||||
"maxPerRow": 4,
|
||||
"type": "hexbin",
|
||||
"version": "3.0.0"
|
||||
},
|
||||
{
|
||||
"custom": {
|
||||
"textMode": "valueAndName",
|
||||
"calc": "lastNotNull",
|
||||
"colorRange": [
|
||||
"thresholds"
|
||||
],
|
||||
"detailUrl": "/dashboards/linux-host-by-categraf?ident=${__field.labels.ident}"
|
||||
"detailUrl": "/dashboards/linux-host-by-categraf?ident=${__field.labels.ident}",
|
||||
"textMode": "valueAndName"
|
||||
},
|
||||
"options": {
|
||||
"thresholds": {
|
||||
"steps": [
|
||||
{
|
||||
"color": "#ef3c3c",
|
||||
"value": 95,
|
||||
"type": ""
|
||||
},
|
||||
{
|
||||
"color": "#ff656b",
|
||||
"value": 85,
|
||||
"type": ""
|
||||
},
|
||||
{
|
||||
"color": "#ffae39",
|
||||
"value": 75,
|
||||
"type": ""
|
||||
},
|
||||
{
|
||||
"color": "#2c9d3d",
|
||||
"value": null,
|
||||
"type": "base"
|
||||
}
|
||||
]
|
||||
},
|
||||
"standardOptions": {
|
||||
"util": "percent"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "hexbin",
|
||||
"datasourceCate": "prometheus",
|
||||
"datasourceValue": "${prom}",
|
||||
"id": "86d4a502-21f7-4981-9b38-ed8e696b6f49",
|
||||
"layout": {
|
||||
"h": 5,
|
||||
"i": "872b2040-c5b0-43fe-92c7-e37cb77edffc",
|
||||
"isResizable": true,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 0,
|
||||
"i": "872b2040-c5b0-43fe-92c7-e37cb77edffc",
|
||||
"isResizable": true
|
||||
"y": 0
|
||||
},
|
||||
"maxPerRow": 4,
|
||||
"name": "内存利用率",
|
||||
"options": {
|
||||
"standardOptions": {
|
||||
"util": "percent"
|
||||
},
|
||||
"thresholds": {
|
||||
"steps": [
|
||||
{
|
||||
"color": "#ef3c3c",
|
||||
"type": "",
|
||||
"value": 95
|
||||
},
|
||||
{
|
||||
"color": "#ff656b",
|
||||
"type": "",
|
||||
"value": 85
|
||||
},
|
||||
{
|
||||
"color": "#ffae39",
|
||||
"type": "",
|
||||
"value": 75
|
||||
},
|
||||
{
|
||||
"color": "#2c9d3d",
|
||||
"type": "base",
|
||||
"value": null
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"version": "3.0.0",
|
||||
"datasourceCate": "prometheus",
|
||||
"datasourceValue": "${prom}",
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"expr": "mem_used_percent{ident=~\"$ident\"}",
|
||||
"instant": true,
|
||||
"legend": "{{ident}}",
|
||||
"instant": true
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"transformations": [
|
||||
@@ -112,56 +149,19 @@
|
||||
"options": {}
|
||||
}
|
||||
],
|
||||
"name": "内存利用率",
|
||||
"maxPerRow": 4,
|
||||
"custom": {
|
||||
"textMode": "valueAndName",
|
||||
"calc": "lastNotNull",
|
||||
"colorRange": [
|
||||
"thresholds"
|
||||
],
|
||||
"detailUrl": "/dashboards/linux-host-by-categraf?ident=${__field.labels.ident}"
|
||||
},
|
||||
"options": {
|
||||
"thresholds": {
|
||||
"steps": [
|
||||
{
|
||||
"color": "#ef3c3c",
|
||||
"value": 95,
|
||||
"type": ""
|
||||
},
|
||||
{
|
||||
"color": "#ff656b",
|
||||
"value": 85,
|
||||
"type": ""
|
||||
},
|
||||
{
|
||||
"color": "#ffae39",
|
||||
"value": 75,
|
||||
"type": ""
|
||||
},
|
||||
{
|
||||
"color": "#2c9d3d",
|
||||
"value": null,
|
||||
"type": "base"
|
||||
}
|
||||
]
|
||||
},
|
||||
"standardOptions": {
|
||||
"util": "percent"
|
||||
}
|
||||
}
|
||||
"type": "hexbin",
|
||||
"version": "3.0.0"
|
||||
},
|
||||
{
|
||||
"type": "table",
|
||||
"id": "77bf513a-8504-4d33-9efe-75aaf9abc9e4",
|
||||
"layout": {
|
||||
"h": 11,
|
||||
"i": "77bf513a-8504-4d33-9efe-75aaf9abc9e4",
|
||||
"isResizable": true,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 5,
|
||||
"i": "77bf513a-8504-4d33-9efe-75aaf9abc9e4",
|
||||
"isResizable": true
|
||||
"y": 5
|
||||
},
|
||||
"version": "3.0.0",
|
||||
"datasourceCate": "prometheus",
|
||||
@@ -208,10 +208,11 @@
|
||||
"aggrDimension": "ident",
|
||||
"sortColumn": "ident",
|
||||
"sortOrder": "ascend",
|
||||
"linkMode": "appendLinkColumn",
|
||||
"links": [
|
||||
{
|
||||
"title": "详情",
|
||||
"url": "/dashboards/linux-host-by-categraf?ident=${__field.labels.ident}"
|
||||
"url": "/dashboards-built-in/detail?__built-in-cate=Linux&__built-in-name=Linux%20Host%20by%20Categraf&${__field.labels.ident}&prom=1"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -221,7 +222,8 @@
|
||||
"overrides": [
|
||||
{
|
||||
"matcher": {
|
||||
"value": "A"
|
||||
"value": "A",
|
||||
"id": "byFrameRefID"
|
||||
},
|
||||
"properties": {
|
||||
"standardOptions": {
|
||||
@@ -260,7 +262,8 @@
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"value": "B"
|
||||
"value": "B",
|
||||
"id": "byFrameRefID"
|
||||
},
|
||||
"properties": {
|
||||
"standardOptions": {
|
||||
@@ -300,7 +303,8 @@
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"value": "C"
|
||||
"value": "C",
|
||||
"id": "byFrameRefID"
|
||||
},
|
||||
"properties": {
|
||||
"standardOptions": {
|
||||
@@ -313,7 +317,8 @@
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"value": "D"
|
||||
"value": "D",
|
||||
"id": "byFrameRefID"
|
||||
},
|
||||
"properties": {
|
||||
"standardOptions": {
|
||||
@@ -322,22 +327,22 @@
|
||||
},
|
||||
"valueMappings": [
|
||||
{
|
||||
"type": "range",
|
||||
"match": {
|
||||
"to": 90
|
||||
},
|
||||
"result": {
|
||||
"color": "#2c9d3d"
|
||||
},
|
||||
"match": {
|
||||
"to": 90
|
||||
}
|
||||
"type": "range"
|
||||
},
|
||||
{
|
||||
"type": "range",
|
||||
"match": {
|
||||
"from": 90
|
||||
},
|
||||
"result": {
|
||||
"color": "#ff656b"
|
||||
},
|
||||
"match": {
|
||||
"from": 90
|
||||
}
|
||||
"type": "range"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -1,334 +0,0 @@
|
||||
{
|
||||
"name": "中间件业务-Seata集群-公共业务服务-服务看板",
|
||||
"tags": "",
|
||||
"ident": "",
|
||||
"configs": {
|
||||
"version": "2.0.0",
|
||||
"links": [],
|
||||
"var": [
|
||||
{
|
||||
"type": "query",
|
||||
"name": "instance",
|
||||
"definition": "label_values(seata_transaction,instance)",
|
||||
"allValue": null,
|
||||
"allOption": false,
|
||||
"multi": false,
|
||||
"reg": ""
|
||||
},
|
||||
{
|
||||
"type": "query",
|
||||
"name": "group",
|
||||
"definition": "label_values(seata_transaction,group)",
|
||||
"allValue": null,
|
||||
"allOption": true,
|
||||
"multi": true,
|
||||
"reg": ""
|
||||
}
|
||||
],
|
||||
"panels": [
|
||||
{
|
||||
"type": "timeseries",
|
||||
"id": "5a0db458-1fc7-4089-9265-d4bc74d015a4",
|
||||
"layout": {
|
||||
"h": 7,
|
||||
"w": 8,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"i": "5a0db458-1fc7-4089-9265-d4bc74d015a4",
|
||||
"isResizable": true
|
||||
},
|
||||
"version": "2.0.0",
|
||||
"datasourceCate": "prometheus",
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"expr": "sum(seata_transaction{instance=\"$instance\",group=~\"$group\",meter=\"summary\",statistic=\"count\",status=~\"committed|rollbacked\"}) by (status)",
|
||||
"legend": ""
|
||||
}
|
||||
],
|
||||
"name": "正常事务",
|
||||
"options": {
|
||||
"tooltip": {
|
||||
"mode": "all",
|
||||
"sort": "none"
|
||||
},
|
||||
"legend": {
|
||||
"displayMode": "hidden"
|
||||
},
|
||||
"standardOptions": {
|
||||
"util": "none"
|
||||
},
|
||||
"thresholds": {
|
||||
"steps": [
|
||||
{
|
||||
"color": "#634CD9",
|
||||
"value": null,
|
||||
"type": "base"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"custom": {
|
||||
"drawStyle": "lines",
|
||||
"lineInterpolation": "smooth",
|
||||
"spanNulls": false,
|
||||
"lineWidth": 1,
|
||||
"fillOpacity": 0.5,
|
||||
"gradientMode": "none",
|
||||
"stack": "off",
|
||||
"scaleDistribution": {
|
||||
"type": "linear"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "timeseries",
|
||||
"id": "ae6d99b2-2541-4093-838f-17dc358490e6",
|
||||
"layout": {
|
||||
"h": 7,
|
||||
"w": 8,
|
||||
"x": 8,
|
||||
"y": 0,
|
||||
"i": "604eb46d-b669-4ad6-890b-e7a45ef0ccec",
|
||||
"isResizable": true
|
||||
},
|
||||
"version": "2.0.0",
|
||||
"datasourceCate": "prometheus",
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"expr": "sum(seata_transaction{instance=\"$instance\",group=~\"$group\",meter=\"summary\",statistic=\"count\",status=~\"unretry|timeout\"}) by (status)",
|
||||
"legend": ""
|
||||
}
|
||||
],
|
||||
"name": "异常事务",
|
||||
"options": {
|
||||
"tooltip": {
|
||||
"mode": "all",
|
||||
"sort": "none"
|
||||
},
|
||||
"legend": {
|
||||
"displayMode": "hidden"
|
||||
},
|
||||
"standardOptions": {
|
||||
"util": "none"
|
||||
},
|
||||
"thresholds": {
|
||||
"steps": [
|
||||
{
|
||||
"color": "#634CD9",
|
||||
"value": null,
|
||||
"type": "base"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"custom": {
|
||||
"drawStyle": "lines",
|
||||
"lineInterpolation": "smooth",
|
||||
"spanNulls": false,
|
||||
"lineWidth": 1,
|
||||
"fillOpacity": 0.5,
|
||||
"gradientMode": "none",
|
||||
"stack": "off",
|
||||
"scaleDistribution": {
|
||||
"type": "linear"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "timeseries",
|
||||
"id": "c0341b0a-5e6e-4b7b-8916-003528e64ea4",
|
||||
"layout": {
|
||||
"h": 7,
|
||||
"w": 8,
|
||||
"x": 16,
|
||||
"y": 0,
|
||||
"i": "f835a637-11e1-4d9c-91ec-6bbcd874156b",
|
||||
"isResizable": true
|
||||
},
|
||||
"version": "2.0.0",
|
||||
"datasourceCate": "prometheus",
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"expr": "avg(seata_transaction{instance=\"$instance\",group=~\"$group\",meter=\"timer\",statistic=\"average\"}) by (status)",
|
||||
"legend": ""
|
||||
}
|
||||
],
|
||||
"name": "事务耗时(含业务时间)",
|
||||
"options": {
|
||||
"tooltip": {
|
||||
"mode": "all",
|
||||
"sort": "none"
|
||||
},
|
||||
"legend": {
|
||||
"displayMode": "hidden"
|
||||
},
|
||||
"standardOptions": {
|
||||
"util": "none"
|
||||
},
|
||||
"thresholds": {
|
||||
"steps": [
|
||||
{
|
||||
"color": "#634CD9",
|
||||
"value": null,
|
||||
"type": "base"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"custom": {
|
||||
"drawStyle": "lines",
|
||||
"lineInterpolation": "smooth",
|
||||
"spanNulls": false,
|
||||
"lineWidth": 1,
|
||||
"fillOpacity": 0.5,
|
||||
"gradientMode": "none",
|
||||
"stack": "off",
|
||||
"scaleDistribution": {
|
||||
"type": "linear"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "timeseries",
|
||||
"id": "0ed8fd7a-baa7-4b04-a003-d7fe0c26db11",
|
||||
"layout": {
|
||||
"h": 7,
|
||||
"w": 8,
|
||||
"x": 0,
|
||||
"y": 7,
|
||||
"i": "80f0ee2b-8706-43b4-a24a-ca8c7ce334f9",
|
||||
"isResizable": true
|
||||
},
|
||||
"version": "2.0.0",
|
||||
"datasourceCate": "prometheus",
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"expr": "sum(seata_transaction{instance=\"$instance\",group=~\"$group\",meter=\"summary\",statistic=\"tps\"}) by (status)",
|
||||
"legend": "{{status}}"
|
||||
}
|
||||
],
|
||||
"name": "事务TPS(按状态)",
|
||||
"options": {
|
||||
"tooltip": {
|
||||
"mode": "all",
|
||||
"sort": "none"
|
||||
},
|
||||
"legend": {
|
||||
"displayMode": "hidden"
|
||||
},
|
||||
"standardOptions": {
|
||||
"util": "none"
|
||||
},
|
||||
"thresholds": {
|
||||
"steps": [
|
||||
{
|
||||
"color": "#634CD9",
|
||||
"value": null,
|
||||
"type": "base"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"custom": {
|
||||
"drawStyle": "lines",
|
||||
"lineInterpolation": "smooth",
|
||||
"spanNulls": false,
|
||||
"lineWidth": 1,
|
||||
"fillOpacity": 0.5,
|
||||
"gradientMode": "none",
|
||||
"stack": "off",
|
||||
"scaleDistribution": {
|
||||
"type": "linear"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "timeseries",
|
||||
"id": "26f4ddbb-ddfd-4cbc-a71e-2530b6d59465",
|
||||
"layout": {
|
||||
"h": 7,
|
||||
"w": 8,
|
||||
"x": 8,
|
||||
"y": 7,
|
||||
"i": "869a8477-04ca-48c0-8c87-bd6859d61675",
|
||||
"isResizable": true
|
||||
},
|
||||
"version": "2.0.0",
|
||||
"datasourceCate": "prometheus",
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"expr": "sum(rate(seata_transaction{instance=\"$instance\",group=~\"$group\",meter=\"counter\",status=~\"committed|rollbacked\"}[1m])) by (instance)",
|
||||
"legend": "{{instance}}{{pod}}"
|
||||
}
|
||||
],
|
||||
"name": "事务TPS(按容器)",
|
||||
"options": {
|
||||
"tooltip": {
|
||||
"mode": "all",
|
||||
"sort": "none"
|
||||
},
|
||||
"legend": {
|
||||
"displayMode": "hidden"
|
||||
},
|
||||
"standardOptions": {
|
||||
"util": "none"
|
||||
},
|
||||
"thresholds": {
|
||||
"steps": [
|
||||
{
|
||||
"color": "#634CD9",
|
||||
"value": null,
|
||||
"type": "base"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"custom": {
|
||||
"drawStyle": "lines",
|
||||
"lineInterpolation": "smooth",
|
||||
"spanNulls": false,
|
||||
"lineWidth": 1,
|
||||
"fillOpacity": 0.5,
|
||||
"gradientMode": "none",
|
||||
"stack": "off",
|
||||
"scaleDistribution": {
|
||||
"type": "linear"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "pie",
|
||||
"id": "240abb70-e5b9-43e9-b691-c14f4be3b92a",
|
||||
"layout": {
|
||||
"h": 7,
|
||||
"w": 8,
|
||||
"x": 16,
|
||||
"y": 7,
|
||||
"i": "240abb70-e5b9-43e9-b691-c14f4be3b92a",
|
||||
"isResizable": true
|
||||
},
|
||||
"version": "2.0.0",
|
||||
"datasourceCate": "prometheus",
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"expr": "sum(seata_transaction{instance=\"$instance\",group=~\"$group\",meter=\"counter\"}) by (status)",
|
||||
"legend": "{{status}}"
|
||||
}
|
||||
],
|
||||
"name": "事务总量统计",
|
||||
"custom": {
|
||||
"calc": "lastNotNull",
|
||||
"legengPosition": "right",
|
||||
"donut": false,
|
||||
"labelWithName": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1290,10 +1290,9 @@
|
||||
"name": "ident",
|
||||
"type": "query",
|
||||
"datasource": {
|
||||
"cate": "prometheus",
|
||||
"value": "${prom}"
|
||||
"cate": "prometheus"
|
||||
},
|
||||
"definition": "label_values(system_load1{disk_used_percent{device=~\".+:\"},ident)",
|
||||
"definition": "label_values(disk_used_percent{device=~\".+:\"},ident)",
|
||||
"multi": true,
|
||||
"allOption": true
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ func (w *NotifyConfigCacheType) syncNotifyConfigs() error {
|
||||
return err
|
||||
}
|
||||
|
||||
cval = tplx.ReplaceMacroVariables(models.SMTP, cval, userVariableMap)
|
||||
cval = tplx.ReplaceTemplateUseText(models.SMTP, cval, userVariableMap)
|
||||
|
||||
if strings.TrimSpace(cval) != "" {
|
||||
err = toml.Unmarshal([]byte(cval), &w.smtp)
|
||||
|
||||
@@ -17,53 +17,53 @@ import (
|
||||
)
|
||||
|
||||
type AlertCurEvent struct {
|
||||
Id int64 `json:"id" gorm:"primaryKey"`
|
||||
Cate string `json:"cate"`
|
||||
Cluster string `json:"cluster"`
|
||||
DatasourceId int64 `json:"datasource_id"`
|
||||
GroupId int64 `json:"group_id"` // busi group id
|
||||
GroupName string `json:"group_name"` // busi group name
|
||||
Hash string `json:"hash"` // rule_id + vector_key
|
||||
RuleId int64 `json:"rule_id"`
|
||||
RuleName string `json:"rule_name"`
|
||||
RuleNote string `json:"rule_note"`
|
||||
RuleProd string `json:"rule_prod"`
|
||||
RuleAlgo string `json:"rule_algo"`
|
||||
Severity int `json:"severity"`
|
||||
PromForDuration int `json:"prom_for_duration"`
|
||||
PromQl string `json:"prom_ql"`
|
||||
RuleConfig string `json:"-" gorm:"rule_config"` // rule config
|
||||
RuleConfigJson interface{} `json:"rule_config" gorm:"-"` // rule config for fe
|
||||
PromEvalInterval int `json:"prom_eval_interval"`
|
||||
Callbacks string `json:"-"` // for db
|
||||
CallbacksJSON []string `json:"callbacks" gorm:"-"` // for fe
|
||||
RunbookUrl string `json:"runbook_url"`
|
||||
NotifyRecovered int `json:"notify_recovered"`
|
||||
NotifyChannels string `json:"-"` // for db
|
||||
NotifyChannelsJSON []string `json:"notify_channels" gorm:"-"` // for fe
|
||||
NotifyGroups string `json:"-"` // for db
|
||||
NotifyGroupsJSON []string `json:"notify_groups" gorm:"-"` // for fe
|
||||
NotifyGroupsObj []*UserGroup `json:"notify_groups_obj" gorm:"-"` // for fe
|
||||
TargetIdent string `json:"target_ident"`
|
||||
TargetNote string `json:"target_note"`
|
||||
TriggerTime int64 `json:"trigger_time"`
|
||||
TriggerValue string `json:"trigger_value"`
|
||||
Tags string `json:"-"` // for db
|
||||
TagsJSON []string `json:"tags" gorm:"-"` // for fe
|
||||
TagsMap map[string]string `json:"tags_map" gorm:"-"` // for internal usage
|
||||
Annotations string `json:"-"` //
|
||||
AnnotationsJSON map[string]string `json:"annotations" gorm:"-"` // for fe
|
||||
IsRecovered bool `json:"is_recovered" gorm:"-"` // for notify.py
|
||||
NotifyUsersObj []*User `json:"notify_users_obj" gorm:"-"` // for notify.py
|
||||
LastEvalTime int64 `json:"last_eval_time" gorm:"-"` // for notify.py 上次计算的时间
|
||||
LastEscalationNotifyTime int64 `json:"last_escalation_notify_time" gorm:"-"`
|
||||
LastSentTime int64 `json:"last_sent_time" gorm:"-"` // 上次发送时间
|
||||
NotifyCurNumber int `json:"notify_cur_number"` // notify: current number
|
||||
FirstTriggerTime int64 `json:"first_trigger_time"` // 连续告警的首次告警时间
|
||||
ExtraConfig interface{} `json:"extra_config" gorm:"-"`
|
||||
Status int `json:"status" gorm:"-"`
|
||||
Claimant string `json:"claimant" gorm:"-"`
|
||||
SubRuleId int64 `json:"sub_rule_id" gorm:"-"`
|
||||
Id int64 `json:"id" gorm:"primaryKey"`
|
||||
Cate string `json:"cate"`
|
||||
Cluster string `json:"cluster"`
|
||||
DatasourceId int64 `json:"datasource_id"`
|
||||
GroupId int64 `json:"group_id"` // busi group id
|
||||
GroupName string `json:"group_name"` // busi group name
|
||||
Hash string `json:"hash"` // rule_id + vector_key
|
||||
RuleId int64 `json:"rule_id"`
|
||||
RuleName string `json:"rule_name"`
|
||||
RuleNote string `json:"rule_note"`
|
||||
RuleProd string `json:"rule_prod"`
|
||||
RuleAlgo string `json:"rule_algo"`
|
||||
Severity int `json:"severity"`
|
||||
PromForDuration int `json:"prom_for_duration"`
|
||||
PromQl string `json:"prom_ql"`
|
||||
RuleConfig string `json:"-" gorm:"rule_config"` // rule config
|
||||
RuleConfigJson interface{} `json:"rule_config" gorm:"-"` // rule config for fe
|
||||
PromEvalInterval int `json:"prom_eval_interval"`
|
||||
Callbacks string `json:"-"` // for db
|
||||
CallbacksJSON []string `json:"callbacks" gorm:"-"` // for fe
|
||||
RunbookUrl string `json:"runbook_url"`
|
||||
NotifyRecovered int `json:"notify_recovered"`
|
||||
NotifyChannels string `json:"-"` // for db
|
||||
NotifyChannelsJSON []string `json:"notify_channels" gorm:"-"` // for fe
|
||||
NotifyGroups string `json:"-"` // for db
|
||||
NotifyGroupsJSON []string `json:"notify_groups" gorm:"-"` // for fe
|
||||
NotifyGroupsObj []*UserGroup `json:"notify_groups_obj" gorm:"-"` // for fe
|
||||
TargetIdent string `json:"target_ident"`
|
||||
TargetNote string `json:"target_note"`
|
||||
TriggerTime int64 `json:"trigger_time"`
|
||||
TriggerValue string `json:"trigger_value"`
|
||||
Tags string `json:"-"` // for db
|
||||
TagsJSON []string `json:"tags" gorm:"-"` // for fe
|
||||
TagsMap map[string]string `json:"tags_map" gorm:"-"` // for internal usage
|
||||
Annotations string `json:"-"` //
|
||||
AnnotationsJSON map[string]string `json:"annotations" gorm:"-"` // for fe
|
||||
IsRecovered bool `json:"is_recovered" gorm:"-"` // for notify.py
|
||||
NotifyUsersObj []*User `json:"notify_users_obj" gorm:"-"` // for notify.py
|
||||
LastEvalTime int64 `json:"last_eval_time" gorm:"-"` // for notify.py 上次计算的时间
|
||||
LastSentTime int64 `json:"last_sent_time" gorm:"-"` // 上次发送时间
|
||||
NotifyCurNumber int `json:"notify_cur_number"` // notify: current number
|
||||
FirstTriggerTime int64 `json:"first_trigger_time"` // 连续告警的首次告警时间
|
||||
ExtraConfig interface{} `json:"extra_config" gorm:"-"`
|
||||
Status int `json:"status" gorm:"-"`
|
||||
Claimant string `json:"claimant" gorm:"-"`
|
||||
SubRuleId int64 `json:"sub_rule_id" gorm:"-"`
|
||||
ExtraInfo []string `json:"extra_info" gorm:"-"`
|
||||
}
|
||||
|
||||
func (e *AlertCurEvent) TableName() string {
|
||||
|
||||
@@ -85,6 +85,16 @@ func InsertPermPoints(db *gorm.DB) {
|
||||
Operation: "/log/index-patterns",
|
||||
})
|
||||
|
||||
ops = append(ops, models.RoleOperation{
|
||||
RoleName: "Standard",
|
||||
Operation: "/help/variable-configs",
|
||||
})
|
||||
|
||||
ops = append(ops, models.RoleOperation{
|
||||
RoleName: "Admin",
|
||||
Operation: "/permissions",
|
||||
})
|
||||
|
||||
for _, op := range ops {
|
||||
exists, err := models.Exists(db.Model(&models.RoleOperation{}).Where("operation = ? and role_name = ?", op.Operation, op.RoleName))
|
||||
if err != nil {
|
||||
|
||||
@@ -567,9 +567,10 @@ func (u *User) UserGroups(ctx *ctx.Context, limit int, query string) ([]UserGrou
|
||||
return lst, err
|
||||
}
|
||||
|
||||
var user *User
|
||||
if len(lst) == 0 && len(query) > 0 {
|
||||
// 隐藏功能,一般人不告诉,哈哈。query可能是给的用户名,所以上面的sql没有查到,当做user来查一下试试
|
||||
user, err := UserGetByUsername(ctx, query)
|
||||
user, err = UserGetByUsername(ctx, query)
|
||||
if user == nil {
|
||||
return lst, err
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package aop
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -40,7 +41,8 @@ type LoggerConfig struct {
|
||||
|
||||
// Output is a writer where logs are written.
|
||||
// Optional. Default value is gin.DefaultWriter.
|
||||
Output io.Writer
|
||||
Output io.Writer
|
||||
PrintBody bool
|
||||
|
||||
// SkipPaths is a url path array which logs are not written.
|
||||
// Optional.
|
||||
@@ -177,8 +179,13 @@ func ErrorLoggerT(typ gin.ErrorType) gin.HandlerFunc {
|
||||
|
||||
// Logger instances a Logger middleware that will write the logs to gin.DefaultWriter.
|
||||
// By default gin.DefaultWriter = os.Stdout.
|
||||
func Logger() gin.HandlerFunc {
|
||||
return LoggerWithConfig(LoggerConfig{})
|
||||
func Logger(conf ...LoggerConfig) gin.HandlerFunc {
|
||||
var configuration LoggerConfig
|
||||
if len(conf) > 0 {
|
||||
configuration = conf[0]
|
||||
}
|
||||
|
||||
return LoggerWithConfig(configuration)
|
||||
}
|
||||
|
||||
// LoggerWithFormatter instance a Logger middleware with the specified log format function.
|
||||
@@ -197,6 +204,21 @@ func LoggerWithWriter(out io.Writer, notlogged ...string) gin.HandlerFunc {
|
||||
})
|
||||
}
|
||||
|
||||
type CustomResponseWriter struct {
|
||||
gin.ResponseWriter
|
||||
body *bytes.Buffer
|
||||
}
|
||||
|
||||
func (w CustomResponseWriter) Write(data []byte) (int, error) {
|
||||
w.body.Write(data)
|
||||
return w.ResponseWriter.Write(data)
|
||||
}
|
||||
|
||||
func (w CustomResponseWriter) WriteString(s string) (int, error) {
|
||||
w.body.WriteString(s)
|
||||
return w.ResponseWriter.WriteString(s)
|
||||
}
|
||||
|
||||
// LoggerWithConfig instance a Logger middleware with config.
|
||||
func LoggerWithConfig(conf LoggerConfig) gin.HandlerFunc {
|
||||
formatter := conf.Formatter
|
||||
@@ -234,18 +256,24 @@ func LoggerWithConfig(conf LoggerConfig) gin.HandlerFunc {
|
||||
path := c.Request.URL.Path
|
||||
raw := c.Request.URL.RawQuery
|
||||
|
||||
// var (
|
||||
// rdr1 io.ReadCloser
|
||||
// rdr2 io.ReadCloser
|
||||
// )
|
||||
var (
|
||||
rdr1 io.ReadCloser
|
||||
rdr2 io.ReadCloser
|
||||
)
|
||||
|
||||
// if c.Request.Method != "GET" {
|
||||
// buf, _ := ioutil.ReadAll(c.Request.Body)
|
||||
// rdr1 = ioutil.NopCloser(bytes.NewBuffer(buf))
|
||||
// rdr2 = ioutil.NopCloser(bytes.NewBuffer(buf))
|
||||
bodyWriter := &CustomResponseWriter{
|
||||
ResponseWriter: c.Writer,
|
||||
body: bytes.NewBuffer(nil),
|
||||
}
|
||||
c.Writer = bodyWriter
|
||||
|
||||
// c.Request.Body = rdr2
|
||||
// }
|
||||
if conf.PrintBody {
|
||||
buf, _ := io.ReadAll(c.Request.Body)
|
||||
rdr1 = io.NopCloser(bytes.NewBuffer(buf))
|
||||
rdr2 = io.NopCloser(bytes.NewBuffer(buf))
|
||||
|
||||
c.Request.Body = rdr2
|
||||
}
|
||||
|
||||
// Process request
|
||||
c.Next()
|
||||
@@ -277,18 +305,36 @@ func LoggerWithConfig(conf LoggerConfig) gin.HandlerFunc {
|
||||
|
||||
// fmt.Fprint(out, formatter(param))
|
||||
logger.Info(formatter(param))
|
||||
|
||||
// if c.Request.Method != "GET" {
|
||||
// logger.Debug(readBody(rdr1))
|
||||
// }
|
||||
if conf.PrintBody {
|
||||
respBody := readBody(bytes.NewReader(bodyWriter.body.Bytes()), c.Writer.Header().Get("Content-Encoding"))
|
||||
reqBody := readBody(rdr1, c.Request.Header.Get("Content-Encoding"))
|
||||
logger.Debugf("path:%s req body:%s resp:%s", path, reqBody, respBody)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func readBody(reader io.Reader) string {
|
||||
buf := new(bytes.Buffer)
|
||||
buf.ReadFrom(reader)
|
||||
func readBody(reader io.Reader, encoding string) string {
|
||||
var bodyBytes []byte
|
||||
var err error
|
||||
|
||||
s := buf.String()
|
||||
return s
|
||||
if encoding == "gzip" {
|
||||
gzipReader, err := gzip.NewReader(reader)
|
||||
if err != nil {
|
||||
return fmt.Sprintf("failed to create gzip reader: %v", err)
|
||||
}
|
||||
defer gzipReader.Close()
|
||||
|
||||
bodyBytes, err = io.ReadAll(gzipReader)
|
||||
if err != nil {
|
||||
return fmt.Sprintf("failed to read gzip response body: %v", err)
|
||||
}
|
||||
} else {
|
||||
bodyBytes, err = io.ReadAll(reader)
|
||||
if err != nil {
|
||||
return fmt.Sprintf("failed to read response body: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return string(bodyBytes)
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ type Config struct {
|
||||
KeyFile string
|
||||
PProf bool
|
||||
PrintAccessLog bool
|
||||
PrintBody bool
|
||||
ExposeMetrics bool
|
||||
ShutdownTimeout int
|
||||
MaxContentLength int64
|
||||
@@ -72,7 +73,7 @@ type JWTAuth struct {
|
||||
func GinEngine(mode string, cfg Config) *gin.Engine {
|
||||
gin.SetMode(mode)
|
||||
|
||||
loggerMid := aop.Logger()
|
||||
loggerMid := aop.Logger(aop.LoggerConfig{PrintBody: cfg.PrintBody})
|
||||
recoveryMid := aop.Recovery()
|
||||
|
||||
if strings.ToLower(mode) == "release" {
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
templateT "text/template"
|
||||
|
||||
"github.com/toolkits/pkg/logger"
|
||||
)
|
||||
@@ -37,7 +38,7 @@ var TemplateFuncMap = template.FuncMap{
|
||||
"formatDecimal": FormatDecimal,
|
||||
}
|
||||
|
||||
// ReplaceMacroVariables replaces variables in a template string with values.
|
||||
// ReplaceTemplateUseHtml replaces variables in a template string with values.
|
||||
//
|
||||
// It accepts the following parameters:
|
||||
//
|
||||
@@ -45,14 +46,14 @@ var TemplateFuncMap = template.FuncMap{
|
||||
//
|
||||
// - templateText: The template string containing variables to replace
|
||||
//
|
||||
// - macroValue: A struct containing fields to replace the variables
|
||||
// - templateData: A struct containing fields to replace the variables
|
||||
//
|
||||
// It parses the templateText into a template using template.New and template.Parse.
|
||||
//
|
||||
// It executes the parsed template with macroValue as the data, writing the result
|
||||
// It executes the parsed template with templateData as the data, writing the result
|
||||
// to a bytes.Buffer.
|
||||
//
|
||||
// Any {{.Field}} variables in templateText are replaced with values from macroValue.
|
||||
// Any {{.Field}} variables in templateText are replaced with values from templateData.
|
||||
//
|
||||
// If there are any errors parsing or executing the template, they are logged and
|
||||
// the original templateText is returned.
|
||||
@@ -67,17 +68,31 @@ var TemplateFuncMap = template.FuncMap{
|
||||
//
|
||||
// data := Data{"John"}
|
||||
//
|
||||
// output := ReplaceMacroVariables("mytpl", "Hello {{.Name}}!", data)
|
||||
func ReplaceMacroVariables(name string, templateText string, macroValue any) string {
|
||||
// output := ReplaceTemplateUseHtml("mytpl", "Hello {{.Name}}!", data)
|
||||
func ReplaceTemplateUseHtml(name string, templateText string, templateData any) string {
|
||||
tpl, err := template.New(name).Parse(templateText)
|
||||
if err != nil {
|
||||
logger.Warningf("parse config error: %v", err)
|
||||
return templateText
|
||||
}
|
||||
var body bytes.Buffer
|
||||
if err := tpl.Execute(&body, macroValue); err != nil {
|
||||
if err := tpl.Execute(&body, templateData); err != nil {
|
||||
logger.Warningf("execute config error: %v", err)
|
||||
return templateText
|
||||
}
|
||||
return body.String()
|
||||
}
|
||||
|
||||
func ReplaceTemplateUseText(name string, templateText string, templateData any) string {
|
||||
tpl, err := templateT.New(name).Parse(templateText)
|
||||
if err != nil {
|
||||
logger.Warningf("text parse config error: %v", err)
|
||||
return templateText
|
||||
}
|
||||
var body bytes.Buffer
|
||||
if err := tpl.Execute(&body, templateData); err != nil {
|
||||
logger.Warningf("text execute config error: %v", err)
|
||||
return templateText
|
||||
}
|
||||
return body.String()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user