Merge pull request #590 from influxdata/cpg-add-error-logging

Add server error logging
pull/594/head
Chris Goller 2016-11-19 11:54:42 -06:00 committed by GitHub
commit 76bf76e362
9 changed files with 132 additions and 123 deletions

View File

@ -45,14 +45,14 @@ type explorations struct {
func (h *Service) Explorations(w http.ResponseWriter, r *http.Request) {
id, err := paramID("id", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
ctx := r.Context()
mrExs, err := h.ExplorationStore.Query(ctx, chronograf.UserID(id))
if err != nil {
unknownErrorWithMessage(w, err)
unknownErrorWithMessage(w, err, h.Logger)
return
}
@ -71,20 +71,20 @@ func (h *Service) Explorations(w http.ResponseWriter, r *http.Request) {
func (h *Service) ExplorationsID(w http.ResponseWriter, r *http.Request) {
eID, err := paramID("eid", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
uID, err := paramID("id", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
ctx := r.Context()
e, err := h.ExplorationStore.Get(ctx, chronograf.ExplorationID(eID))
if err != nil || e.UserID != chronograf.UserID(uID) {
notFound(w, eID)
notFound(w, eID, h.Logger)
return
}
@ -101,26 +101,26 @@ type patchExplorationRequest struct {
func (h *Service) UpdateExploration(w http.ResponseWriter, r *http.Request) {
id, err := paramID("eid", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
uID, err := paramID("id", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
ctx := r.Context()
e, err := h.ExplorationStore.Get(ctx, chronograf.ExplorationID(id))
if err != nil || e.UserID != chronograf.UserID(uID) {
notFound(w, id)
notFound(w, id, h.Logger)
return
}
var req patchExplorationRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
invalidJSON(w)
invalidJSON(w, h.Logger)
return
}
@ -128,7 +128,7 @@ func (h *Service) UpdateExploration(w http.ResponseWriter, r *http.Request) {
var ok bool
if e.Data, ok = req.Data.(string); !ok {
err := fmt.Errorf("Error: Exploration data is not a string")
invalidData(w, err)
invalidData(w, err, h.Logger)
return
}
}
@ -139,7 +139,7 @@ func (h *Service) UpdateExploration(w http.ResponseWriter, r *http.Request) {
if err := h.ExplorationStore.Update(ctx, e); err != nil {
msg := "Error: Failed to update Exploration"
Error(w, http.StatusInternalServerError, msg)
Error(w, http.StatusInternalServerError, msg, h.Logger)
return
}
@ -156,14 +156,14 @@ type postExplorationRequest struct {
func (h *Service) NewExploration(w http.ResponseWriter, r *http.Request) {
uID, err := paramID("id", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
// TODO: Check user if user exists.
var req postExplorationRequest
if err = json.NewDecoder(r.Body).Decode(&req); err != nil {
invalidJSON(w)
invalidJSON(w, h.Logger)
return
}
@ -182,7 +182,7 @@ func (h *Service) NewExploration(w http.ResponseWriter, r *http.Request) {
e, err = h.ExplorationStore.Add(ctx, e)
if err != nil {
msg := fmt.Errorf("Error: Failed to save Exploration")
unknownErrorWithMessage(w, msg)
unknownErrorWithMessage(w, msg, h.Logger)
return
}
@ -195,25 +195,25 @@ func (h *Service) NewExploration(w http.ResponseWriter, r *http.Request) {
func (h *Service) RemoveExploration(w http.ResponseWriter, r *http.Request) {
eID, err := paramID("eid", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
uID, err := paramID("id", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
ctx := r.Context()
e, err := h.ExplorationStore.Get(ctx, chronograf.ExplorationID(eID))
if err != nil || e.UserID != chronograf.UserID(uID) {
notFound(w, eID)
notFound(w, eID, h.Logger)
return
}
if err := h.ExplorationStore.Delete(ctx, &chronograf.Exploration{ID: chronograf.ExplorationID(eID)}); err != nil {
unknownErrorWithMessage(w, err)
unknownErrorWithMessage(w, err, h.Logger)
return
}
w.WriteHeader(http.StatusNoContent)

View File

@ -55,24 +55,24 @@ type kapacitor struct {
func (h *Service) NewKapacitor(w http.ResponseWriter, r *http.Request) {
srcID, err := paramID("id", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
ctx := r.Context()
_, err = h.SourcesStore.Get(ctx, srcID)
if err != nil {
notFound(w, srcID)
notFound(w, srcID, h.Logger)
return
}
var req postKapacitorRequest
if err = json.NewDecoder(r.Body).Decode(&req); err != nil {
invalidJSON(w)
invalidJSON(w, h.Logger)
return
}
if err := req.Valid(); err != nil {
invalidData(w, err)
invalidData(w, err, h.Logger)
return
}
@ -86,7 +86,7 @@ func (h *Service) NewKapacitor(w http.ResponseWriter, r *http.Request) {
if srv, err = h.ServersStore.Add(ctx, srv); err != nil {
msg := fmt.Errorf("Error storing kapacitor %v: %v", req, err)
unknownErrorWithMessage(w, msg)
unknownErrorWithMessage(w, msg, h.Logger)
return
}
@ -120,7 +120,7 @@ func (h *Service) Kapacitors(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
mrSrvs, err := h.ServersStore.All(ctx)
if err != nil {
Error(w, http.StatusInternalServerError, "Error loading kapacitors")
Error(w, http.StatusInternalServerError, "Error loading kapacitors", h.Logger)
return
}
@ -140,20 +140,20 @@ func (h *Service) Kapacitors(w http.ResponseWriter, r *http.Request) {
func (h *Service) KapacitorsID(w http.ResponseWriter, r *http.Request) {
id, err := paramID("kid", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
srcID, err := paramID("id", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
ctx := r.Context()
srv, err := h.ServersStore.Get(ctx, id)
if err != nil || srv.SrcID != srcID {
notFound(w, id)
notFound(w, id, h.Logger)
return
}
@ -165,25 +165,25 @@ func (h *Service) KapacitorsID(w http.ResponseWriter, r *http.Request) {
func (h *Service) RemoveKapacitor(w http.ResponseWriter, r *http.Request) {
id, err := paramID("kid", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
srcID, err := paramID("id", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
ctx := r.Context()
srv, err := h.ServersStore.Get(ctx, id)
if err != nil || srv.SrcID != srcID {
notFound(w, id)
notFound(w, id, h.Logger)
return
}
if err = h.ServersStore.Delete(ctx, srv); err != nil {
unknownErrorWithMessage(w, err)
unknownErrorWithMessage(w, err, h.Logger)
return
}
w.WriteHeader(http.StatusNoContent)
@ -213,31 +213,31 @@ func (p *patchKapacitorRequest) Valid() error {
func (h *Service) UpdateKapacitor(w http.ResponseWriter, r *http.Request) {
id, err := paramID("kid", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
srcID, err := paramID("id", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
ctx := r.Context()
srv, err := h.ServersStore.Get(ctx, id)
if err != nil || srv.SrcID != srcID {
notFound(w, id)
notFound(w, id, h.Logger)
return
}
var req patchKapacitorRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
invalidJSON(w)
invalidJSON(w, h.Logger)
return
}
if err := req.Valid(); err != nil {
invalidData(w, err)
invalidData(w, err, h.Logger)
return
}
@ -256,7 +256,7 @@ func (h *Service) UpdateKapacitor(w http.ResponseWriter, r *http.Request) {
if err := h.ServersStore.Update(ctx, srv); err != nil {
msg := fmt.Sprintf("Error updating kapacitor ID %d", id)
Error(w, http.StatusInternalServerError, msg)
Error(w, http.StatusInternalServerError, msg, h.Logger)
return
}
@ -268,20 +268,20 @@ func (h *Service) UpdateKapacitor(w http.ResponseWriter, r *http.Request) {
func (h *Service) KapacitorRulesPost(w http.ResponseWriter, r *http.Request) {
id, err := paramID("kid", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
srcID, err := paramID("id", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
ctx := r.Context()
srv, err := h.ServersStore.Get(ctx, id)
if err != nil || srv.SrcID != srcID {
notFound(w, id)
notFound(w, id, h.Logger)
return
}
@ -295,7 +295,7 @@ func (h *Service) KapacitorRulesPost(w http.ResponseWriter, r *http.Request) {
var req chronograf.AlertRule
if err = json.NewDecoder(r.Body).Decode(&req); err != nil {
invalidJSON(w)
invalidJSON(w, h.Logger)
return
}
// TODO: validate this data
@ -308,13 +308,13 @@ func (h *Service) KapacitorRulesPost(w http.ResponseWriter, r *http.Request) {
task, err := c.Create(ctx, req)
if err != nil {
Error(w, http.StatusInternalServerError, err.Error())
Error(w, http.StatusInternalServerError, err.Error(), h.Logger)
return
}
req.ID = task.ID
rule, err := h.AlertRulesStore.Add(ctx, srcID, id, req)
if err != nil {
Error(w, http.StatusInternalServerError, err.Error())
Error(w, http.StatusInternalServerError, err.Error(), h.Logger)
return
}
@ -348,20 +348,20 @@ type alertResponse struct {
func (h *Service) KapacitorRulesPut(w http.ResponseWriter, r *http.Request) {
id, err := paramID("kid", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
srcID, err := paramID("id", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
ctx := r.Context()
srv, err := h.ServersStore.Get(ctx, id)
if err != nil || srv.SrcID != srcID {
notFound(w, id)
notFound(w, id, h.Logger)
return
}
@ -374,7 +374,7 @@ func (h *Service) KapacitorRulesPut(w http.ResponseWriter, r *http.Request) {
}
var req chronograf.AlertRule
if err = json.NewDecoder(r.Body).Decode(&req); err != nil {
invalidJSON(w)
invalidJSON(w, h.Logger)
return
}
// TODO: validate this data
@ -388,22 +388,22 @@ func (h *Service) KapacitorRulesPut(w http.ResponseWriter, r *http.Request) {
// Check if the rule exists and is scoped correctly
if _, err := h.AlertRulesStore.Get(ctx, srcID, id, tid); err != nil {
if err == chronograf.ErrAlertNotFound {
notFound(w, id)
notFound(w, id, h.Logger)
return
}
Error(w, http.StatusInternalServerError, err.Error())
Error(w, http.StatusInternalServerError, err.Error(), h.Logger)
return
}
req.ID = tid
task, err := c.Update(ctx, c.Href(tid), req)
if err != nil {
Error(w, http.StatusInternalServerError, err.Error())
Error(w, http.StatusInternalServerError, err.Error(), h.Logger)
return
}
if err := h.AlertRulesStore.Update(ctx, srcID, id, req); err != nil {
Error(w, http.StatusInternalServerError, err.Error())
Error(w, http.StatusInternalServerError, err.Error(), h.Logger)
return
}
@ -423,26 +423,26 @@ func (h *Service) KapacitorRulesPut(w http.ResponseWriter, r *http.Request) {
func (h *Service) KapacitorRulesGet(w http.ResponseWriter, r *http.Request) {
id, err := paramID("kid", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
srcID, err := paramID("id", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
ctx := r.Context()
srv, err := h.ServersStore.Get(ctx, id)
if err != nil || srv.SrcID != srcID {
notFound(w, id)
notFound(w, id, h.Logger)
return
}
rules, err := h.AlertRulesStore.All(ctx, srcID, id)
if err != nil {
Error(w, http.StatusInternalServerError, err.Error())
Error(w, http.StatusInternalServerError, err.Error(), h.Logger)
return
}
@ -454,7 +454,7 @@ func (h *Service) KapacitorRulesGet(w http.ResponseWriter, r *http.Request) {
for _, rule := range rules {
tickscript, err := ticker.Generate(rule)
if err != nil {
Error(w, http.StatusInternalServerError, err.Error())
Error(w, http.StatusInternalServerError, err.Error(), h.Logger)
return
}
@ -476,24 +476,24 @@ type allAlertsResponse struct {
Rules []alertResponse `json:"rules"`
}
// KapacitorRulesGet retrieves specific task
// KapacitorRulesID retrieves specific task
func (h *Service) KapacitorRulesID(w http.ResponseWriter, r *http.Request) {
id, err := paramID("kid", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
srcID, err := paramID("id", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
ctx := r.Context()
srv, err := h.ServersStore.Get(ctx, id)
if err != nil || srv.SrcID != srcID {
notFound(w, id)
notFound(w, id, h.Logger)
return
}
tid := httprouter.GetParamFromContext(ctx, "tid")
@ -501,10 +501,10 @@ func (h *Service) KapacitorRulesID(w http.ResponseWriter, r *http.Request) {
rule, err := h.AlertRulesStore.Get(ctx, srcID, id, tid)
if err != nil {
if err == chronograf.ErrAlertNotFound {
notFound(w, id)
notFound(w, id, h.Logger)
return
}
Error(w, http.StatusInternalServerError, err.Error())
Error(w, http.StatusInternalServerError, err.Error(), h.Logger)
return
}
@ -512,7 +512,7 @@ func (h *Service) KapacitorRulesID(w http.ResponseWriter, r *http.Request) {
c := kapa.Client{}
tickscript, err := ticker.Generate(rule)
if err != nil {
Error(w, http.StatusInternalServerError, err.Error())
Error(w, http.StatusInternalServerError, err.Error(), h.Logger)
return
}
@ -528,24 +528,24 @@ func (h *Service) KapacitorRulesID(w http.ResponseWriter, r *http.Request) {
encodeJSON(w, http.StatusOK, res, h.Logger)
}
// KapacitosRulesDelete proxies DELETE to kapacitor
// KapacitorRulesDelete proxies DELETE to kapacitor
func (h *Service) KapacitorRulesDelete(w http.ResponseWriter, r *http.Request) {
id, err := paramID("kid", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
srcID, err := paramID("id", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
ctx := r.Context()
srv, err := h.ServersStore.Get(ctx, id)
if err != nil || srv.SrcID != srcID {
notFound(w, id)
notFound(w, id, h.Logger)
return
}
@ -554,10 +554,10 @@ func (h *Service) KapacitorRulesDelete(w http.ResponseWriter, r *http.Request) {
// Check if the rule is linked to this server and kapacitor
if _, err := h.AlertRulesStore.Get(ctx, srcID, id, tid); err != nil {
if err == chronograf.ErrAlertNotFound {
notFound(w, id)
notFound(w, id, h.Logger)
return
}
Error(w, http.StatusInternalServerError, err.Error())
Error(w, http.StatusInternalServerError, err.Error(), h.Logger)
return
}
@ -567,12 +567,12 @@ func (h *Service) KapacitorRulesDelete(w http.ResponseWriter, r *http.Request) {
Password: srv.Password,
}
if err := c.Delete(ctx, c.Href(tid)); err != nil {
Error(w, http.StatusInternalServerError, err.Error())
Error(w, http.StatusInternalServerError, err.Error(), h.Logger)
return
}
if err := h.AlertRulesStore.Delete(ctx, srcID, id, chronograf.AlertRule{ID: tid}); err != nil {
Error(w, http.StatusInternalServerError, err.Error())
Error(w, http.StatusInternalServerError, err.Error(), h.Logger)
return
}

View File

@ -32,19 +32,19 @@ func newLayoutResponse(layout chronograf.Layout) layoutResponse {
func (h *Service) NewLayout(w http.ResponseWriter, r *http.Request) {
var layout chronograf.Layout
if err := json.NewDecoder(r.Body).Decode(&layout); err != nil {
invalidJSON(w)
invalidJSON(w, h.Logger)
return
}
if err := ValidLayoutRequest(layout); err != nil {
invalidData(w, err)
invalidData(w, err, h.Logger)
return
}
var err error
if layout, err = h.LayoutStore.Add(r.Context(), layout); err != nil {
msg := fmt.Errorf("Error storing layout %v: %v", layout, err)
unknownErrorWithMessage(w, msg)
unknownErrorWithMessage(w, msg, h.Logger)
return
}
@ -72,7 +72,7 @@ func (h *Service) Layouts(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
layouts, err := h.LayoutStore.All(ctx)
if err != nil {
Error(w, http.StatusInternalServerError, "Error loading layouts")
Error(w, http.StatusInternalServerError, "Error loading layouts", h.Logger)
return
}
@ -104,7 +104,7 @@ func (h *Service) LayoutsID(w http.ResponseWriter, r *http.Request) {
layout, err := h.LayoutStore.Get(ctx, id)
if err != nil {
Error(w, http.StatusNotFound, fmt.Sprintf("ID %s not found", id))
Error(w, http.StatusNotFound, fmt.Sprintf("ID %s not found", id), h.Logger)
return
}
@ -122,7 +122,7 @@ func (h *Service) RemoveLayout(w http.ResponseWriter, r *http.Request) {
}
if err := h.LayoutStore.Delete(ctx, layout); err != nil {
unknownErrorWithMessage(w, err)
unknownErrorWithMessage(w, err, h.Logger)
return
}
@ -136,25 +136,25 @@ func (h *Service) UpdateLayout(w http.ResponseWriter, r *http.Request) {
_, err := h.LayoutStore.Get(ctx, id)
if err != nil {
Error(w, http.StatusNotFound, fmt.Sprintf("ID %s not found", id))
Error(w, http.StatusNotFound, fmt.Sprintf("ID %s not found", id), h.Logger)
return
}
var req chronograf.Layout
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
invalidJSON(w)
invalidJSON(w, h.Logger)
return
}
req.ID = id
if err := ValidLayoutRequest(req); err != nil {
invalidData(w, err)
invalidData(w, err, h.Logger)
return
}
if err := h.LayoutStore.Update(ctx, req); err != nil {
msg := fmt.Sprintf("Error updating layout ID %s: %v", id, err)
Error(w, http.StatusInternalServerError, msg)
Error(w, http.StatusInternalServerError, msg, h.Logger)
return
}

View File

@ -16,7 +16,7 @@ func (h *Service) GetMappings(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
layouts, err := h.LayoutStore.All(ctx)
if err != nil {
Error(w, http.StatusInternalServerError, "Error loading layouts")
Error(w, http.StatusInternalServerError, "Error loading layouts", h.Logger)
return
}

View File

@ -8,7 +8,7 @@ import (
"strings"
"github.com/bouk/httprouter"
"github.com/influxdata/chronograf" // When julienschmidt/httprouter v2 w/ context is out, switch "github.com/influxdata/chronograf
"github.com/influxdata/chronograf" // When julienschmidt/httprouter v2 w/ context is out, switch
"github.com/influxdata/chronograf/jwt"
)
@ -152,44 +152,45 @@ func encodeJSON(w http.ResponseWriter, status int, v interface{}, logger chronog
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
if err := json.NewEncoder(w).Encode(v); err != nil {
unknownErrorWithMessage(w, err)
unknownErrorWithMessage(w, err, logger)
}
}
// Error writes an JSON message
func Error(w http.ResponseWriter, code int, msg string) {
e := struct {
Code int `json:"code"`
Message string `json:"message"`
}{
func Error(w http.ResponseWriter, code int, msg string, logger chronograf.Logger) {
e := ErrorMessage{
Code: code,
Message: msg,
}
b, err := json.Marshal(e)
if err != nil {
//log.Print("go-oidc: failed to marshal %#v: %v", e, err)
code = http.StatusInternalServerError
b = []byte(`{"code": 500, "message":"server_error"}`)
}
logger.
WithField("component", "server").
WithField("http_status ", code).
Error("Error message ", msg)
w.Header().Set("Content-Type", JSONType)
w.WriteHeader(code)
w.Write(b)
}
func invalidData(w http.ResponseWriter, err error) {
Error(w, http.StatusUnprocessableEntity, fmt.Sprintf("%v", err))
func invalidData(w http.ResponseWriter, err error, logger chronograf.Logger) {
Error(w, http.StatusUnprocessableEntity, fmt.Sprintf("%v", err), logger)
}
func invalidJSON(w http.ResponseWriter) {
Error(w, http.StatusBadRequest, "Unparsable JSON")
func invalidJSON(w http.ResponseWriter, logger chronograf.Logger) {
Error(w, http.StatusBadRequest, "Unparsable JSON", logger)
}
func unknownErrorWithMessage(w http.ResponseWriter, err error) {
Error(w, http.StatusInternalServerError, fmt.Sprintf("Unknown error: %v", err))
func unknownErrorWithMessage(w http.ResponseWriter, err error, logger chronograf.Logger) {
Error(w, http.StatusInternalServerError, fmt.Sprintf("Unknown error: %v", err), logger)
}
func notFound(w http.ResponseWriter, id int) {
Error(w, http.StatusNotFound, fmt.Sprintf("ID %d not found", id))
func notFound(w http.ResponseWriter, id int, logger chronograf.Logger) {
Error(w, http.StatusNotFound, fmt.Sprintf("ID %d not found", id), logger)
}
func paramID(key string, r *http.Request) (int, error) {

View File

@ -26,30 +26,30 @@ type postProxyResponse struct {
func (h *Service) Proxy(w http.ResponseWriter, r *http.Request) {
id, err := paramID("id", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
var req chronograf.Query
if err = json.NewDecoder(r.Body).Decode(&req); err != nil {
invalidJSON(w)
invalidJSON(w, h.Logger)
return
}
if err = ValidProxyRequest(req); err != nil {
invalidData(w, err)
invalidData(w, err, h.Logger)
return
}
ctx := r.Context()
src, err := h.SourcesStore.Get(ctx, id)
if err != nil {
notFound(w, id)
notFound(w, id, h.Logger)
return
}
if err = h.TimeSeries.Connect(ctx, &src); err != nil {
msg := fmt.Sprintf("Unable to connect to source %d", id)
Error(w, http.StatusBadRequest, msg)
Error(w, http.StatusBadRequest, msg, h.Logger)
return
}
@ -57,11 +57,11 @@ func (h *Service) Proxy(w http.ResponseWriter, r *http.Request) {
if err != nil {
if err == chronograf.ErrUpstreamTimeout {
msg := "Timeout waiting for Influx response"
Error(w, http.StatusRequestTimeout, msg)
Error(w, http.StatusRequestTimeout, msg, h.Logger)
return
}
// TODO: Here I want to return the error code from influx.
Error(w, http.StatusBadRequest, err.Error())
Error(w, http.StatusBadRequest, err.Error(), h.Logger)
return
}
@ -75,33 +75,33 @@ func (h *Service) Proxy(w http.ResponseWriter, r *http.Request) {
func (h *Service) KapacitorProxy(w http.ResponseWriter, r *http.Request) {
srcID, err := paramID("id", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
id, err := paramID("kid", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
path := r.URL.Query().Get("path")
if path == "" {
Error(w, http.StatusUnprocessableEntity, "path query parameter required")
Error(w, http.StatusUnprocessableEntity, "path query parameter required", h.Logger)
return
}
ctx := r.Context()
srv, err := h.ServersStore.Get(ctx, id)
if err != nil || srv.SrcID != srcID {
notFound(w, id)
notFound(w, id, h.Logger)
return
}
u, err := url.Parse(srv.URL)
if err != nil {
msg := fmt.Sprintf("Error parsing kapacitor url: %v", err)
Error(w, http.StatusUnprocessableEntity, msg)
Error(w, http.StatusUnprocessableEntity, msg, h.Logger)
return
}

View File

@ -47,6 +47,7 @@ type Server struct {
handler http.Handler
}
// BuildInfo is sent to the usage client to track versions and commits
type BuildInfo struct {
Version string
Commit string
@ -141,6 +142,7 @@ func openService(boltPath, cannedPath string, logger chronograf.Logger) Service
},
LayoutStore: layouts,
AlertRulesStore: db.AlertsStore,
Logger: logger,
}
}

View File

@ -12,3 +12,9 @@ type Service struct {
TimeSeries chronograf.TimeSeries
Logger chronograf.Logger
}
// ErrorMessage is the error response format for all service errors
type ErrorMessage struct {
Code int `json:"code"`
Message string `json:"message"`
}

View File

@ -41,12 +41,12 @@ func newSourceResponse(src chronograf.Source) sourceResponse {
func (h *Service) NewSource(w http.ResponseWriter, r *http.Request) {
var src chronograf.Source
if err := json.NewDecoder(r.Body).Decode(&src); err != nil {
invalidJSON(w)
invalidJSON(w, h.Logger)
return
}
if err := ValidSourceRequest(src); err != nil {
invalidData(w, err)
invalidData(w, err, h.Logger)
return
}
@ -58,7 +58,7 @@ func (h *Service) NewSource(w http.ResponseWriter, r *http.Request) {
var err error
if src, err = h.SourcesStore.Add(r.Context(), src); err != nil {
msg := fmt.Errorf("Error storing source %v: %v", src, err)
unknownErrorWithMessage(w, msg)
unknownErrorWithMessage(w, msg, h.Logger)
return
}
@ -76,7 +76,7 @@ func (h *Service) Sources(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
srcs, err := h.SourcesStore.All(ctx)
if err != nil {
Error(w, http.StatusInternalServerError, "Error loading sources")
Error(w, http.StatusInternalServerError, "Error loading sources", h.Logger)
return
}
@ -95,14 +95,14 @@ func (h *Service) Sources(w http.ResponseWriter, r *http.Request) {
func (h *Service) SourcesID(w http.ResponseWriter, r *http.Request) {
id, err := paramID("id", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
ctx := r.Context()
src, err := h.SourcesStore.Get(ctx, id)
if err != nil {
notFound(w, id)
notFound(w, id, h.Logger)
return
}
@ -114,14 +114,14 @@ func (h *Service) SourcesID(w http.ResponseWriter, r *http.Request) {
func (h *Service) RemoveSource(w http.ResponseWriter, r *http.Request) {
id, err := paramID("id", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
src := chronograf.Source{ID: id}
ctx := r.Context()
if err = h.SourcesStore.Delete(ctx, src); err != nil {
unknownErrorWithMessage(w, err)
unknownErrorWithMessage(w, err, h.Logger)
return
}
@ -132,20 +132,20 @@ func (h *Service) RemoveSource(w http.ResponseWriter, r *http.Request) {
func (h *Service) UpdateSource(w http.ResponseWriter, r *http.Request) {
id, err := paramID("id", r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, err.Error())
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
return
}
ctx := r.Context()
src, err := h.SourcesStore.Get(ctx, id)
if err != nil {
notFound(w, id)
notFound(w, id, h.Logger)
return
}
var req chronograf.Source
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
invalidJSON(w)
invalidJSON(w, h.Logger)
return
}
@ -170,13 +170,13 @@ func (h *Service) UpdateSource(w http.ResponseWriter, r *http.Request) {
}
if err := ValidSourceRequest(src); err != nil {
invalidData(w, err)
invalidData(w, err, h.Logger)
return
}
if err := h.SourcesStore.Update(ctx, src); err != nil {
msg := fmt.Sprintf("Error updating source ID %d", id)
Error(w, http.StatusInternalServerError, msg)
Error(w, http.StatusInternalServerError, msg, h.Logger)
return
}
encodeJSON(w, http.StatusOK, newSourceResponse(src), h.Logger)