fork of https://github.com/sourcegraph/zoekt
0

Configure Feed

Select the types of activity you want to include in your feed.

Add prometheus metrics to zoekt-dynamic-indexserver (#541)

+64 -6
+50 -6
cmd/zoekt-dynamic-indexserver/main.go
··· 31 31 "path/filepath" 32 32 "strconv" 33 33 "time" 34 + 35 + "github.com/prometheus/client_golang/prometheus" 36 + "github.com/prometheus/client_golang/prometheus/collectors" 37 + "github.com/prometheus/client_golang/prometheus/promauto" 38 + "github.com/prometheus/client_golang/prometheus/promhttp" 34 39 ) 35 40 36 41 func loggedRun(cmd *exec.Cmd) error { ··· 125 130 } 126 131 127 132 type indexServer struct { 128 - opts Options 133 + opts Options 134 + promRegistry *prometheus.Registry 135 + metricsRequestsTotal *prometheus.CounterVec 129 136 } 130 137 131 138 func (s *indexServer) serveHealthCheck(w http.ResponseWriter, r *http.Request) { 132 139 // Nothing to do. Just return 200 133 140 } 134 141 142 + func (s *indexServer) serveMetrics(w http.ResponseWriter, r *http.Request) { 143 + promhttp.HandlerFor(s.promRegistry, promhttp.HandlerOpts{Registry: s.promRegistry}).ServeHTTP(w, r) 144 + } 145 + 135 146 func (s *indexServer) serveIndex(w http.ResponseWriter, r *http.Request) { 147 + route := "index" 136 148 dec := json.NewDecoder(r.Body) 137 149 dec.DisallowUnknownFields() 138 150 var req indexRequest ··· 146 158 147 159 response, err := indexRepository(s.opts, req) 148 160 if err != nil { 149 - respondWithError(w, err) 161 + s.respondWithError(w, r.Method, route, err) 150 162 return 151 163 } 152 164 153 165 w.Header().Set("Content-Type", "application/json") 154 166 _ = json.NewEncoder(w).Encode(response) 167 + 168 + s.incrementRequestsTotal(r.Method, route, http.StatusOK) 155 169 } 156 170 157 171 func (s *indexServer) serveTruncate(w http.ResponseWriter, r *http.Request) { 172 + route := "truncate" 158 173 err := emptyDirectory(s.opts.repoDir) 159 174 160 175 if err != nil { 161 176 err = fmt.Errorf("Failed to empty repoDir repoDir: %v with error: %v", s.opts.repoDir, err) 162 177 163 - respondWithError(w, err) 178 + s.respondWithError(w, r.Method, route, err) 164 179 return 165 180 } 166 181 ··· 169 184 if err != nil { 170 185 err = fmt.Errorf("Failed to empty repoDir indexDir: %v with error: %v", s.opts.repoDir, err) 171 186 172 - respondWithError(w, err) 187 + s.respondWithError(w, r.Method, route, err) 173 188 return 174 189 } 175 190 ··· 178 193 } 179 194 w.Header().Set("Content-Type", "application/json") 180 195 _ = json.NewEncoder(w).Encode(response) 196 + 197 + s.incrementRequestsTotal(r.Method, route, http.StatusOK) 181 198 } 182 199 183 - func respondWithError(w http.ResponseWriter, err error) { 200 + func (s *indexServer) respondWithError(w http.ResponseWriter, method, route string, err error) { 201 + responseCode := http.StatusInternalServerError 202 + 184 203 log.Print(err) 204 + s.incrementRequestsTotal(method, route, responseCode) 185 205 186 206 w.Header().Set("Content-Type", "application/json") 187 - w.WriteHeader(http.StatusInternalServerError) 207 + w.WriteHeader(responseCode) 188 208 response := map[string]any{ 189 209 "Success": false, 190 210 "Error": err.Error(), ··· 193 213 _ = json.NewEncoder(w).Encode(response) 194 214 } 195 215 216 + func (s *indexServer) incrementRequestsTotal(method, route string, responseCode int) { 217 + s.metricsRequestsTotal.With(prometheus.Labels{"code": strconv.Itoa(responseCode), "method": method, "route": route}).Inc() 218 + } 219 + 220 + func (s *indexServer) initMetrics() { 221 + s.promRegistry = prometheus.NewRegistry() 222 + 223 + // Add go runtime metrics and process collectors. 224 + s.promRegistry.MustRegister( 225 + collectors.NewGoCollector(), 226 + collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}), 227 + ) 228 + 229 + s.metricsRequestsTotal = promauto.With(s.promRegistry).NewCounterVec( 230 + prometheus.CounterOpts{ 231 + Name: "zoekt_dynamic_indexserver_requests_total", 232 + Help: "Total number of HTTP requests by status code, method, and route.", 233 + }, 234 + []string{"method", "route", "code"}, 235 + ) 236 + } 237 + 196 238 func (s *indexServer) startIndexingApi() { 197 239 http.HandleFunc("/", s.serveHealthCheck) 240 + http.HandleFunc("/metrics", s.serveMetrics) 198 241 http.HandleFunc("/index", s.serveIndex) 199 242 http.HandleFunc("/truncate", s.serveTruncate) 200 243 ··· 253 296 opts: opts, 254 297 } 255 298 299 + server.initMetrics() 256 300 server.startIndexingApi() 257 301 }
+14
cmd/zoekt-dynamic-indexserver/main_test.go
··· 55 55 } 56 56 } 57 57 58 + func TestInitMetrics(t *testing.T) { 59 + server := indexServer{} 60 + 61 + server.initMetrics() 62 + 63 + if server.promRegistry == nil { 64 + t.Errorf("promRegistry shouldn't be nil") 65 + } 66 + 67 + if server.metricsRequestsTotal == nil { 68 + t.Errorf("metricsRequestsTotal shouldn't be nil") 69 + } 70 + } 71 + 58 72 func TestIndexRepository(t *testing.T) { 59 73 var cmdHistory [][]string 60 74