Skip to content

Instantly share code, notes, and snippets.

@0sc
Last active July 18, 2019 04:09
Show Gist options
  • Save 0sc/01a2462171f9ba7fca45d7a61d79336d to your computer and use it in GitHub Desktop.
Save 0sc/01a2462171f9ba7fca45d7a61d79336d to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"io"
"log"
"math"
"math/rand"
"net/http"
"os"
"strings"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
var (
requestCounter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Namespace: "app",
Name: "http_requests_total",
Help: "count http requests",
},
[]string{"code", "method"},
)
responseCounter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Namespace: "app",
Name: "http_response_total",
Help: "count http responses",
},
[]string{"status", "code"},
)
hello = map[string]string{
"en": "Hello",
"es": "Hola",
"de": "Hallo",
"ch": "你好",
"ru": "Привет",
}
port = os.Getenv("PORT")
)
func handler(w http.ResponseWriter, r *http.Request) {
lang := strings.TrimPrefix(r.URL.RequestURI(), "/")
greeting, ok := hello[lang]
if !ok {
fmt.Printf("unknown language: %s\n", lang)
w.WriteHeader(http.StatusBadRequest)
return
}
w.WriteHeader(http.StatusOK)
fmt.Fprint(w, greeting)
}
func selfPing() {
start := time.Now()
oscillationFactor := func() float64 {
return 20 + math.Sin(math.Sin(2*math.Pi*float64(time.Since(start))/float64(10*time.Minute)))
}
langs := []string{"en", "es", "de", "ch", "ru"}
for {
time.Sleep(time.Duration(100*oscillationFactor()) * time.Millisecond)
index := rand.Intn(len(langs))
lang := langs[index]
resp, err := http.Get(fmt.Sprintf("http://0.0.0.0:%s/%s", port, lang))
kind := "failure"
if err != nil {
log.Println("got error", err)
responseCounter.WithLabelValues(kind, "").Inc()
continue
}
if resp.StatusCode == http.StatusOK {
kind = "success"
}
io.Copy(os.Stdout, resp.Body)
fmt.Println()
resp.Body.Close()
responseCounter.WithLabelValues(kind, resp.Status).Inc()
}
}
func main() {
rand.Seed(time.Now().Unix())
pr := prometheus.NewRegistry()
pr.MustRegister(requestCounter, responseCounter)
mux := http.NewServeMux()
mux.Handle("/metrics", promhttp.HandlerFor(pr, promhttp.HandlerOpts{}))
mux.Handle("/", promhttp.InstrumentHandlerCounter(requestCounter, http.HandlerFunc(handler)))
addr := fmt.Sprintf("0.0.0.0:%s", port)
log.Println("starting server on", addr)
go selfPing()
log.Fatal(http.ListenAndServe(addr, mux))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment