Add Prometheus monitoring page under /metrics

This commit is contained in:
Herman Schaaf
2017-09-25 21:41:09 +01:00
committed by Shawn Smith
parent 60e57f234d
commit 572182cf9d
8 changed files with 58 additions and 18 deletions

View File

@@ -1,15 +1,12 @@
package handlers
import (
"log"
"net/http"
"text/template"
)
// AboutHandler handles the about page
func AboutHandler(w http.ResponseWriter, r *http.Request) {
log.Println("Serving about page")
t := template.Must(template.New("about.html").Delims("[[", "]]").ParseFiles("templates/about.html", "templates/footer.html"))
t.Execute(w, map[string]interface{}{
"google_analytics_key": googleAnalyticsKey,

View File

@@ -1,13 +1,11 @@
package handlers
import (
"log"
"net/http"
)
// AssetsHandler handles serving static files
func AssetsHandler(w http.ResponseWriter, r *http.Request) {
log.Println("Serving " + r.URL.Path[1:])
w.Header().Set("Cache-Control", "max-age=86400")
http.ServeFile(w, r, r.URL.Path[1:])
@@ -15,6 +13,5 @@ func AssetsHandler(w http.ResponseWriter, r *http.Request) {
// FaviconHandler handles serving the favicon.ico
func FaviconHandler(w http.ResponseWriter, r *http.Request) {
log.Println("Serving " + r.URL.Path[1:])
http.ServeFile(w, r, "assets/favicon.ico")
}

View File

@@ -13,8 +13,6 @@ import (
// HomeHandler handles the homepage
func HomeHandler(w http.ResponseWriter, r *http.Request) {
log.Println("Serving home page")
if r.URL.Path[1:] == "" {
db, err := bolt.Open(DBPath, 0755, &bolt.Options{Timeout: 1 * time.Second})
if err != nil {

64
main.go
View File

@@ -12,11 +12,15 @@ import (
"github.com/gojp/goreportcard/handlers"
"github.com/boltdb/bolt"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
var (
addr = flag.String("http", ":8000", "HTTP listen address")
dev = flag.Bool("dev", false, "dev mode")
addr = flag.String("http", ":8000", "HTTP listen address")
metricsAddr = flag.String("metrics", ":8001", "The address to listen on for metric-related HTTP requests.")
dev = flag.Bool("dev", false, "dev mode")
)
func makeHandler(name string, dev bool, fn func(http.ResponseWriter, *http.Request, string, bool)) http.HandlerFunc {
@@ -76,6 +80,42 @@ func initDB() error {
return err
}
// metrics provides functionality for monitoring the application status
type metrics struct {
responseTimes *prometheus.SummaryVec
}
// setupMetrics creates custom Prometheus metrics for monitoring
// application statistics.
func setupMetrics() *metrics {
m := &metrics{}
m.responseTimes = prometheus.NewSummaryVec(
prometheus.SummaryOpts{
Name: "response_time_ms",
Help: "Time to serve requests",
},
[]string{"endpoint"},
)
prometheus.MustRegister(m.responseTimes)
return m
}
// recordDuration records the length of a request from start to now
func (m metrics) recordDuration(start time.Time, name string) {
elapsed := time.Since(start)
m.responseTimes.WithLabelValues(name).Observe(float64(elapsed.Nanoseconds()))
log.Printf("Served %s in %s", name, elapsed)
}
// instrument adds metric instrumentation to the handler passed in as argument
func (m metrics) instrument(path string, h http.HandlerFunc) (string, http.HandlerFunc) {
return path, func(w http.ResponseWriter, r *http.Request) {
defer m.recordDuration(time.Now(), path)
h.ServeHTTP(w, r)
}
}
func main() {
flag.Parse()
if err := os.MkdirAll("_repos/src/github.com", 0755); err != nil && !os.IsExist(err) {
@@ -87,14 +127,18 @@ func main() {
log.Fatal("ERROR: could not open bolt db: ", err)
}
http.HandleFunc("/assets/", handlers.AssetsHandler)
http.HandleFunc("/favicon.ico", handlers.FaviconHandler)
http.HandleFunc("/checks", handlers.CheckHandler)
http.HandleFunc("/report/", makeHandler("report", *dev, handlers.ReportHandler))
http.HandleFunc("/badge/", makeHandler("badge", *dev, handlers.BadgeHandler))
http.HandleFunc("/high_scores/", handlers.HighScoresHandler)
http.HandleFunc("/about/", handlers.AboutHandler)
http.HandleFunc("/", handlers.HomeHandler)
m := setupMetrics()
http.HandleFunc(m.instrument("/assets/", handlers.AssetsHandler))
http.HandleFunc(m.instrument("/favicon.ico", handlers.FaviconHandler))
http.HandleFunc(m.instrument("/checks", handlers.CheckHandler))
http.HandleFunc(m.instrument("/report/", makeHandler("report", *dev, handlers.ReportHandler)))
http.HandleFunc(m.instrument("/badge/", makeHandler("badge", *dev, handlers.BadgeHandler)))
http.HandleFunc(m.instrument("/high_scores/", handlers.HighScoresHandler))
http.HandleFunc(m.instrument("/about/", handlers.AboutHandler))
http.HandleFunc(m.instrument("/", handlers.HomeHandler))
http.Handle("/metrics", promhttp.Handler())
log.Printf("Running on %s ...", *addr)
log.Fatal(http.ListenAndServe(*addr, nil))

1
vendor/github.com/prometheus/client_golang generated vendored Submodule

Submodule vendor/github.com/prometheus/client_golang added at 353b8c3f37

1
vendor/github.com/prometheus/client_model generated vendored Submodule

Submodule vendor/github.com/prometheus/client_model added at 6f38060186

1
vendor/github.com/prometheus/common generated vendored Submodule

Submodule vendor/github.com/prometheus/common added at 2f17f4a9d4

1
vendor/github.com/prometheus/procfs generated vendored Submodule

Submodule vendor/github.com/prometheus/procfs added at e645f4e5aa