Example #1
0
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))
}
Example #2
0
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))
}
Example #3
0
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)
}
Example #4
0
// 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))
}
Example #5
0
// 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
}
Example #6
0
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(),
	))
}
Example #7
0
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))
}
Example #8
0
// 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),
	))
}
Example #9
0
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)
}
Example #10
0
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)
}
Example #11
0
// 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)
}
Example #12
0
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)
}
Example #13
0
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
}
Example #14
0
// 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
}
Example #15
0
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)
	}
}
Example #16
0
// 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
}
Example #17
0
func (f *apiHandler) publicDir() http.HandlerFunc {
	fs := http.FileServer(http.Dir(f.conf.PublicDir))
	return prometheus.InstrumentHandler("frontend", fs)
}
Example #18
0
func (f *apiHandler) register(name string, writer writerFunc) http.HandlerFunc {
	h := prometheus.InstrumentHandler(name, f.iplookup(writer))
	return f.cors.Handler(h).ServeHTTP
}
Example #19
0
func handle(name string, f http.HandlerFunc) http.HandlerFunc {
	h := httputil.CompressionHandler{
		Handler: f,
	}
	return prometheus.InstrumentHandler(name, h)
}
Example #20
0
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(),
			)
		}
	}
}
Example #21
0
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)
	}
}
Example #22
0
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)
}
Example #23
0
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 {}
	}
}
Example #24
0
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)
	}
}