Skip to content

Commit d52fc8d

Browse files
committed
Merge branch 'alert_ui_take2' into alerting
2 parents 66d47a9 + 9216492 commit d52fc8d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+1968
-1387
lines changed

.floo

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
{
2-
"url": "https://floobits.com/raintank/grafana"
3-
}
4-
2+
"url": "https://floobits.com/raintank/grafana"
3+
}

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
* **InfluxDB**: Add spread function, closes [#5211](https://github.com/grafana/grafana/issues/5211)
1111
* **Scripts**: Use restart instead of start for deb package script, closes [#5282](https://github.com/grafana/grafana/pull/5282)
1212
* **Logging**: Moved to structured logging lib, and moved to component specific level filters via config file, closes [#4590](https://github.com/grafana/grafana/issues/4590)
13+
* **Search**: Add search limit query parameter, closes [#5292](https://github.com/grafana/grafana/pull/5292)
1314

1415
## Breaking changes
1516
* **Logging** : Changed default logging output format (now structured into message, and key value pairs, with logger key acting as component). You can also no change in config to json log ouput.

alerting_model.json

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
{
2+
"alert": {
3+
"name": "Majority servers down",
4+
"frequency": 60,
5+
"notify": ["group1", "group2"],
6+
"expressions": [
7+
{
8+
"left": [
9+
{
10+
"type": "query",
11+
"refId": "A",
12+
"timeRange": {"from": "5m", "to": "now-1m"},
13+
},
14+
{
15+
"type": "function",
16+
"name": "max"
17+
}
18+
],
19+
"operator": ">",
20+
"right": [
21+
{
22+
"type": "constant",
23+
"value": 100
24+
}
25+
],
26+
"level": 2,
27+
}
28+
]
29+
},
30+
31+
"alert": {
32+
"name": "Majority servers down take2",
33+
"frequency": 60,
34+
"notify": ["group1", "group2"],
35+
"expressions": [
36+
{
37+
"left": [
38+
{
39+
"type": "query",
40+
"refId": "A",
41+
"timeRange": {"from": "5m", "to": "now-1m"},
42+
},
43+
{
44+
"type": "function",
45+
"name": "max"
46+
}
47+
],
48+
"operator": ">",
49+
"right": [
50+
{
51+
"type": "query",
52+
"refId": "A",
53+
"timeRange": {"from": "now-1d-5m", "to": "now-1d"},
54+
},
55+
{
56+
"type": "function",
57+
"name": "max"
58+
}
59+
],
60+
"level": 2,
61+
}
62+
]
63+
},
64+
"alert": {
65+
"name": "CPU usage last 5min above 90%",
66+
"frequency": 60,
67+
"expressions": [
68+
{
69+
"expr": "query(#A, 5m, now, avg)",
70+
"operator": ">",
71+
"critLevel": 90,
72+
}
73+
]
74+
},
75+
"alert": {
76+
"name": "Series count above 10",
77+
"frequency": "1m",
78+
"expressions": [
79+
{
80+
"expr": "query(#A, 5m, now, avg) | countSeries()",
81+
"operator": ">",
82+
"critLevel": 10,
83+
}
84+
]
85+
},
86+
"alert": {
87+
"name": "Disk Free Zero in 3 days",
88+
"frequency": "1d",
89+
"expressions": [
90+
{
91+
"expr": "query(#A, 1d, now, trend(3d))",
92+
"operator": ">",
93+
"critLevel": 0,
94+
}
95+
]
96+
},
97+
"alert": {
98+
"name": "Server requests is zero for more than 10min",
99+
"frequency": "1d",
100+
"expressions": [
101+
{
102+
"expr": "query(#A, 10m, now, sum)",
103+
"operator": "=",
104+
"critLevel": 0,
105+
}
106+
]
107+
},
108+
"alert": {
109+
"name": "Timeouts should not be more than 0.1% of requests",
110+
"frequency": "1d",
111+
"expressions": [
112+
{
113+
"expr": "query(#A, 10m, now, sum) | subtract | query(#B, 10m, now, sum)",
114+
"operator": ">",
115+
"critLevel": 0,
116+
}
117+
]
118+
},
119+
"alert": {
120+
"name": "CPU usage last 5min changed by more than 20% compared to last 24hours",
121+
"frequency": "1m",
122+
"value": "query(#A, 5m, now, avg)",
123+
"operator": "percent change",
124+
"threshold": "query(#A, 1d, now, avg)",
125+
},
126+
127+
"alert": {
128+
"name": "CPU higher than 90%",
129+
"frequency": "1m",
130+
"valueExpr": "query(#A, 5m, now, avg)",
131+
"evalType": "greater than",
132+
"critLevel": 20,
133+
"warnLevel": 10,
134+
},
135+
136+
"alert": {
137+
"name": "CPU usage last 5min changed by more than 20% compared to last 24hours",
138+
"frequency": "1m",
139+
"expr": "query(#A, 5m, now, avg) percentGreaterThan()",
140+
"evalType": "percentscre change",
141+
"evalExpr": "query(#A, 1d, now, avg)",
142+
"critLevel": 20,
143+
"warnLevel": 10,
144+
},
145+
"alert": {
146+
"name": "CPU usage last 5min changed by more than 20% compared to last 24hours",
147+
"frequency": "1m",
148+
"valueQuery": "query(#A, 5m, now, avg) ",
149+
"evalType": "simple", "// other options are: percent change, trend"
150+
"evalQuery": "query(#A, 1d, now, avg)",
151+
"comparison": "greater than",
152+
"critLevel": 20,
153+
"warnLevel": 10,
154+
},
155+
"alert": {
156+
"name": "CPU usage last 5min changed by more than 20% compared to last 24hours",
157+
"frequency": "1m",
158+
"valueQuery": "query(#A, 5m, now, avg) | Evaluate Against: Static Threshold | >200 Warn | >300 Critical",
159+
"valueQuery": "query(#A, 5m, now, avg) | Evaluate Against: Percent Change Compared To | query(#B, 5m, now, avg) | >200 Warn | >300 Critical",
160+
"valueQuery": "query(#A, 5m, now, trend) | Evaluate Against: Forcast | 7days | >200 Warn | >300 Critical",
161+
"evalType": "simple", "// other options are: percent change, trend"
162+
"evalQuery": "query(#A, 1d, now, avg)",
163+
"comparison": "greater than",
164+
"critLevel": 20,
165+
"warnLevel": 10,
166+
},
167+
}

pkg/api/alerting.go

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func GetAlertChanges(c *middleware.Context) Response {
4343
return Json(200, query.Result)
4444
}
4545

46-
// GET /api/alerts
46+
// GET /api/alerts/rules/
4747
func GetAlerts(c *middleware.Context) Response {
4848
query := models.GetAlertsQuery{
4949
OrgId: c.OrgId,
@@ -64,15 +64,8 @@ func GetAlerts(c *middleware.Context) Response {
6464
Id: alert.Id,
6565
DashboardId: alert.DashboardId,
6666
PanelId: alert.PanelId,
67-
Query: alert.Query,
68-
QueryRefId: alert.QueryRefId,
69-
WarnLevel: alert.WarnLevel,
70-
CritLevel: alert.CritLevel,
71-
Frequency: alert.Frequency,
7267
Name: alert.Name,
7368
Description: alert.Description,
74-
QueryRange: alert.QueryRange,
75-
Aggregator: alert.Aggregator,
7669
State: alert.State,
7770
})
7871
}

pkg/api/common.go

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"encoding/json"
55
"net/http"
66

7-
"github.com/grafana/grafana/pkg/log"
87
"github.com/grafana/grafana/pkg/metrics"
98
"github.com/grafana/grafana/pkg/middleware"
109
"github.com/grafana/grafana/pkg/setting"
@@ -21,13 +20,15 @@ var (
2120
)
2221

2322
type Response interface {
24-
WriteTo(out http.ResponseWriter)
23+
WriteTo(ctx *middleware.Context)
2524
}
2625

2726
type NormalResponse struct {
28-
status int
29-
body []byte
30-
header http.Header
27+
status int
28+
body []byte
29+
header http.Header
30+
errMessage string
31+
err error
3132
}
3233

3334
func wrap(action interface{}) macaron.Handler {
@@ -41,17 +42,21 @@ func wrap(action interface{}) macaron.Handler {
4142
res = ServerError(err)
4243
}
4344

44-
res.WriteTo(c.Resp)
45+
res.WriteTo(c)
4546
}
4647
}
4748

48-
func (r *NormalResponse) WriteTo(out http.ResponseWriter) {
49-
header := out.Header()
49+
func (r *NormalResponse) WriteTo(ctx *middleware.Context) {
50+
if r.err != nil {
51+
ctx.Logger.Error(r.errMessage, "error", r.err)
52+
}
53+
54+
header := ctx.Resp.Header()
5055
for k, v := range r.header {
5156
header[k] = v
5257
}
53-
out.WriteHeader(r.status)
54-
out.Write(r.body)
58+
ctx.Resp.WriteHeader(r.status)
59+
ctx.Resp.Write(r.body)
5560
}
5661

5762
func (r *NormalResponse) Cache(ttl string) *NormalResponse {
@@ -64,7 +69,6 @@ func (r *NormalResponse) Header(key, value string) *NormalResponse {
6469
}
6570

6671
// functions to create responses
67-
6872
func Empty(status int) *NormalResponse {
6973
return Respond(status, nil)
7074
}
@@ -80,29 +84,35 @@ func ApiSuccess(message string) *NormalResponse {
8084
}
8185

8286
func ApiError(status int, message string, err error) *NormalResponse {
83-
resp := make(map[string]interface{})
84-
85-
if err != nil {
86-
log.Error(4, "%s: %v", message, err)
87-
if setting.Env != setting.PROD {
88-
resp["error"] = err.Error()
89-
}
90-
}
87+
data := make(map[string]interface{})
9188

9289
switch status {
9390
case 404:
9491
metrics.M_Api_Status_404.Inc(1)
95-
resp["message"] = "Not Found"
92+
data["message"] = "Not Found"
9693
case 500:
9794
metrics.M_Api_Status_500.Inc(1)
98-
resp["message"] = "Internal Server Error"
95+
data["message"] = "Internal Server Error"
9996
}
10097

10198
if message != "" {
102-
resp["message"] = message
99+
data["message"] = message
100+
}
101+
102+
if err != nil {
103+
if setting.Env != setting.PROD {
104+
data["error"] = err.Error()
105+
}
106+
}
107+
108+
resp := Json(status, data)
109+
110+
if err != nil {
111+
resp.errMessage = message
112+
resp.err = err
103113
}
104114

105-
return Json(status, resp)
115+
return resp
106116
}
107117

108118
func Respond(status int, body interface{}) *NormalResponse {

pkg/api/dashboard.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -151,15 +151,13 @@ func PostDashboard(c *middleware.Context, cmd m.SaveDashboardCommand) {
151151
}
152152

153153
if setting.AlertingEnabled {
154-
saveAlertCommand := m.SaveAlertsCommand{
155-
DashboardId: cmd.Result.Id,
156-
OrgId: c.OrgId,
157-
UserId: c.UserId,
158-
Alerts: alerting.ParseAlertsFromDashboard(&cmd),
154+
alertCmd := alerting.UpdateDashboardAlertsCommand{
155+
OrgId: c.OrgId,
156+
UserId: c.UserId,
157+
Dashboard: cmd.Result,
159158
}
160159

161-
err = bus.Dispatch(&saveAlertCommand)
162-
if err != nil {
160+
if err := bus.Dispatch(&alertCmd); err != nil {
163161
c.JsonApiErr(500, "Failed to save alerts", err)
164162
return
165163
}

pkg/log/log.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212

1313
"gopkg.in/ini.v1"
1414

15+
"github.com/go-stack/stack"
1516
"github.com/inconshreveable/log15"
1617
"github.com/inconshreveable/log15/term"
1718
)
@@ -22,6 +23,7 @@ var loggersToClose []DisposableHandler
2223
func init() {
2324
loggersToClose = make([]DisposableHandler, 0)
2425
Root = log15.Root()
26+
Root.SetHandler(log15.DiscardHandler())
2527
}
2628

2729
func New(logger string, ctx ...interface{}) Logger {
@@ -227,3 +229,9 @@ func LogFilterHandler(maxLevel log15.Lvl, filters map[string]log15.Lvl, h log15.
227229
return r.Lvl <= maxLevel
228230
}, h)
229231
}
232+
233+
func Stack(skip int) string {
234+
call := stack.Caller(skip)
235+
s := stack.Trace().TrimBelow(call).TrimRuntime()
236+
return s.String()
237+
}

pkg/middleware/logger.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,11 @@ func Logger() macaron.Handler {
4848

4949
if ctx, ok := c.Data["ctx"]; ok {
5050
ctxTyped := ctx.(*Context)
51-
ctxTyped.Logger.Info("Request Completed", "method", req.Method, "path", req.URL.Path, "status", status, "remote_addr", c.RemoteAddr(), "time_ns", timeTakenMs, "size", rw.Size())
51+
if status == 500 {
52+
ctxTyped.Logger.Error("Request Completed", "method", req.Method, "path", req.URL.Path, "status", status, "remote_addr", c.RemoteAddr(), "time_ns", timeTakenMs, "size", rw.Size())
53+
} else {
54+
ctxTyped.Logger.Info("Request Completed", "method", req.Method, "path", req.URL.Path, "status", status, "remote_addr", c.RemoteAddr(), "time_ns", timeTakenMs, "size", rw.Size())
55+
}
5256
}
5357
}
5458
}

0 commit comments

Comments
 (0)