func JSON(h func(miniprofiler.Timer, http.ResponseWriter, *http.Request) (interface{}, error)) http.Handler { return miniprofiler.NewHandler(func(t miniprofiler.Timer, w http.ResponseWriter, r *http.Request) { d, err := h(t, w, r) if err != nil { serveError(w, err) return } if d == nil { return } buf := new(bytes.Buffer) if err := json.NewEncoder(buf).Encode(d); err != nil { log.Println(err) serveError(w, err) return } var tw io.Writer = w if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") { w.Header().Set("Content-Encoding", "gzip") gz := gzip.NewWriter(w) defer gz.Close() tw = gz } if cb := r.FormValue("callback"); cb != "" { w.Header().Add("Content-Type", "application/javascript") tw.Write([]byte(cb + "(")) buf.WriteTo(tw) tw.Write([]byte(")")) return } w.Header().Add("Content-Type", "application/json") buf.WriteTo(tw) }) }
func Listen(listenAddr string, devMode bool, tsdbHost string) error { if devMode { log.Println("using local web assets") } webFS := FS(devMode) indexTemplate = func() *template.Template { str := FSMustString(devMode, "/templates/index.html") templates, err := template.New("").Parse(str) if err != nil { log.Fatal(err) } return templates } if !devMode { tpl := indexTemplate() indexTemplate = func() *template.Template { return tpl } } if tsdbHost != "" { router.HandleFunc("/api/index", IndexTSDB) router.Handle("/api/put", Relay(tsdbHost)) } router.HandleFunc("/api/", APIRedirect) router.Handle("/api/action", JSON(Action)) router.Handle("/api/alerts", JSON(Alerts)) router.Handle("/api/backup", JSON(Backup)) router.Handle("/api/config", miniprofiler.NewHandler(Config)) router.Handle("/api/config_test", miniprofiler.NewHandler(ConfigTest)) router.Handle("/api/egraph/{bs}.svg", JSON(ExprGraph)) router.Handle("/api/expr", JSON(Expr)) router.Handle("/api/graph", JSON(Graph)) router.Handle("/api/health", JSON(HealthCheck)) router.Handle("/api/host", JSON(Host)) router.Handle("/api/incidents", JSON(Incidents)) router.Handle("/api/incidents/events", JSON(IncidentEvents)) router.Handle("/api/metadata/get", JSON(GetMetadata)) router.Handle("/api/metadata/metrics", JSON(MetadataMetrics)) router.Handle("/api/metadata/put", JSON(PutMetadata)) router.Handle("/api/metric", JSON(UniqueMetrics)) router.Handle("/api/metric/{tagk}/{tagv}", JSON(MetricsByTagPair)) router.Handle("/api/metric/tagkey", JSON(MetricsWithTagKeys)) router.Handle("/api/rule", JSON(Rule)) router.HandleFunc("/api/shorten", Shorten) router.Handle("/api/silence/clear", JSON(SilenceClear)) router.Handle("/api/silence/get", JSON(SilenceGet)) router.Handle("/api/silence/set", JSON(SilenceSet)) router.Handle("/api/status", JSON(Status)) router.Handle("/api/tagk/{metric}", JSON(TagKeysByMetric)) router.Handle("/api/tagv/{tagk}", JSON(TagValuesByTagKey)) router.Handle("/api/tagv/{tagk}/{metric}", JSON(TagValuesByMetricTagKey)) router.HandleFunc("/api/version", Version) router.Handle("/api/debug/schedlock", JSON(ScheduleLockStatus)) http.Handle("/", miniprofiler.NewHandler(Index)) http.Handle("/api/", router) fs := http.FileServer(webFS) http.Handle("/partials/", fs) http.Handle("/static/", http.StripPrefix("/static/", fs)) http.Handle("/favicon.ico", fs) log.Println("bosun web listening on:", listenAddr) log.Println("tsdb host:", tsdbHost) return http.ListenAndServe(listenAddr, nil) }