func api(at string, handler ApiHandlerFunc) http.HandlerFunc { return func(rw http.ResponseWriter, r *http.Request) { start := time.Now() if !passwordCheck(r) { rw.Header().Set("WWW-Authenticate", `Basic realm="Convox System"`) rw.WriteHeader(401) rw.Write([]byte("invalid authorization")) return } if !versionCheck(r) { rw.WriteHeader(403) rw.Write([]byte("client outdated, please update with `convox update`")) return } err := handler(rw, r) if err != nil { rw.WriteHeader(err.Code()) RenderError(rw, err) logError(at, err) return } log.WithFields(log.Fields{ "ns": "kernel", "at": at, "state": "success", "measure#handler.elapsed": fmt.Sprintf("%0.3fms", float64(time.Now().Sub(start).Nanoseconds())/1000000), }).Info() } }
func logError(at string, err *httperr.Error) { l := log.WithFields(log.Fields{ "ns": "kernel", "at": at, "state": "error", }) if err.User() { l.WithField("count#error.user", 1).Warn(err.Error()) return } err.Save() id := rand.Int31() l.WithFields(log.Fields{ "id": id, "count#error": 1, }).Warn(err.Error()) for i, t := range err.Trace() { l.WithFields(log.Fields{ "id": id, "line": i, }).Warn(t) } }
func ws(at string, handler ApiWebsocketFunc) websocket.Handler { return websocket.Handler(func(ws *websocket.Conn) { start := time.Now() if !passwordCheck(ws.Request()) { ws.Write([]byte("ERROR: invalid authorization\n")) return } if !versionCheck(ws.Request()) { ws.Write([]byte("client outdated, please update with `convox update`\n")) return } err := handler(ws) if err != nil { ws.Write([]byte(fmt.Sprintf("ERROR: %v\n", err))) logError(at, err) return } log.WithFields(log.Fields{ "ns": "kernel", "at": at, "state": "success", "measure#websocket.handler.elapsed": fmt.Sprintf("%0.3fms", float64(time.Now().Sub(start).Nanoseconds())/1000000), }).Info() }) }
func TrackEvent(event string, params map[string]interface{}) { log := logrus.WithFields(logrus.Fields{"ns": "api.helpers", "at": "TrackEvent"}) if params == nil { params = map[string]interface{}{} } params["client_id"] = os.Getenv("CLIENT_ID") userId := RackId() log.WithFields(logrus.Fields{"event": event, "user_id": userId}).WithFields(logrus.Fields(params)).Info() segment.Track(&analytics.Track{ Event: event, UserId: userId, Properties: params, }) }
func TestLogstashFormatter(t *testing.T) { assert := assert.New(t) lf := LogstashFormatter{Type: "abc"} fields := logrus.Fields{ "message": "def", "level": "ijk", "type": "lmn", "one": 1, "pi": 3.14, "bool": true, } entry := logrus.WithFields(fields) entry.Message = "msg" entry.Level = logrus.InfoLevel b, _ := lf.Format(entry) var data map[string]interface{} dec := json.NewDecoder(bytes.NewReader(b)) dec.UseNumber() dec.Decode(&data) // base fields assert.Equal(json.Number("1"), data["@version"]) assert.NotEmpty(data["@timestamp"]) assert.Equal("abc", data["type"]) assert.Equal("msg", data["message"]) assert.Equal("info", data["level"]) // substituted fields assert.Equal("def", data["fields.message"]) assert.Equal("ijk", data["fields.level"]) assert.Equal("lmn", data["fields.type"]) // formats assert.Equal(json.Number("1"), data["one"]) assert.Equal(json.Number("3.14"), data["pi"]) assert.Equal(true, data["bool"]) }