Update HTTP/clientlib dependencies + cleanups.
Change-Id: I175ac4874b25358dd569866e3d575ba49e4357f2
This commit is contained in:
parent
6d789102f9
commit
20b146657b
|
@ -17,8 +17,27 @@ import (
|
|||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
var configLoads = prometheus.NewCounter()
|
||||
const namespace = "alertmanager"
|
||||
|
||||
var configReloads = prometheus.NewCounter(
|
||||
prometheus.CounterOpts{
|
||||
Namespace: namespace,
|
||||
Subsystem: "config",
|
||||
Name: "reloads_total",
|
||||
Help: "The total number of configuration reloads.",
|
||||
},
|
||||
)
|
||||
|
||||
var failedConfigReloads = prometheus.NewCounter(
|
||||
prometheus.CounterOpts{
|
||||
Namespace: namespace,
|
||||
Subsystem: "config",
|
||||
Name: "failed_reloads_total",
|
||||
Help: "The number of failed configuration reloads.",
|
||||
},
|
||||
)
|
||||
|
||||
func init() {
|
||||
prometheus.Register("alertmanager_config_reloads_total", "The number of configuration reloads.", prometheus.NilLabels, configLoads)
|
||||
prometheus.MustRegister(configReloads)
|
||||
prometheus.MustRegister(failedConfigReloads)
|
||||
}
|
||||
|
|
|
@ -52,11 +52,11 @@ func (w *fileWatcher) Watch(cb ReloadCallback) {
|
|||
conf, err := LoadFromFile(w.fileName)
|
||||
if err != nil {
|
||||
glog.Error("Error loading new config: ", err)
|
||||
configLoads.Increment(map[string]string{"outcome": "failure"})
|
||||
failedConfigReloads.Inc()
|
||||
} else {
|
||||
cb(&conf)
|
||||
glog.Info("Config reloaded successfully")
|
||||
configLoads.Increment(map[string]string{"outcome": "success"})
|
||||
configReloads.Inc()
|
||||
}
|
||||
// Re-add the file watcher since it can get lost on some changes. E.g.
|
||||
// saving a file with vim results in a RENAME-MODIFY-DELETE event
|
||||
|
|
|
@ -23,12 +23,12 @@ import (
|
|||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
type SilenceId uint
|
||||
type SilenceID uint
|
||||
type Silences []*Silence
|
||||
|
||||
type Silence struct {
|
||||
// The numeric ID of the silence.
|
||||
Id SilenceId
|
||||
ID SilenceID
|
||||
// Name/email of the silence creator.
|
||||
CreatedBy string
|
||||
// When the silence was first created (Unix timestamp).
|
||||
|
@ -45,7 +45,7 @@ type Silence struct {
|
|||
}
|
||||
|
||||
type ApiSilence struct {
|
||||
Id SilenceId
|
||||
ID SilenceID
|
||||
CreatedBy string
|
||||
CreatedAtSeconds int64
|
||||
EndsAtSeconds int64
|
||||
|
@ -62,7 +62,7 @@ func (s *Silence) MarshalJSON() ([]byte, error) {
|
|||
}
|
||||
|
||||
return json.Marshal(&ApiSilence{
|
||||
Id: s.Id,
|
||||
ID: s.ID,
|
||||
CreatedBy: s.CreatedBy,
|
||||
CreatedAtSeconds: s.CreatedAt.Unix(),
|
||||
EndsAtSeconds: s.EndsAt.Unix(),
|
||||
|
@ -88,7 +88,7 @@ func (s *Silence) UnmarshalJSON(data []byte) error {
|
|||
}
|
||||
|
||||
*s = Silence{
|
||||
Id: sc.Id,
|
||||
ID: sc.ID,
|
||||
CreatedBy: sc.CreatedBy,
|
||||
CreatedAt: time.Unix(sc.CreatedAtSeconds, 0).UTC(),
|
||||
EndsAt: time.Unix(sc.EndsAtSeconds, 0).UTC(),
|
||||
|
@ -104,9 +104,9 @@ func (s Silence) Matches(l AlertLabelSet) bool {
|
|||
|
||||
type Silencer struct {
|
||||
// Silences managed by this Silencer.
|
||||
Silences map[SilenceId]*Silence
|
||||
// Used to track the next Silence Id to allocate.
|
||||
lastId SilenceId
|
||||
Silences map[SilenceID]*Silence
|
||||
// Used to track the next Silence ID to allocate.
|
||||
lastID SilenceID
|
||||
// Tracks whether silences have changed since the last call to HasChanged.
|
||||
dirty bool
|
||||
|
||||
|
@ -120,13 +120,13 @@ type IsSilencedInterrogator interface {
|
|||
|
||||
func NewSilencer() *Silencer {
|
||||
return &Silencer{
|
||||
Silences: make(map[SilenceId]*Silence),
|
||||
Silences: make(map[SilenceID]*Silence),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Silencer) nextSilenceId() SilenceId {
|
||||
s.lastId++
|
||||
return s.lastId
|
||||
func (s *Silencer) nextSilenceID() SilenceID {
|
||||
s.lastID++
|
||||
return s.lastID
|
||||
}
|
||||
|
||||
func (s *Silencer) setupExpiryTimer(sc *Silence) {
|
||||
|
@ -135,29 +135,29 @@ func (s *Silencer) setupExpiryTimer(sc *Silence) {
|
|||
}
|
||||
expDuration := sc.EndsAt.Sub(time.Now())
|
||||
sc.expiryTimer = time.AfterFunc(expDuration, func() {
|
||||
if err := s.DelSilence(sc.Id); err != nil {
|
||||
glog.Errorf("Failed to delete silence %d: %s", sc.Id, err)
|
||||
if err := s.DelSilence(sc.ID); err != nil {
|
||||
glog.Errorf("Failed to delete silence %d: %s", sc.ID, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Silencer) AddSilence(sc *Silence) SilenceId {
|
||||
func (s *Silencer) AddSilence(sc *Silence) SilenceID {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
s.dirty = true
|
||||
|
||||
if sc.Id == 0 {
|
||||
sc.Id = s.nextSilenceId()
|
||||
if sc.ID == 0 {
|
||||
sc.ID = s.nextSilenceID()
|
||||
} else {
|
||||
if sc.Id > s.lastId {
|
||||
s.lastId = sc.Id
|
||||
if sc.ID > s.lastID {
|
||||
s.lastID = sc.ID
|
||||
}
|
||||
}
|
||||
|
||||
s.setupExpiryTimer(sc)
|
||||
s.Silences[sc.Id] = sc
|
||||
return sc.Id
|
||||
s.Silences[sc.ID] = sc
|
||||
return sc.ID
|
||||
}
|
||||
|
||||
func (s *Silencer) UpdateSilence(sc *Silence) error {
|
||||
|
@ -166,9 +166,9 @@ func (s *Silencer) UpdateSilence(sc *Silence) error {
|
|||
|
||||
s.dirty = true
|
||||
|
||||
origSilence, ok := s.Silences[sc.Id]
|
||||
origSilence, ok := s.Silences[sc.ID]
|
||||
if !ok {
|
||||
return fmt.Errorf("Silence with ID %d doesn't exist", sc.Id)
|
||||
return fmt.Errorf("Silence with ID %d doesn't exist", sc.ID)
|
||||
}
|
||||
if sc.EndsAt != origSilence.EndsAt {
|
||||
origSilence.expiryTimer.Stop()
|
||||
|
@ -178,7 +178,7 @@ func (s *Silencer) UpdateSilence(sc *Silence) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *Silencer) GetSilence(id SilenceId) (*Silence, error) {
|
||||
func (s *Silencer) GetSilence(id SilenceID) (*Silence, error) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
|
@ -189,7 +189,7 @@ func (s *Silencer) GetSilence(id SilenceId) (*Silence, error) {
|
|||
return sc, nil
|
||||
}
|
||||
|
||||
func (s *Silencer) DelSilence(id SilenceId) error {
|
||||
func (s *Silencer) DelSilence(id SilenceID) error {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
|
|
|
@ -33,10 +33,10 @@ func (scenario *testSilencerScenario) test(i int, t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatalf("%d.%d. Error getting silence: %s", i, j, err)
|
||||
}
|
||||
if retrievedSilence.Id != id {
|
||||
t.Fatalf("%d.%d. Expected ID %d, got %d", i, j, id, retrievedSilence.Id)
|
||||
if retrievedSilence.ID != id {
|
||||
t.Fatalf("%d.%d. Expected ID %d, got %d", i, j, id, retrievedSilence.ID)
|
||||
}
|
||||
sc.Id = id
|
||||
sc.ID = id
|
||||
if sc != retrievedSilence {
|
||||
t.Fatalf("%d.%d. Expected silence %v, got %v", i, j, sc, retrievedSilence)
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ func (scenario *testSilencerScenario) test(i int, t *testing.T) {
|
|||
}
|
||||
|
||||
for j, sc := range silences {
|
||||
if err := s.DelSilence(sc.Id); err != nil {
|
||||
if err := s.DelSilence(sc.ID); err != nil {
|
||||
t.Fatalf("%d.%d. Got error while deleting silence: %s", i, j, err)
|
||||
}
|
||||
|
||||
|
|
|
@ -14,28 +14,29 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
|
||||
"github.com/prometheus/alertmanager/manager"
|
||||
)
|
||||
|
||||
func (s AlertManagerService) AddAlerts(as manager.Alerts) {
|
||||
for i, a := range as {
|
||||
func (s AlertManagerService) addAlerts(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||
alerts := manager.Alerts{}
|
||||
if err := parseJSON(w, r, &alerts); err != nil {
|
||||
return
|
||||
}
|
||||
for i, a := range alerts {
|
||||
if a.Summary == "" || a.Description == "" {
|
||||
glog.Errorf("Missing field in alert %d: %s", i, a)
|
||||
rb := s.ResponseBuilder()
|
||||
rb.SetResponseCode(http.StatusBadRequest)
|
||||
http.Error(w, fmt.Sprintf("Missing field in alert %d: %s", i, a), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if _, ok := a.Labels[manager.AlertNameLabel]; !ok {
|
||||
glog.Errorf("Missing alert name label in alert %d: %s", i, a)
|
||||
rb := s.ResponseBuilder()
|
||||
rb.SetResponseCode(http.StatusBadRequest)
|
||||
http.Error(w, fmt.Sprintf("Missing alert name label in alert %d: %s", i, a), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
s.Manager.Receive(as)
|
||||
s.Manager.Receive(alerts)
|
||||
}
|
||||
|
|
|
@ -14,21 +14,54 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"code.google.com/p/gorest"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/julienschmidt/httprouter"
|
||||
|
||||
"github.com/prometheus/alertmanager/manager"
|
||||
)
|
||||
|
||||
type AlertManagerService struct {
|
||||
gorest.RestService `root:"/api/" consumes:"application/json" produces:"application/json"`
|
||||
|
||||
addAlerts gorest.EndPoint `method:"POST" path:"/alerts" postdata:"Alerts"`
|
||||
addSilence gorest.EndPoint `method:"POST" path:"/silences" postdata:"Silence"`
|
||||
getSilence gorest.EndPoint `method:"GET" path:"/silences/{id:int}" output:"string"`
|
||||
updateSilence gorest.EndPoint `method:"POST" path:"/silences/{id:int}" postdata:"Silence"`
|
||||
delSilence gorest.EndPoint `method:"DELETE" path:"/silences/{id:int}"`
|
||||
silenceSummary gorest.EndPoint `method:"GET" path:"/silences" output:"string"`
|
||||
|
||||
Manager manager.AlertManager
|
||||
Silencer *manager.Silencer
|
||||
}
|
||||
|
||||
func (s AlertManagerService) Handler() http.Handler {
|
||||
r := httprouter.New()
|
||||
|
||||
r.POST("/api/alerts", s.addAlerts)
|
||||
r.GET("/api/silences", s.silenceSummary)
|
||||
r.POST("/api/silences", s.addSilence)
|
||||
r.GET("/api/silences/:id", s.getSilence)
|
||||
r.POST("/api/silences/:id", s.updateSilence)
|
||||
r.DELETE("/api/silences/:id", s.deleteSilence)
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func respondJSON(w http.ResponseWriter, v interface{}) {
|
||||
resultBytes, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprint("Error marshalling JSON: ", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-type", "application/json")
|
||||
w.Write(resultBytes)
|
||||
}
|
||||
|
||||
func getID(p httprouter.Params) int {
|
||||
n, _ := strconv.Atoi(p.ByName("id"))
|
||||
return n
|
||||
}
|
||||
|
||||
func parseJSON(w http.ResponseWriter, r *http.Request, v interface{}) error {
|
||||
d := json.NewDecoder(r.Body)
|
||||
if err := d.Decode(v); err != nil {
|
||||
http.Error(w, fmt.Sprint("failed to parse JSON: ", err.Error()), http.StatusBadRequest)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -14,80 +14,57 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"code.google.com/p/gorest"
|
||||
"github.com/golang/glog"
|
||||
//"github.com/golang/glog"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
|
||||
"github.com/prometheus/alertmanager/manager"
|
||||
)
|
||||
|
||||
type Silence struct {
|
||||
CreatedBy string
|
||||
CreatedAtSeconds int64
|
||||
EndsAtSeconds int64
|
||||
Comment string
|
||||
Filters map[string]string
|
||||
}
|
||||
|
||||
func (s AlertManagerService) AddSilence(sc manager.Silence) {
|
||||
func (s AlertManagerService) addSilence(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||
sc := manager.Silence{}
|
||||
if err := parseJSON(w, r, &sc); err != nil {
|
||||
return
|
||||
}
|
||||
// BUG: add server-side form validation.
|
||||
id := s.Silencer.AddSilence(&sc)
|
||||
|
||||
rb := s.ResponseBuilder()
|
||||
rb.SetResponseCode(http.StatusCreated)
|
||||
rb.Location(fmt.Sprintf("/api/silences/%d", id))
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
w.Header().Set("Location", fmt.Sprintf("/api/silences/%d", id))
|
||||
}
|
||||
|
||||
func (s AlertManagerService) GetSilence(id int) string {
|
||||
rb := s.ResponseBuilder()
|
||||
rb.SetContentType(gorest.Application_Json)
|
||||
silence, err := s.Silencer.GetSilence(manager.SilenceId(id))
|
||||
func (s AlertManagerService) getSilence(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||
silence, err := s.Silencer.GetSilence(manager.SilenceID(getID(p)))
|
||||
if err != nil {
|
||||
glog.Error("Error getting silence: ", err)
|
||||
rb.SetResponseCode(http.StatusNotFound)
|
||||
return err.Error()
|
||||
http.Error(w, fmt.Sprint("Error getting silence: ", err), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
resultBytes, err := json.Marshal(&silence)
|
||||
if err != nil {
|
||||
glog.Error("Error marshalling silence: ", err)
|
||||
rb.SetResponseCode(http.StatusInternalServerError)
|
||||
return err.Error()
|
||||
}
|
||||
return string(resultBytes)
|
||||
respondJSON(w, &silence)
|
||||
}
|
||||
|
||||
func (s AlertManagerService) UpdateSilence(sc manager.Silence, id int) {
|
||||
func (s AlertManagerService) updateSilence(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||
sc := manager.Silence{}
|
||||
if err := parseJSON(w, r, &sc); err != nil {
|
||||
return
|
||||
}
|
||||
// BUG: add server-side form validation.
|
||||
sc.Id = manager.SilenceId(id)
|
||||
sc.ID = manager.SilenceID(getID(p))
|
||||
if err := s.Silencer.UpdateSilence(&sc); err != nil {
|
||||
glog.Error("Error updating silence: ", err)
|
||||
rb := s.ResponseBuilder()
|
||||
rb.SetResponseCode(http.StatusNotFound)
|
||||
http.Error(w, fmt.Sprint("Error updating silence: ", err), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (s AlertManagerService) DelSilence(id int) {
|
||||
if err := s.Silencer.DelSilence(manager.SilenceId(id)); err != nil {
|
||||
glog.Error("Error deleting silence: ", err)
|
||||
rb := s.ResponseBuilder()
|
||||
rb.SetResponseCode(http.StatusNotFound)
|
||||
func (s AlertManagerService) deleteSilence(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||
if err := s.Silencer.DelSilence(manager.SilenceID(getID(p))); err != nil {
|
||||
http.Error(w, fmt.Sprint("Error deleting silence: ", err), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (s AlertManagerService) SilenceSummary() string {
|
||||
rb := s.ResponseBuilder()
|
||||
rb.SetContentType(gorest.Application_Json)
|
||||
silenceSummary := s.Silencer.SilenceSummary()
|
||||
|
||||
resultBytes, err := json.Marshal(silenceSummary)
|
||||
if err != nil {
|
||||
glog.Error("Error marshalling silences: ", err)
|
||||
rb.SetResponseCode(http.StatusInternalServerError)
|
||||
return err.Error()
|
||||
}
|
||||
return string(resultBytes)
|
||||
func (s AlertManagerService) silenceSummary(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||
respondJSON(w, s.Silencer.SilenceSummary())
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
var silenceRow = null;
|
||||
var silenceId = null;
|
||||
var silenceID = null;
|
||||
|
||||
function clearSilenceLabels() {
|
||||
$("#silence_filters_table").empty();
|
||||
|
@ -74,7 +74,7 @@ function createSilence() {
|
|||
function updateSilence() {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/api/silences/" + silenceId,
|
||||
url: "/api/silences/" + silenceID,
|
||||
data: silenceJsonFromForm(),
|
||||
dataType: "text",
|
||||
success: function(data, textStatus, jqXHR) {
|
||||
|
@ -86,22 +86,22 @@ function updateSilence() {
|
|||
});
|
||||
}
|
||||
|
||||
function getSilence(silenceId, successFn) {
|
||||
function getSilence(silenceID, successFn) {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: "/api/silences/" + silenceId,
|
||||
url: "/api/silences/" + silenceID,
|
||||
async: false,
|
||||
success: successFn,
|
||||
error: function(data, textStatus, jqXHR) {
|
||||
alert("Creating silence failed: " + textStatus);
|
||||
alert("Getting silence failed: " + textStatus);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function deleteSilence(silenceId, silenceRow) {
|
||||
function deleteSilence(silenceID, silenceRow) {
|
||||
$.ajax({
|
||||
type: "DELETE",
|
||||
url: "/api/silences/" + silenceId,
|
||||
url: "/api/silences/" + silenceID,
|
||||
success: function(data, textStatus, jqXHR) {
|
||||
silenceRow.remove();
|
||||
$("#del_silence_modal").modal("hide");
|
||||
|
@ -113,7 +113,7 @@ function deleteSilence(silenceId, silenceRow) {
|
|||
}
|
||||
|
||||
function initNewSilence() {
|
||||
silenceId = null;
|
||||
silenceID = null;
|
||||
$("#edit_silence_header, #edit_silence_btn").html("Create Silence");
|
||||
$("#edit_silence_form")[0].reset();
|
||||
}
|
||||
|
@ -162,7 +162,7 @@ function init() {
|
|||
});
|
||||
|
||||
$("#edit_silence_form").submit(function() {
|
||||
if (silenceId != null) {
|
||||
if (silenceID != null) {
|
||||
updateSilence();
|
||||
} else {
|
||||
createSilence();
|
||||
|
@ -174,9 +174,9 @@ function init() {
|
|||
$("#edit_silence_header, #edit_silence_btn").html("Update Silence");
|
||||
|
||||
silenceRow = $(this).parents("tr");
|
||||
silenceId = silenceRow.find("input[name='silence_id']").val();
|
||||
$("#edit_silence_form input[name='silence_id']").val(silenceId);
|
||||
getSilence(silenceId, function(silence) {
|
||||
silenceID = silenceRow.find("input[name='silence_id']").val();
|
||||
$("#edit_silence_form input[name='silence_id']").val(silenceID);
|
||||
getSilence(silenceID, function(silence) {
|
||||
var picker = $("#ends_at_datetimepicker").data('datetimepicker');
|
||||
var endsAt = new Date(silence.EndsAtSeconds * 1000);
|
||||
picker.setLocalDate(endsAt);
|
||||
|
@ -194,12 +194,12 @@ function init() {
|
|||
// from the modal dialog to remove that silence.
|
||||
$(".del_silence_modal_btn").click(function() {
|
||||
silenceRow = $(this).parents("tr");
|
||||
silenceId = silenceRow.find("input[name='silence_id']").val();
|
||||
silenceID = silenceRow.find("input[name='silence_id']").val();
|
||||
});
|
||||
|
||||
// Deletion confirmation button action.
|
||||
$(".del_silence_btn").click(function() {
|
||||
deleteSilence(silenceId, silenceRow);
|
||||
deleteSilence(silenceID, silenceRow);
|
||||
});
|
||||
|
||||
$(".silence_link").click(function() {
|
||||
|
|
|
@ -46,12 +46,12 @@
|
|||
</td>
|
||||
<td>{{timeSince .Created}} ago</td>
|
||||
<td>{{timeSince .LastRefreshed}} ago</td>
|
||||
<td><a href="{{.Alert.Payload.GeneratorUrl}}">{{(truncate .Alert.Payload.GeneratorUrl 40)}}</a></td>
|
||||
<td><a href="{{.Alert.Payload.GeneratorURL}}">{{(truncate .Alert.Payload.GeneratorURL 40)}}</a></td>
|
||||
<td>{{.Alert.Payload.AlertingRule}}</td>
|
||||
<td>
|
||||
{{$silence := call $silenceForAlert .Alert}}
|
||||
{{if $silence}}
|
||||
by <a href="#" class="silence_link">silence {{$silence.Id}}</a>
|
||||
by <a href="#" class="silence_link">silence {{$silence.ID}}</a>
|
||||
{{else}}
|
||||
not silenced
|
||||
{{end}}
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<tbody>
|
||||
{{range .Silences}}
|
||||
<tr>
|
||||
<td>{{.Id}}</td>
|
||||
<td>{{.ID}}</td>
|
||||
<td>
|
||||
{{range .Filters}}
|
||||
<span class="label label-info">{{.NamePattern}}="{{.ValuePattern}}"</span>
|
||||
|
@ -33,7 +33,7 @@
|
|||
<td>{{.EndsAt}}</td>
|
||||
<td>{{.Comment}}</td>
|
||||
<td>
|
||||
<input type="hidden" name="silence_id" value="{{.Id}}">
|
||||
<input type="hidden" name="silence_id" value="{{.ID}}">
|
||||
|
||||
<a href="#edit_silence_modal" role="button" class="btn btn-mini btn-primary edit_silence_btn" id="new_silence_btn" data-toggle="modal">Edit Silence</a>
|
||||
<a href="#del_silence_modal" role="button" class="btn btn-mini btn-danger del_silence_modal_btn" data-toggle="modal">Remove Silence</a>
|
||||
|
|
32
web/web.go
32
web/web.go
|
@ -18,12 +18,10 @@ import (
|
|||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"net/http/pprof"
|
||||
_ "net/http/pprof"
|
||||
|
||||
"code.google.com/p/gorest"
|
||||
"github.com/golang/glog"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/exp"
|
||||
|
||||
"github.com/prometheus/alertmanager/web/api"
|
||||
"github.com/prometheus/alertmanager/web/blob"
|
||||
|
@ -43,35 +41,27 @@ type WebService struct {
|
|||
}
|
||||
|
||||
func (w WebService) ServeForever() error {
|
||||
gorest.RegisterService(w.AlertManagerService)
|
||||
|
||||
exp.Handle("/favicon.ico", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
http.Handle("/favicon.ico", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "", 404)
|
||||
}))
|
||||
|
||||
// TODO(julius): This will need to be rewritten once the exp package provides
|
||||
// the coarse mux behaviors via a wrapper function.
|
||||
exp.Handle("/debug/pprof/", http.HandlerFunc(pprof.Index))
|
||||
exp.Handle("/debug/pprof/cmdline", http.HandlerFunc(pprof.Cmdline))
|
||||
exp.Handle("/debug/pprof/profile", http.HandlerFunc(pprof.Profile))
|
||||
exp.Handle("/debug/pprof/symbol", http.HandlerFunc(pprof.Symbol))
|
||||
http.Handle("/", prometheus.InstrumentHandler("index", w.AlertsHandler))
|
||||
http.Handle("/alerts", prometheus.InstrumentHandler("alerts", w.AlertsHandler))
|
||||
http.Handle("/silences", prometheus.InstrumentHandler("silences", w.SilencesHandler))
|
||||
http.Handle("/status", prometheus.InstrumentHandler("status", w.StatusHandler))
|
||||
|
||||
exp.Handle("/", w.AlertsHandler)
|
||||
exp.Handle("/alerts", w.AlertsHandler)
|
||||
exp.Handle("/silences", w.SilencesHandler)
|
||||
exp.Handle("/status", w.StatusHandler)
|
||||
|
||||
exp.Handle("/api/", compressionHandler{handler: gorest.Handle()})
|
||||
exp.Handle("/metrics", prometheus.DefaultHandler)
|
||||
http.Handle("/metrics", prometheus.Handler())
|
||||
if *useLocalAssets {
|
||||
exp.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("web/static"))))
|
||||
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("web/static"))))
|
||||
} else {
|
||||
exp.Handle("/static/", http.StripPrefix("/static/", new(blob.Handler)))
|
||||
http.Handle("/static/", http.StripPrefix("/static/", new(blob.Handler)))
|
||||
}
|
||||
http.Handle("/api/", w.AlertManagerService.Handler())
|
||||
|
||||
glog.Info("listening on ", *listenAddress)
|
||||
|
||||
return http.ListenAndServe(*listenAddress, exp.DefaultCoarseMux)
|
||||
return http.ListenAndServe(*listenAddress, nil)
|
||||
}
|
||||
|
||||
func getLocalTemplate(name string) (*template.Template, error) {
|
||||
|
|
Loading…
Reference in New Issue