From b63047a4027157bc525194fbc97f904895ebbc6e Mon Sep 17 00:00:00 2001 From: Chris Goller Date: Sat, 19 Nov 2016 11:41:06 -0600 Subject: [PATCH] Add server error logging --- server/exploration.go | 36 +++++++------- server/kapacitors.go | 106 +++++++++++++++++++++--------------------- server/layout.go | 20 ++++---- server/mappings.go | 2 +- server/mux.go | 33 ++++++------- server/proxy.go | 24 +++++----- server/server.go | 2 + server/service.go | 6 +++ server/sources.go | 26 +++++------ 9 files changed, 132 insertions(+), 123 deletions(-) diff --git a/server/exploration.go b/server/exploration.go index 23252106c..b04ce618f 100644 --- a/server/exploration.go +++ b/server/exploration.go @@ -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) diff --git a/server/kapacitors.go b/server/kapacitors.go index a62e627d4..cb97152eb 100644 --- a/server/kapacitors.go +++ b/server/kapacitors.go @@ -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 } diff --git a/server/layout.go b/server/layout.go index c9b38f1aa..e600c288e 100644 --- a/server/layout.go +++ b/server/layout.go @@ -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 } diff --git a/server/mappings.go b/server/mappings.go index 2917cc651..e26b63013 100644 --- a/server/mappings.go +++ b/server/mappings.go @@ -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 } diff --git a/server/mux.go b/server/mux.go index fbf6affc2..53acb8edc 100644 --- a/server/mux.go +++ b/server/mux.go @@ -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) { diff --git a/server/proxy.go b/server/proxy.go index ab12279fe..10f0052ed 100644 --- a/server/proxy.go +++ b/server/proxy.go @@ -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 } diff --git a/server/server.go b/server/server.go index b5d76d54b..a1a42f07b 100644 --- a/server/server.go +++ b/server/server.go @@ -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, } } diff --git a/server/service.go b/server/service.go index 198b342a7..1e640f0e4 100644 --- a/server/service.go +++ b/server/service.go @@ -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"` +} diff --git a/server/sources.go b/server/sources.go index c7c42fb12..2ba2d29e5 100644 --- a/server/sources.go +++ b/server/sources.go @@ -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)