Skip to content

Commit

Permalink
Merge pull request #3 from prometheus/refactor/show-alerts
Browse files Browse the repository at this point in the history
Show alerts in UI; add no-op silence dialog; cleanups.
  • Loading branch information
juliusv committed Jul 22, 2013
2 parents 8182f1b + ed289d5 commit 19e1ad7
Show file tree
Hide file tree
Showing 9 changed files with 179 additions and 37 deletions.
3 changes: 3 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
package main

import (
"flag"
"log"

"github.com/prometheus/alert_manager/manager"
Expand All @@ -22,6 +23,8 @@ import (
)

func main() {
flag.Parse()

log.Print("Starting event suppressor...")
suppressor := manager.NewSuppressor()
defer suppressor.Close()
Expand Down
17 changes: 12 additions & 5 deletions manager/aggregator.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
)

const (
minimumRepeatRate = 5 * time.Minute
minimumRefreshPeriod = 5 * time.Minute
notificationRetryPeriod = 1 * time.Minute
)
Expand Down Expand Up @@ -172,11 +173,10 @@ func (a *Aggregator) aggregate(req *aggregateEventsRequest, s SummaryReceiver) {
return
}
log.Println("aggregating", *req)
for _, element := range req.Events {
for _, event := range req.Events {
for _, r := range a.Rules {
log.Println("Checking rule", r, r.Handles(element))
if r.Handles(element) {
fp := element.Fingerprint()
if r.Handles(event) {
fp := event.Fingerprint()
aggregation, ok := a.Aggregates[fp]
if !ok {
expTimer := time.AfterFunc(minimumRefreshPeriod, func() {
Expand All @@ -192,7 +192,7 @@ func (a *Aggregator) aggregate(req *aggregateEventsRequest, s SummaryReceiver) {
a.Aggregates[fp] = aggregation
}

aggregation.Ingest(element)
aggregation.Ingest(event)
aggregation.SendNotification(s)
break
}
Expand All @@ -213,6 +213,13 @@ type aggregatorResetRulesRequest struct {

func (a *Aggregator) replaceRules(r *aggregatorResetRulesRequest) {
log.Println("Replacing", len(r.Rules), "aggregator rules...")

for _, rule := range r.Rules {
if rule.RepeatRate < minimumRepeatRate {
log.Println("Rule repeat rate too low, setting to minimum value")
rule.RepeatRate = minimumRepeatRate
}
}
a.Rules = r.Rules

r.Response <- new(aggregatorResetRulesResponse)
Expand Down
27 changes: 27 additions & 0 deletions web/helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright 2013 Prometheus Team
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package web

import (
"html/template"
"time"
)

func timeSince(t time.Time) string {
return time.Now().Round(time.Second / 10).Sub(t.Round(time.Second / 10)).String()
}

var webHelpers = template.FuncMap{
"timeSince": timeSince,
}
12 changes: 12 additions & 0 deletions web/static/css/default.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
body {
padding-top: 60px;
}

#create_silence_modal th {
text-align: left;
}

.add_silence_form {
display: inline;
}

.del_label_button {
margin-bottom: 10px;
}
49 changes: 49 additions & 0 deletions web/static/js/alerts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
function clearSilenceLabels() {
$("#silence_label_table").empty();
}

function addSilenceLabel(label, value) {
if (!label) {
label = "";
}
if (!value) {
value = "";
}
$("#silence_label_table").append(
'<tr>' +
' <td><input class="input-large" type="text" placeholder="label regex" value="' + label + '"></td>' +
' <td><input class="input-large" type="text" placeholder="value regex" value="' + value + '"></td>' +
' <td><button class="btn del_label_button"><i class="icon-minus"></i></button></td>' +
'</tr>');
bindDelLabel();
}

function bindDelLabel() {
$(".del_label_button").unbind("click");
$(".del_label_button").click(function() {
$(this).parents("tr").remove();
});
}

function init() {
$("#new_silence_btn").click(function() {
clearSilenceLabels();
});

$(".add_silence_btn").click(function() {
clearSilenceLabels();

var form = $(this).parents("form");
var labels = form.children('input[name="label[]"]');
var values = form.children('input[name="value[]"]');
for (var i = 0; i < labels.length; i++) {
addSilenceLabel(labels.get(i).value, values.get(i).value);
}
});

$("#add_label_button").click(function() {
addSilenceLabel("", "");
});
}

$(init);
44 changes: 43 additions & 1 deletion web/templates/_base.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Prometheus Alert Manager</title>

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>

<link href="/static/vendor/bootstrap/css/bootstrap.min.css" media="all" rel="stylesheet" type="text/css" />
<script src="/static/vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
<script src="/static/vendor/bootstrap/js/bootstrap.js" type="text/javascript"></script>

<link href="/static/css/default.css" media="all" rel="stylesheet" type="text/css" />

Expand Down Expand Up @@ -43,3 +45,43 @@
</div>
</body>
</html>
{{define "createSilenceModal"}}
<!-- Modal -->
<div id="create_silence_modal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="create_silence_header" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="create_silence_header">Create Silence</h3>
</div>
<div class="modal-body">
<form class="form-horizontal">
<div class="control-group">
<label class="control-label" for="silence_creator">Creator</label>
<div class="controls">
<input type="text" id="silence_creator" placeholder="Creator">
</div>
</div>
<div class="control-group">
<label class="control-label" for="silence_expiry">Expiry</label>
<div class="controls">
<input type="text" id="silence_expiry" placeholder="Expiry">
</div>
</div>
<div class="control-group">
<label class="control-label" for="silence_creator">Comment</label>
<div class="controls">
<input type="text" id="silence_comment" placeholder="Comment">
</div>
</div>
</form>
<label>Labels:</label>
<table id="silence_label_table">
</table>
<button class="btn" id="add_label_button"><i class="icon-plus"></i> Add Label Filter</button>
<button class="btn">Preview Silence</button>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
<button class="btn btn-primary">Create Silence</button>
</div>
</div>
{{end}}
50 changes: 24 additions & 26 deletions web/templates/alerts.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<h2>Alerts</h2>
<div class="input-append">
<input class="input-xxlarge" type="text" value="service=&quot;*&quot;">
<button class="btn" type="button"><i class="icon-search"></i></button>
<button class="btn" type="button"><i class="icon-filter"></i></button>
</div>
<table class="table table-striped table-bordered table-hover">
<thead>
Expand All @@ -23,34 +23,32 @@ <h2>Alerts</h2>
<tbody>
{{range .AlertAggregates}}
<tr>
<td>{{.Event}} <button class="btn btn-mini">Silence Alert</button></td>
<td>{{.Event.Labels}} <button class="btn btn-mini">Silence Instance</button></td>
<td>{{.Created}}</td>
<td>{{.LastRefreshed}}</td>
<td>
{{index .Event.Name}}
<form class="add_silence_form">
<input type="hidden" name="label[]" value="name">
<input type="hidden" name="value[]" value="{{.Event.Labels.name}}">
<a href="#create_silence_modal" role="button" class="btn btn-mini add_silence_btn" data-toggle="modal">Silence Alert</a>
</form>
</td>
<td>
{{range $label, $value := .Event.Labels}}
<b>{{$label}}</b>="{{$value}}",
{{end}}
<form class="add_silence_form">
{{range $label, $value := .Event.Labels}}
<input type="hidden" name="label[]" value="{{$label}}">
<input type="hidden" name="value[]" value="{{$value}}">
{{end}}
<a href="#create_silence_modal" role="button" class="btn btn-mini add_silence_btn" data-toggle="modal">Silence Instance</a>
</form>
</td>
<td>{{timeSince .Created}} ago</td>
<td>{{timeSince .LastRefreshed}} ago</td>
<td>No</td>
</tr>
{{end}}
<tr>
<td>TheTaxesAreTooDamnHigh <button class="btn btn-mini">Silence Alert</button></td>
<td>{foo="bar",baz="biz"} <button class="btn btn-mini">Silence Instance</button></td>
<td>...</td>
<td>...</td>
<td>No</td>
</tr>
<tr>
<td>TheTaxesAreTooDamnHigh <button class="btn btn-mini">Silence Alert</button></td>
<td>{foo="bar",baz="biz"} <button class="btn btn-mini">Silence Instance</button></td>
<td>...</td>
<td>...</td>
<td>No</td>
</tr>
<tr>
<td>TheTaxesAreTooDamnHigh <button class="btn btn-mini">Silence Alert</button></td>
<td>{foo="bar",baz="biz"} <button class="btn btn-mini">Silence Instance</button></td>
<td>...</td>
<td>...</td>
<td>No</td>
</tr>
</tbody>
</table>
{{template "createSilenceModal" .}}
{{end}}
3 changes: 2 additions & 1 deletion web/templates/silences.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

{{define "content"}}
<h2>Silences</h2>
<p><button class="btn btn-primary">New Silence</button><p/>
<p><a href="#create_silence_modal" role="button" class="btn btn-primary" id="new_silence_btn" data-toggle="modal">New Silence</a></p>
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
Expand Down Expand Up @@ -90,4 +90,5 @@ <h2>Silences</h2>
</tr>
</tbody>
</table>
{{template "createSilenceModal" .}}
{{end}}
11 changes: 7 additions & 4 deletions web/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,17 @@ func (w WebService) ServeForever() error {
}

func getLocalTemplate(name string) (*template.Template, error) {
return template.ParseFiles(
t := template.New("_base.html")
t.Funcs(webHelpers)
return t.ParseFiles(
"web/templates/_base.html",
fmt.Sprintf("web/templates/%s.html", name),
)
}

func getEmbeddedTemplate(name string) (*template.Template, error) {
t := template.New("_base")
t := template.New("_base.html")
t.Funcs(webHelpers)

file, err := blob.GetFile(blob.TemplateFiles, "_base.html")
if err != nil {
Expand All @@ -110,10 +113,10 @@ func getTemplate(name string) (t *template.Template, err error) {
}

if err != nil {
return
return nil, err
}

return
return t, nil
}

func executeTemplate(w http.ResponseWriter, name string, data interface{}) {
Expand Down

0 comments on commit 19e1ad7

Please sign in to comment.