-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
116 lines (98 loc) · 3.46 KB
/
main.go
File metadata and controls
116 lines (98 loc) · 3.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package main
import (
"context"
"flag"
"fmt"
"net/http"
"os"
"strconv"
"strings"
"time"
config2 "web_proxy_cache/config"
"web_proxy_cache/provider"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/segmentio/ksuid"
log "github.com/sirupsen/logrus"
)
var version = "undefined"
var ServerAddress = config2.GetEnv("SERVER_ADDRESS", ":8080")
func main() {
versionFlag := flag.Bool("v", false, "Show version")
flag.Parse()
if *versionFlag {
fmt.Printf("web_proxy_cache version %s\n", version)
os.Exit(0)
}
// Create a Prometheus histogram for response time of the exporter
responseTime := promauto.NewHistogramVec(prometheus.HistogramOpts{
Name: config2.MetricsPrefix + "request_duration_seconds",
Help: "Histogram of the time (in seconds) each request took to complete.",
Buckets: []float64{0.050, 0.100, 0.200, 0.500, 0.800, 1.00, 2.000, 3.000},
},
[]string{"proxy", "status"},
)
// Register each provider endpoint
for path, handler := range provider.Providers {
log.WithFields(log.Fields{"path": path}).Info("Registering provider")
http.Handle(path, logCall(promMonitor(handler, responseTime, path)))
}
// Setup handler for exporter metrics
http.Handle("/metrics", promhttp.HandlerFor(
prometheus.DefaultGatherer,
promhttp.HandlerOpts{
// Opt into OpenMetrics to support exemplars.
EnableOpenMetrics: true,
},
))
server := &http.Server{
//ReadTimeout: viper.GetDuration("httpserver.read_timeout") * time.Second,
//WriteTimeout: viper.GetDuration("httpserver.write_timeout") * time.Second,
Addr: ServerAddress,
}
// Start the server and log any errors
//log.WithFields(log.Fields{"address": config.ServerAddress, "version": version}).Info("Starting proxy server")
log.WithFields(log.Fields{"address": ServerAddress, "version": version}).Info("Starting proxy server")
//, "cache_size": config.CacheSize, "cache_ttl": config.CacheTTL, "cache_grace": config.CacheGrace}).Info("Starting proxy server")
err := server.ListenAndServe()
if err != nil {
log.Fatal("Error starting proxy server: ", err)
}
}
type loggingResponseWriter struct {
http.ResponseWriter
statusCode int
length int
}
func logCall(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
lrw := loggingResponseWriter{ResponseWriter: w}
requestId := nextRequestID()
ctx := context.WithValue(r.Context(), "requestid", requestId)
next.ServeHTTP(&lrw, r.WithContext(ctx)) // call original
w.Header().Set("Content-Length", strconv.Itoa(lrw.length))
log.WithFields(log.Fields{
"method": r.Method,
"uri": r.RequestURI,
"fabric": r.URL.Query().Get("target"),
"status": lrw.statusCode,
"length": lrw.length,
"requestid": requestId,
"exec_time": time.Since(start).Microseconds(),
}).Info("api call")
})
}
func nextRequestID() ksuid.KSUID {
return ksuid.New()
}
func promMonitor(next http.Handler, ops *prometheus.HistogramVec, endpoint string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
lrw := loggingResponseWriter{ResponseWriter: w}
next.ServeHTTP(&lrw, r) // call original
response := time.Since(start).Seconds()
ops.With(prometheus.Labels{"proxy": strings.ReplaceAll(endpoint, "/", ""), "status": strconv.Itoa(lrw.statusCode)}).Observe(response)
})
}