func (s *Server) route() { s.r = mux.NewRouter().StrictSlash(true) s.r.Path("/").Methods("OPTIONS").HandlerFunc(s.handleProbe) s.r.Path("/robots.txt").HandlerFunc(s.handleRobotsTxt) s.r.Path("/metrics").Handler( prometheus.InstrumentHandler("metrics", prometheus.UninstrumentedHandler())) s.r.PathPrefix("/static/").Handler( prometheus.InstrumentHandler("static", http.StripPrefix("/static", http.HandlerFunc(s.handleStatic)))) s.r.Handle("/", prometheus.InstrumentHandlerFunc("home", s.handleHomeStatic)) s.r.PathPrefix("/about").Handler( prometheus.InstrumentHandler("about", http.HandlerFunc(s.handleAboutStatic))) s.r.HandleFunc("/room/{room:[a-z0-9]+}/ws", instrumentSocketHandlerFunc("ws", s.handleRoom)) s.r.Handle( "/room/{room:[a-z0-9]+}/", prometheus.InstrumentHandlerFunc("room_static", s.handleRoomStatic)) s.r.Handle( "/prefs/reset-password", prometheus.InstrumentHandlerFunc("prefsResetPassword", s.handleResetPassword)) s.r.Handle( "/prefs/verify", prometheus.InstrumentHandlerFunc("prefsVerify", s.handlePrefsVerify)) }
func (s *Server) route() { s.r = mux.NewRouter().StrictSlash(true) s.r.NotFoundHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { s.serveErrorPage("page not found", http.StatusNotFound, w, r) }) s.r.Path("/").Methods("OPTIONS").HandlerFunc(s.handleProbe) s.r.Path("/robots.txt").HandlerFunc(s.handleRobotsTxt) s.r.Path("/metrics").Handler( prometheus.InstrumentHandler("metrics", prometheus.UninstrumentedHandler())) s.r.PathPrefix("/static/").Handler( prometheus.InstrumentHandler("static", http.HandlerFunc(s.handleStatic))) s.r.Handle("/", prometheus.InstrumentHandlerFunc("home", s.handleHomeStatic)) s.r.PathPrefix("/about").Handler( prometheus.InstrumentHandler("about", http.HandlerFunc(s.handleAboutStatic))) s.r.HandleFunc("/room/{prefix:(pm:)?}{room:[a-z0-9]+}/ws", instrumentSocketHandlerFunc("ws", s.handleRoom)) s.r.Handle( "/room/{prefix:(pm:)?}{room:[a-z0-9]+}/", prometheus.InstrumentHandlerFunc("room_static", s.handleRoomStatic)) s.r.Handle( "/prefs/reset-password", prometheus.InstrumentHandlerFunc("prefsResetPassword", s.handlePrefsResetPassword)) s.r.Handle( "/prefs/verify", prometheus.InstrumentHandlerFunc("prefsVerify", s.handlePrefsVerify)) }
func Start(config *Config) error { if err := clone(config); err != nil { return err } handler := handler(config) ops := http.NewServeMux() if config.AllowHooks { ops.Handle("/hooks/", prometheus.InstrumentHandler("hooks", http.StripPrefix("/hooks", hooksHandler(config)))) } /*ops.Handle("/reflect/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() fmt.Fprintf(os.Stdout, "%s %s\n", r.Method, r.URL) io.Copy(os.Stdout, r.Body) }))*/ ops.Handle("/metrics", prometheus.UninstrumentedHandler()) healthz.InstallHandler(ops) mux := http.NewServeMux() mux.Handle("/", prometheus.InstrumentHandler("git", handler)) mux.Handle("/_/", http.StripPrefix("/_", ops)) log.Printf("Serving %s on %s", config.Home, config.Listen) return http.ListenAndServe(config.Listen, mux) }
// Register the API's endpoints in the given router. func (api *API) Register(r *route.Router) { instr := func(name string, f apiFunc) http.HandlerFunc { hf := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { setCORS(w) if data, err := f(r); err != nil { respondError(w, err, data) } else if data != nil { respond(w, data) } else { w.WriteHeader(http.StatusNoContent) } }) return prometheus.InstrumentHandler(name, httputil.CompressionHandler{ Handler: hf, }) } r.Options("/*path", instr("options", api.options)) r.Get("/query", instr("query", api.query)) r.Get("/query_range", instr("query_range", api.queryRange)) r.Get("/label/:name/values", instr("label_values", api.labelValues)) r.Get("/series", instr("series", api.series)) r.Del("/series", instr("drop_series", api.dropSeries)) }
// Register an endpoint with the HTTP server func (m *Manager) RegisterHttpHandler(method string, path string, handle http.Handler) *Manager { log.AppLog.Debug("Registering HTTP endpoint on '%s' with method '%s'", path, method) m.httpRouter.Add(method, path, prometheus.InstrumentHandler(path, handle)) return m }
func ExampleInstrumentHandler() { // Handle the "/doc" endpoint with the standard http.FileServer handler. // By wrapping the handler with InstrumentHandler, request count, // request and response sizes, and request latency are automatically // exported to Prometheus, partitioned by HTTP status code and method // and by the handler name (here "fileserver"). http.Handle("/doc", prometheus.InstrumentHandler( "fileserver", http.FileServer(http.Dir("/usr/share/doc")), )) // The Prometheus handler still has to be registered to handle the // "/metrics" endpoint. The handler returned by prometheus.Handler() is // already instrumented - with "prometheus" as the handler name. In this // example, we want the handler name to be "metrics", so we instrument // the uninstrumented Prometheus handler ourselves. http.Handle("/metrics", prometheus.InstrumentHandler( "metrics", prometheus.UninstrumentedHandler(), )) }
func (ah *apiHandler) RegisterPublicDir(mux *http.ServeMux) { if ah.conf.PublicDir == "" { return } fs := http.FileServer(http.Dir(ah.conf.PublicDir)) fs = prometheus.InstrumentHandler("frontend", fs) prefix := ah.prefix("") mux.Handle(prefix, http.StripPrefix(prefix, fs)) }
// RegisterHandler registers the handler for the various endpoints below /api. func (msrv *MetricsService) RegisterHandler() { handler := func(h func(http.ResponseWriter, *http.Request)) http.Handler { return httputils.CompressionHandler{ Handler: http.HandlerFunc(h), } } http.Handle("/api/query", prometheus.InstrumentHandler( "/api/query", handler(msrv.Query), )) http.Handle("/api/query_range", prometheus.InstrumentHandler( "/api/query_range", handler(msrv.QueryRange), )) http.Handle("/api/metrics", prometheus.InstrumentHandler( "/api/metrics", handler(msrv.Metrics), )) http.Handle("/api/targets", prometheus.InstrumentHandler( "/api/targets", handler(msrv.SetTargets), )) }
func main() { flag.Parse() store.Init() p := func(name string, handler http.HandlerFunc) http.Handler { return prometheus.InstrumentHandler(name, handler) } router := mux.NewRouter() router.Handle("/metrics", prometheus.Handler()) router.Handle("/", p("/", home)) router.Handle("/login", p("/login", login)) router.Handle("/verify", p("/verify", verify)) apiRouter := mux.NewRouter() apiRouter.Handle("/api/logout", p("/logout", logout)) apiRouter.Handle("/api/user", p("/user", user)) apiRouter.Handle("/api/user/project", p("/user/project", userProject)) apiRouter.Handle("/api/project", p("/project", project)) apiRouter.Handle("/api/project/member", p("/task/member", member)) apiRouter.Handle("/api/task", p("/task", task)) apiRouter.Handle("/api/task/worker", p("/task/worker", worker)) apiRouter.Handle("/api/milestone", p("/milestone", milestone)) apiRouter.Handle("/api/friend", p("/friend", friend)) apiRouter.Handle("/api/chat", p("/chat", chat)) apiRouter.HandleFunc("/api/ws", ws) router.PathPrefix("/api").Handler(negroni.New( negroni.HandlerFunc(apiMiddleware), negroni.Wrap(apiRouter), )) adminRouter := mux.NewRouter() adminRouter.Handle("/api/admin/user", p("/admin/user", adminUser)) adminRouter.Handle("/api/admin/project", p("/admin/project", adminProject)) router.PathPrefix("/api/admin").Handler(negroni.New( negroni.HandlerFunc(adminMiddleware), negroni.Wrap(adminRouter), )) go h.run() n := negroni.Classic() n.UseHandler(router) port := os.Getenv("PORT") if port == "" { port = "8080" } n.Run(":" + port) }
func (w WebService) ServeForever(pathPrefix string) error { http.Handle(pathPrefix+"favicon.ico", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { http.Error(w, "", 404) })) http.HandleFunc("/", prometheus.InstrumentHandlerFunc("index", func(rw http.ResponseWriter, req *http.Request) { // The "/" pattern matches everything, so we need to check // that we're at the root here. if req.URL.Path == pathPrefix { w.AlertsHandler.ServeHTTP(rw, req) } else if req.URL.Path == strings.TrimRight(pathPrefix, "/") { http.Redirect(rw, req, pathPrefix, http.StatusFound) } else if !strings.HasPrefix(req.URL.Path, pathPrefix) { // We're running under a prefix but the user requested something // outside of it. Let's see if this page exists under the prefix. http.Redirect(rw, req, pathPrefix+strings.TrimLeft(req.URL.Path, "/"), http.StatusFound) } else { http.NotFound(rw, req) } })) http.Handle(pathPrefix+"alerts", prometheus.InstrumentHandler("alerts", w.AlertsHandler)) http.Handle(pathPrefix+"silences", prometheus.InstrumentHandler("silences", w.SilencesHandler)) http.Handle(pathPrefix+"status", prometheus.InstrumentHandler("status", w.StatusHandler)) http.Handle(pathPrefix+"metrics", prometheus.Handler()) if *useLocalAssets { http.Handle(pathPrefix+"static/", http.StripPrefix(pathPrefix+"static/", http.FileServer(http.Dir("web/static")))) } else { http.Handle(pathPrefix+"static/", http.StripPrefix(pathPrefix+"static/", new(blob.Handler))) } http.Handle(pathPrefix+"api/", w.AlertManagerService.Handler()) log.Info("listening on ", *listenAddress) return http.ListenAndServe(*listenAddress, nil) }
// ServeForever serves the HTTP endpoints and only returns upon errors. func (ws WebService) ServeForever() error { http.Handle("/favicon.ico", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { http.Error(w, "", 404) })) http.Handle("/", prometheus.InstrumentHandler( "/", ws.StatusHandler, )) http.Handle("/alerts", prometheus.InstrumentHandler( "/alerts", ws.AlertsHandler, )) http.Handle("/consoles/", prometheus.InstrumentHandler( "/consoles/", http.StripPrefix("/consoles/", ws.ConsolesHandler), )) http.Handle("/graph", prometheus.InstrumentHandler( "/graph", http.HandlerFunc(graphHandler), )) http.Handle("/heap", prometheus.InstrumentHandler( "/heap", http.HandlerFunc(dumpHeap), )) ws.MetricsHandler.RegisterHandler() http.Handle("/metrics", prometheus.Handler()) if *useLocalAssets { http.Handle("/static/", prometheus.InstrumentHandler( "/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("web/static"))), )) } else { http.Handle("/static/", prometheus.InstrumentHandler( "/static/", http.StripPrefix("/static/", new(blob.Handler)), )) } if *userAssetsPath != "" { http.Handle("/user/", prometheus.InstrumentHandler( "/user/", http.StripPrefix("/user/", http.FileServer(http.Dir(*userAssetsPath))), )) } if *enableQuit { http.Handle("/-/quit", http.HandlerFunc(ws.quitHandler)) } glog.Info("listening on ", *listenAddress) return http.ListenAndServe(*listenAddress, nil) }
func (ah *apiHandler) RegisterEncoder(mux *http.ServeMux, path string, enc freegeoip.Encoder) { f := http.Handler(freegeoip.NewHandler(ah.conf.DB, enc)) if ah.conf.RateLimiter.Max > 0 { rl := ah.conf.RateLimiter rl.Handler = f f = &rl } origin := ah.conf.Origin if origin == "" { origin = "*" } f = cors(f, origin, "GET", "HEAD") f = prometheus.InstrumentHandler(path, f) mux.Handle(ah.prefix(path), f) }
func (s *Server) configureRouter() error { dirs := s.conf.GetDirectives() router := mux.NewRouter() // register prometheus handler router.Handle("/metrics", prometheus.Handler()) services, err := getServices(s.conf) if err != nil { return err } corsEnabled := dirs.Server.CORSEnabledServices base := strings.TrimRight(dirs.Server.BaseURL, "/") for _, svc := range services { for path, methods := range svc.Endpoints() { for method, handlerFunc := range methods { handlerFunc := http.HandlerFunc(handlerFunc) var handler http.Handler handler = handlerFunc if isServiceEnabled(svc.Name(), corsEnabled) { handler = s.corsHandler(handlerFunc) } svcBase := strings.TrimRight(svc.BaseURL(), "/") fullEndpoint := base + svcBase + path router.Handle(fullEndpoint, handler).Methods(method) if isServiceEnabled(svc.Name(), corsEnabled) { router.Handle(fullEndpoint, handler).Methods("OPTIONS") } u := strings.TrimRight(dirs.Server.BaseURL, "/") + svcBase + path prometheus.InstrumentHandler(u, handler) //ep := fmt.Sprintf("%s %s", method, u) s.log.WithField("method", method).WithField("endpoint", u).Info("endpoint registered") if isServiceEnabled(svc.Name(), corsEnabled) { //ep := fmt.Sprintf("%s %s", "OPTIONS", u) s.log.WithField("method", "OPTIONS").WithField("endpoint", u).Info("endpoint registered (cors)") } } } } s.router = router return nil }
// Create is used to create a new router func Create(scheduler types.Scheduler) *mux.Router { routes := types.Routes{ types.Route{ Name: "AddTask", Method: "POST", Pattern: "/task", Handler: handler.AddTask(scheduler), }, types.Route{ Name: "Status", Method: "GET", Pattern: "/task/{taskId}", Handler: handler.GetTaskInfo(scheduler), }, } router := mux.NewRouter().StrictSlash(true) for _, route := range routes { router. Methods(route.Method). Path(route.Pattern). Name(route.Name). Handler(prometheus.InstrumentHandler(route.Name, route.Handler)) } router. Methods("GET"). Path("/metrics"). Name("Metrics"). Handler(prometheus.Handler()) router. Methods("GET"). Path("/"). Name("Index"). HandlerFunc(indexHandler) router.PathPrefix("/static/"). Handler( http.StripPrefix( "/static/", http.FileServer( &assetfs.AssetFS{Asset: assets.Asset, AssetDir: assets.AssetDir, AssetInfo: assets.AssetInfo, Prefix: "static"}))) router.NotFoundHandler = http.HandlerFunc(notFound) return router }
func main() { logger := log.NewJSONLogger(os.Stdout) listen := os.Getenv("VANITY_LISTEN") if listen == "" { listen = ":8080" } listenMgmt := os.Getenv("VANITY_LISTEN_MGMT") if listenMgmt == "" { listenMgmt = ":8081" } config, err := loadConfiguration(logger, "conf/vanity.yaml") if err != nil { logger.Log("level", "error", "msg", "Could not load config", "err", err) os.Exit(1) } srv := server.New(server.Config{ Log: logger, Hosts: config.Hosts, }) go handleSigs() go func() { http.Handle("/metrics", prometheus.Handler()) http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) { http.Error(w, "OK", http.StatusOK) }) http.HandleFunc("/", http.NotFound) if err := http.ListenAndServe(listenMgmt, nil); err != nil { logger.Log("level", "error", "msg", "Failed to listen on management port", "err", err) } }() s := &http.Server{ Addr: listen, Handler: prometheus.InstrumentHandler("vanity", srv), } if err := s.ListenAndServe(); err != nil { logger.Log("level", "error", "msg", "Failed to listen", "err", err) os.Exit(1) } }
// NewRouter is used to create a new router. func NewRouter(scheduler eremetic.Scheduler, conf *config.Config, db eremetic.TaskDB) *mux.Router { h := NewHandler(scheduler, db) router := mux.NewRouter().StrictSlash(true) for _, route := range routes(h, conf) { router. Methods(route.Method). Path(route.Pattern). Name(route.Name). Handler(prometheus.InstrumentHandler(route.Name, route.Handler)) } router. PathPrefix("/static/"). Handler(h.StaticAssets()) router.NotFoundHandler = http.HandlerFunc(h.NotFound()) return router }
func (f *apiHandler) publicDir() http.HandlerFunc { fs := http.FileServer(http.Dir(f.conf.PublicDir)) return prometheus.InstrumentHandler("frontend", fs) }
func (f *apiHandler) register(name string, writer writerFunc) http.HandlerFunc { h := prometheus.InstrumentHandler(name, f.iplookup(writer)) return f.cors.Handler(h).ServeHTTP }
func handle(name string, f http.HandlerFunc) http.HandlerFunc { h := httputil.CompressionHandler{ Handler: f, } return prometheus.InstrumentHandler(name, h) }
func testHandler(t testing.TB) { metricVec := prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "name", Help: "docstring", ConstLabels: prometheus.Labels{"constname": "constvalue"}, }, []string{"labelname"}, ) metricVec.WithLabelValues("val1").Inc() metricVec.WithLabelValues("val2").Inc() externalMetricFamily := &dto.MetricFamily{ Name: proto.String("externalname"), Help: proto.String("externaldocstring"), Type: dto.MetricType_COUNTER.Enum(), Metric: []*dto.Metric{ { Label: []*dto.LabelPair{ { Name: proto.String("externalconstname"), Value: proto.String("externalconstvalue"), }, { Name: proto.String("externallabelname"), Value: proto.String("externalval1"), }, }, Counter: &dto.Counter{ Value: proto.Float64(1), }, }, }, } externalBuf := &bytes.Buffer{} enc := expfmt.NewEncoder(externalBuf, expfmt.FmtProtoDelim) if err := enc.Encode(externalMetricFamily); err != nil { t.Fatal(err) } externalMetricFamilyAsBytes := externalBuf.Bytes() externalMetricFamilyAsText := []byte(`# HELP externalname externaldocstring # TYPE externalname counter externalname{externalconstname="externalconstvalue",externallabelname="externalval1"} 1 `) externalMetricFamilyAsProtoText := []byte(`name: "externalname" help: "externaldocstring" type: COUNTER metric: < label: < name: "externalconstname" value: "externalconstvalue" > label: < name: "externallabelname" value: "externalval1" > counter: < value: 1 > > `) externalMetricFamilyAsProtoCompactText := []byte(`name:"externalname" help:"externaldocstring" type:COUNTER metric:<label:<name:"externalconstname" value:"externalconstvalue" > label:<name:"externallabelname" value:"externalval1" > counter:<value:1 > > `) expectedMetricFamily := &dto.MetricFamily{ Name: proto.String("name"), Help: proto.String("docstring"), Type: dto.MetricType_COUNTER.Enum(), Metric: []*dto.Metric{ { Label: []*dto.LabelPair{ { Name: proto.String("constname"), Value: proto.String("constvalue"), }, { Name: proto.String("labelname"), Value: proto.String("val1"), }, }, Counter: &dto.Counter{ Value: proto.Float64(1), }, }, { Label: []*dto.LabelPair{ { Name: proto.String("constname"), Value: proto.String("constvalue"), }, { Name: proto.String("labelname"), Value: proto.String("val2"), }, }, Counter: &dto.Counter{ Value: proto.Float64(1), }, }, }, } buf := &bytes.Buffer{} enc = expfmt.NewEncoder(buf, expfmt.FmtProtoDelim) if err := enc.Encode(expectedMetricFamily); err != nil { t.Fatal(err) } expectedMetricFamilyAsBytes := buf.Bytes() expectedMetricFamilyAsText := []byte(`# HELP name docstring # TYPE name counter name{constname="constvalue",labelname="val1"} 1 name{constname="constvalue",labelname="val2"} 1 `) expectedMetricFamilyAsProtoText := []byte(`name: "name" help: "docstring" type: COUNTER metric: < label: < name: "constname" value: "constvalue" > label: < name: "labelname" value: "val1" > counter: < value: 1 > > metric: < label: < name: "constname" value: "constvalue" > label: < name: "labelname" value: "val2" > counter: < value: 1 > > `) expectedMetricFamilyAsProtoCompactText := []byte(`name:"name" help:"docstring" type:COUNTER metric:<label:<name:"constname" value:"constvalue" > label:<name:"labelname" value:"val1" > counter:<value:1 > > metric:<label:<name:"constname" value:"constvalue" > label:<name:"labelname" value:"val2" > counter:<value:1 > > `) externalMetricFamilyWithSameName := &dto.MetricFamily{ Name: proto.String("name"), Help: proto.String("docstring"), Type: dto.MetricType_COUNTER.Enum(), Metric: []*dto.Metric{ { Label: []*dto.LabelPair{ { Name: proto.String("constname"), Value: proto.String("constvalue"), }, { Name: proto.String("labelname"), Value: proto.String("different_val"), }, }, Counter: &dto.Counter{ Value: proto.Float64(42), }, }, }, } expectedMetricFamilyMergedWithExternalAsProtoCompactText := []byte(`name:"name" help:"docstring" type:COUNTER metric:<label:<name:"constname" value:"constvalue" > label:<name:"labelname" value:"different_val" > counter:<value:42 > > metric:<label:<name:"constname" value:"constvalue" > label:<name:"labelname" value:"val1" > counter:<value:1 > > metric:<label:<name:"constname" value:"constvalue" > label:<name:"labelname" value:"val2" > counter:<value:1 > > `) type output struct { headers map[string]string body []byte } var scenarios = []struct { headers map[string]string out output collector prometheus.Collector externalMF []*dto.MetricFamily }{ { // 0 headers: map[string]string{ "Accept": "foo/bar;q=0.2, dings/bums;q=0.8", }, out: output{ headers: map[string]string{ "Content-Type": `text/plain; version=0.0.4`, }, body: []byte{}, }, }, { // 1 headers: map[string]string{ "Accept": "foo/bar;q=0.2, application/quark;q=0.8", }, out: output{ headers: map[string]string{ "Content-Type": `text/plain; version=0.0.4`, }, body: []byte{}, }, }, { // 2 headers: map[string]string{ "Accept": "foo/bar;q=0.2, application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=bla;q=0.8", }, out: output{ headers: map[string]string{ "Content-Type": `text/plain; version=0.0.4`, }, body: []byte{}, }, }, { // 3 headers: map[string]string{ "Accept": "text/plain;q=0.2, application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=delimited;q=0.8", }, out: output{ headers: map[string]string{ "Content-Type": `application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited`, }, body: []byte{}, }, }, { // 4 headers: map[string]string{ "Accept": "application/json", }, out: output{ headers: map[string]string{ "Content-Type": `text/plain; version=0.0.4`, }, body: expectedMetricFamilyAsText, }, collector: metricVec, }, { // 5 headers: map[string]string{ "Accept": "application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=delimited", }, out: output{ headers: map[string]string{ "Content-Type": `application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited`, }, body: expectedMetricFamilyAsBytes, }, collector: metricVec, }, { // 6 headers: map[string]string{ "Accept": "application/json", }, out: output{ headers: map[string]string{ "Content-Type": `text/plain; version=0.0.4`, }, body: externalMetricFamilyAsText, }, externalMF: []*dto.MetricFamily{externalMetricFamily}, }, { // 7 headers: map[string]string{ "Accept": "application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=delimited", }, out: output{ headers: map[string]string{ "Content-Type": `application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited`, }, body: externalMetricFamilyAsBytes, }, externalMF: []*dto.MetricFamily{externalMetricFamily}, }, { // 8 headers: map[string]string{ "Accept": "application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=delimited", }, out: output{ headers: map[string]string{ "Content-Type": `application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited`, }, body: bytes.Join( [][]byte{ externalMetricFamilyAsBytes, expectedMetricFamilyAsBytes, }, []byte{}, ), }, collector: metricVec, externalMF: []*dto.MetricFamily{externalMetricFamily}, }, { // 9 headers: map[string]string{ "Accept": "text/plain", }, out: output{ headers: map[string]string{ "Content-Type": `text/plain; version=0.0.4`, }, body: []byte{}, }, }, { // 10 headers: map[string]string{ "Accept": "application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=bla;q=0.2, text/plain;q=0.5", }, out: output{ headers: map[string]string{ "Content-Type": `text/plain; version=0.0.4`, }, body: expectedMetricFamilyAsText, }, collector: metricVec, }, { // 11 headers: map[string]string{ "Accept": "application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=bla;q=0.2, text/plain;q=0.5;version=0.0.4", }, out: output{ headers: map[string]string{ "Content-Type": `text/plain; version=0.0.4`, }, body: bytes.Join( [][]byte{ externalMetricFamilyAsText, expectedMetricFamilyAsText, }, []byte{}, ), }, collector: metricVec, externalMF: []*dto.MetricFamily{externalMetricFamily}, }, { // 12 headers: map[string]string{ "Accept": "application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=delimited;q=0.2, text/plain;q=0.5;version=0.0.2", }, out: output{ headers: map[string]string{ "Content-Type": `application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited`, }, body: bytes.Join( [][]byte{ externalMetricFamilyAsBytes, expectedMetricFamilyAsBytes, }, []byte{}, ), }, collector: metricVec, externalMF: []*dto.MetricFamily{externalMetricFamily}, }, { // 13 headers: map[string]string{ "Accept": "application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=text;q=0.5, application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=delimited;q=0.4", }, out: output{ headers: map[string]string{ "Content-Type": `application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=text`, }, body: bytes.Join( [][]byte{ externalMetricFamilyAsProtoText, expectedMetricFamilyAsProtoText, }, []byte{}, ), }, collector: metricVec, externalMF: []*dto.MetricFamily{externalMetricFamily}, }, { // 14 headers: map[string]string{ "Accept": "application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=compact-text", }, out: output{ headers: map[string]string{ "Content-Type": `application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=compact-text`, }, body: bytes.Join( [][]byte{ externalMetricFamilyAsProtoCompactText, expectedMetricFamilyAsProtoCompactText, }, []byte{}, ), }, collector: metricVec, externalMF: []*dto.MetricFamily{externalMetricFamily}, }, { // 15 headers: map[string]string{ "Accept": "application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=compact-text", }, out: output{ headers: map[string]string{ "Content-Type": `application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=compact-text`, }, body: bytes.Join( [][]byte{ externalMetricFamilyAsProtoCompactText, expectedMetricFamilyMergedWithExternalAsProtoCompactText, }, []byte{}, ), }, collector: metricVec, externalMF: []*dto.MetricFamily{ externalMetricFamily, externalMetricFamilyWithSameName, }, }, } for i, scenario := range scenarios { registry := prometheus.NewPedanticRegistry() gatherer := prometheus.Gatherer(registry) if scenario.externalMF != nil { gatherer = prometheus.Gatherers{ registry, prometheus.GathererFunc(func() ([]*dto.MetricFamily, error) { return scenario.externalMF, nil }), } } if scenario.collector != nil { registry.Register(scenario.collector) } writer := httptest.NewRecorder() handler := prometheus.InstrumentHandler("prometheus", promhttp.HandlerFor(gatherer, promhttp.HandlerOpts{})) request, _ := http.NewRequest("GET", "/", nil) for key, value := range scenario.headers { request.Header.Add(key, value) } handler(writer, request) for key, value := range scenario.out.headers { if writer.HeaderMap.Get(key) != value { t.Errorf( "%d. expected %q for header %q, got %q", i, value, key, writer.Header().Get(key), ) } } if !bytes.Equal(scenario.out.body, writer.Body.Bytes()) { t.Errorf( "%d. expected body:\n%s\ngot body:\n%s\n", i, scenario.out.body, writer.Body.Bytes(), ) } } }
func main() { var ( showVersion = flag.Bool("version", false, "Print version information.") listenAddress = flag.String("web.listen-address", ":9100", "Address on which to expose metrics and web interface.") metricsPath = flag.String("web.telemetry-path", "/metrics", "Path under which to expose metrics.") enabledCollectors = flag.String("collectors.enabled", filterAvailableCollectors(defaultCollectors), "Comma-separated list of collectors to use.") printCollectors = flag.Bool("collectors.print", false, "If true, print available collectors and exit.") ) flag.Parse() if *showVersion { fmt.Fprintln(os.Stdout, version.Print("node_exporter")) os.Exit(0) } log.Infoln("Starting node_exporter", version.Info()) log.Infoln("Build context", version.BuildContext()) if *printCollectors { collectorNames := make(sort.StringSlice, 0, len(collector.Factories)) for n := range collector.Factories { collectorNames = append(collectorNames, n) } collectorNames.Sort() fmt.Printf("Available collectors:\n") for _, n := range collectorNames { fmt.Printf(" - %s\n", n) } return } collectors, err := loadCollectors(*enabledCollectors) if err != nil { log.Fatalf("Couldn't load collectors: %s", err) } log.Infof("Enabled collectors:") for n := range collectors { log.Infof(" - %s", n) } prometheus.MustRegister(NodeCollector{collectors: collectors}) handler := promhttp.HandlerFor(prometheus.DefaultGatherer, promhttp.HandlerOpts{ErrorLog: log.NewErrorLogger()}) http.Handle(*metricsPath, prometheus.InstrumentHandler("prometheus", handler)) http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte(`<html> <head><title>Node Exporter</title></head> <body> <h1>Node Exporter</h1> <p><a href="` + *metricsPath + `">Metrics</a></p> </body> </html>`)) }) log.Infoln("Listening on", *listenAddress) err = http.ListenAndServe(*listenAddress, nil) if err != nil { log.Fatal(err) } }
func main() { // Flag domain. Note that gRPC transitively registers flags via its import // of glog. So, we define a new flag set, to keep those domains distinct. fs := flag.NewFlagSet("", flag.ExitOnError) var ( redisPass = fs.String("redis.pass", "", "Redis server password") redisDB = fs.Int64("redis.db", 0, "Redis server database") shortenProto = fs.String("short.proto", "http", "Protocol to use for short urls") shortenHost = fs.String("short.host", "localhost", "Host to use for short urls") shortenNotFound = fs.String("short.na", "/", "Redirect address in case no url was found") ) flag.Usage = fs.Usage // only show our flags fs.Parse(os.Args[1:]) // `package log` domain var logger kitlog.Logger logger = kitlog.NewLogfmtLogger(os.Stderr) logger = kitlog.NewContext(logger).With("ts", defaultTimestampUTCNano) stdlog.SetOutput(kitlog.NewStdlibAdapter(logger)) // redirect stdlib logging to us stdlog.SetFlags(0) // flags are handled in our logger // Server domain // Shortener needs a redis connection redisHost := os.Getenv("REDIS_PORT_6379_TCP_ADDR") redisPort := os.Getenv("REDIS_PORT_6379_TCP_PORT") redisAddr := fmt.Sprintf("%s:%s", redisHost, redisPort) logger.Log("srv", "redis", "addr", redisAddr, "pw", *redisPass, "db", *redisDB) client := redis.NewClient(&redis.Options{ Addr: redisAddr, Password: *redisPass, // no password set DB: *redisDB, // use default DB }) defer client.Close() res, err := client.Ping().Result() if err != nil { logger.Log("fatal", err) os.Exit(1) } logger.Log("srv", "redis", "ping", res) logger.Log("srv", "shorten", "proto", *shortenProto, "host", *shortenHost) var s = shorten.New(*shortenProto, *shortenHost, client) s = metrics.Instrument(s) s = logging.Log(logger, s) shortenEndpoint := shorten.NewShortenEndpoint(s) resolveEndpoint := shorten.NewResolveEndpoint(s) infoEndpoint := shorten.NewInfoEndpoint(s) latestEndpoint := shorten.NewLatestEndpoint(s) // Mechanical stuff rand.Seed(time.Now().UnixNano()) root := context.Background() errc := make(chan error) go func() { errc <- interrupt() }() // Transport: HTTP (debug/instrumentation) go func() { logger.Log("addr", debugAddr, "transport", "debug") http.Handle("/metrics", prometheus.Handler()) errc <- http.ListenAndServe(debugAddr, nil) }() // Transport: HTTP (JSON) go func() { ctx, cancel := context.WithCancel(root) defer cancel() before := []httptransport.BeforeFunc{} after := []httptransport.AfterFunc{} shortenHandler := prometheus.InstrumentHandler( "shorten", shorten.NewShortenHandler(ctx, shortenEndpoint, before, after), ) resolveHandler := prometheus.InstrumentHandler( "resolve", shorten.NewResolveHandler(ctx, resolveEndpoint, *shortenNotFound), ) infoHandler := prometheus.InstrumentHandler( "info", shorten.NewInfoHandler(ctx, infoEndpoint, before, after), ) latestHandler := prometheus.InstrumentHandler( "latest", shorten.NewLatestHandler(ctx, latestEndpoint, before, after), ) router := mux.NewRouter() router.Path("/shorten").Methods("POST").HandlerFunc(shortenHandler) router.Path("/{key:([a-zA-Z0-9]+$)}").Methods("GET", "HEAD").HandlerFunc(resolveHandler) router.Path("/info/{key:[a-zA-Z0-9]+}").Methods("GET").HandlerFunc(infoHandler) router.Path("/latest/{count:[0-9]+}").Methods("GET").HandlerFunc(latestHandler) logger.Log("addr", httpAddr, "transport", "HTTP/JSON") errc <- http.ListenAndServe(httpAddr, logging.Handler(logger, router)) }() // Transport: gRPC go func() { ln, err := net.Listen("tcp", grpcAddr) if err != nil { errc <- err return } s := grpc.NewServer() // uses its own context? pb.RegisterShortServer(s, grpcBinding{ shorten: shortenEndpoint, resolve: resolveEndpoint, info: infoEndpoint, latest: latestEndpoint, }) logger.Log("addr", grpcAddr, "transport", "gRPC") errc <- s.Serve(ln) }() logger.Log("fatal", <-errc) }
func main() { flag.Parse() var synapseProxy proxy.SynapseProxy if u, err := url.Parse(*synapseURL); err != nil { panic(err) } else { synapseProxy.URL = *u } var synapse *exec.Cmd if *startSynapse { synapse = exec.Command(*synapsePython, "-m", "synapse.app.homeserver", "-c", *synapseConfig) synapse.Stderr = os.Stderr log.Print("Dendron: Starting synapse...") synapse.Start() channel := make(chan os.Signal, 1) signal.Notify(channel, os.Interrupt) go handleSignal(channel, synapse.Process) if err := waitForSynapse(&synapseProxy); err != nil { panic(err) } log.Print("Dendron: Synapse started") } else { log.Printf("Dendron: Using existing synapse at %v", synapseProxy.URL.String()) } db, err := sql.Open("postgres", *synapseDB) if err != nil { panic(err) } loginHandler, err := login.NewHandler(db, &synapseProxy, *serverName, *macaroonSecret) if err != nil { panic(err) } versionsHandler, err := versions.NewHandler(&synapseProxy, time.Hour) if err != nil { panic(err) } loginFunc := prometheus.InstrumentHandler("login", loginHandler) proxyFunc := prometheus.InstrumentHandler("proxy", &synapseProxy) versionsFunc := prometheus.InstrumentHandler("versions", versionsHandler) mux := http.NewServeMux() mux.Handle("/", proxyFunc) mux.Handle("/_matrix/client/api/v1/login", loginFunc) mux.Handle("/_matrix/client/r0/login", loginFunc) mux.Handle("/_matrix/client/versions", versionsFunc) mux.HandleFunc("/_dendron/test", func(w http.ResponseWriter, req *http.Request) { fmt.Fprintln(w, "test") }) mux.Handle("/_dendron/metrics", prometheus.Handler()) s := &http.Server{ Addr: *listenAddr, Handler: mux, ReadTimeout: 5 * time.Minute, WriteTimeout: 5 * time.Minute, MaxHeaderBytes: 1 << 20, } listener, err := net.Listen("tcp", s.Addr) if err != nil { panic(err) } if *listenTLS { cert, err := tls.LoadX509KeyPair(*listenCertFile, *listenKeyFile) if err != nil { panic(err) } s.TLSConfig = &tls.Config{ Certificates: []tls.Certificate{cert}, } listener = tls.NewListener(listener, s.TLSConfig) } go s.Serve(listener) if synapse != nil { if err := synapse.Wait(); err != nil { panic(err) } } else { select {} } }
func main() { flag.Parse() if *showVersion { fmt.Fprintln(os.Stdout, version.Print("pushgateway")) os.Exit(0) } log.Infoln("Starting pushgateway", version.Info()) log.Infoln("Build context", version.BuildContext()) flags := map[string]string{} flag.VisitAll(func(f *flag.Flag) { flags[f.Name] = f.Value.String() }) ms := storage.NewDiskMetricStore(*persistenceFile, *persistenceInterval) prometheus.SetMetricFamilyInjectionHook(ms.GetMetricFamilies) // Enable collect checks for debugging. // prometheus.EnableCollectChecks(true) r := httprouter.New() r.Handler("GET", *metricsPath, prometheus.Handler()) // Handlers for pushing and deleting metrics. r.PUT("/metrics/job/:job/*labels", handler.Push(ms, true)) r.POST("/metrics/job/:job/*labels", handler.Push(ms, false)) r.DELETE("/metrics/job/:job/*labels", handler.Delete(ms)) r.PUT("/metrics/job/:job", handler.Push(ms, true)) r.POST("/metrics/job/:job", handler.Push(ms, false)) r.DELETE("/metrics/job/:job", handler.Delete(ms)) // Handlers for the deprecated API. r.PUT("/metrics/jobs/:job/instances/:instance", handler.LegacyPush(ms, true)) r.POST("/metrics/jobs/:job/instances/:instance", handler.LegacyPush(ms, false)) r.DELETE("/metrics/jobs/:job/instances/:instance", handler.LegacyDelete(ms)) r.PUT("/metrics/jobs/:job", handler.LegacyPush(ms, true)) r.POST("/metrics/jobs/:job", handler.LegacyPush(ms, false)) r.DELETE("/metrics/jobs/:job", handler.LegacyDelete(ms)) r.Handler("GET", "/static/*filepath", prometheus.InstrumentHandler( "static", http.FileServer( &assetfs.AssetFS{Asset: Asset, AssetDir: AssetDir, AssetInfo: AssetInfo}, ), )) statusHandler := prometheus.InstrumentHandlerFunc("status", handler.Status(ms, Asset, flags)) r.Handler("GET", "/status", statusHandler) r.Handler("GET", "/", statusHandler) // Re-enable pprof. r.GET("/debug/pprof/*pprof", handlePprof) log.Infof("Listening on %s.", *listenAddress) l, err := net.Listen("tcp", *listenAddress) if err != nil { log.Fatal(err) } go interruptHandler(l) err = (&http.Server{Addr: *listenAddress, Handler: r}).Serve(l) log.Errorln("HTTP server stopped:", err) // To give running connections a chance to submit their payload, we wait // for 1sec, but we don't want to wait long (e.g. until all connections // are done) to not delay the shutdown. time.Sleep(time.Second) if err := ms.Shutdown(); err != nil { log.Errorln("Problem shutting down metric storage:", err) } }