Skip to content

Commit 4a771c5

Browse files
author
Matthias Rampke
committed
Import instrumentation from juliusv/prometheus_workshop
we don't want to focus on that bit too much, so we give people the app already instrumented
1 parent 58e3730 commit 4a771c5

File tree

2 files changed

+52
-3
lines changed

2 files changed

+52
-3
lines changed

example_golang/main.go

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"time"
88

99
"github.com/justinas/alice"
10+
"github.com/prometheus/client_golang/prometheus"
1011
"github.com/streadway/handy/report"
1112
)
1213

@@ -20,6 +21,7 @@ func main() {
2021
flag.Parse()
2122

2223
http.HandleFunc("/api/", handleAPI)
24+
http.Handle("/metrics", prometheus.Handler())
2325

2426
// Log every received HTTP request to stdout.
2527
go http.ListenAndServe(*addr, alice.New(

example_golang/server.go

+50-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,43 @@
11
package main
22

33
import (
4+
"fmt"
45
"math/rand"
56
"net/http"
67
_ "net/http/pprof"
78
"time"
9+
10+
"github.com/prometheus/client_golang/prometheus"
11+
)
12+
13+
var (
14+
namespace = "codelab"
15+
subsystem = "api"
16+
17+
requestHistogram = prometheus.NewHistogramVec(
18+
prometheus.HistogramOpts{
19+
Namespace: namespace,
20+
Subsystem: subsystem,
21+
Name: "request_duration_seconds",
22+
Help: "A histogram of the API HTTP request durations in seconds.",
23+
Buckets: prometheus.ExponentialBuckets(0.0001, 1.5, 25),
24+
},
25+
[]string{"method", "path", "status"},
26+
)
27+
requestsInProgress = prometheus.NewGauge(
28+
prometheus.GaugeOpts{
29+
Namespace: namespace,
30+
Subsystem: subsystem,
31+
Name: "http_requests_in_progress",
32+
Help: "The current number of API HTTP requests in progress.",
33+
})
834
)
935

36+
func init() {
37+
prometheus.MustRegister(requestHistogram)
38+
prometheus.MustRegister(requestsInProgress)
39+
}
40+
1041
type responseOpts struct {
1142
baseLatency time.Duration
1243
errorRatio float64
@@ -47,14 +78,29 @@ var opts = map[string]map[string]responseOpts{
4778
}
4879

4980
func handleAPI(w http.ResponseWriter, r *http.Request) {
81+
begun := time.Now()
82+
requestsInProgress.Inc()
83+
status := http.StatusOK
84+
85+
defer func() {
86+
requestsInProgress.Dec()
87+
requestHistogram.With(prometheus.Labels{
88+
"method": r.Method,
89+
"path": r.URL.Path,
90+
"status": fmt.Sprint(status),
91+
}).Observe(time.Since(begun).Seconds())
92+
}()
93+
5094
pathOpts, ok := opts[r.URL.Path]
5195
if !ok {
52-
http.Error(w, "Not Found", http.StatusNotFound)
96+
status = http.StatusNotFound
97+
http.Error(w, fmt.Sprintf("Path %q not found.", r.URL.Path), status)
5398
return
5499
}
55100
methodOpts, ok := pathOpts[r.Method]
56101
if !ok {
57-
http.Error(w, "Method not Allowed", http.StatusMethodNotAllowed)
102+
status = http.StatusMethodNotAllowed
103+
http.Error(w, fmt.Sprintf("Method %q not allowed.", r.Method), status)
58104
return
59105
}
60106

@@ -68,6 +114,7 @@ func handleAPI(w http.ResponseWriter, r *http.Request) {
68114
(methodOpts.baseLatency + time.Duration(rand.NormFloat64()*float64(methodOpts.baseLatency)/10)) * latencyFactor,
69115
)
70116
if rand.Float64() <= methodOpts.errorRatio*errorFactor {
71-
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
117+
status = http.StatusInternalServerError
118+
http.Error(w, "Fake error to test monitoring.", status)
72119
}
73120
}

0 commit comments

Comments
 (0)