diff --git a/core/corehttp/gateway_handler.go b/core/corehttp/gateway_handler.go index 0973e42cf9e..febc4d01af4 100644 --- a/core/corehttp/gateway_handler.go +++ b/core/corehttp/gateway_handler.go @@ -64,7 +64,6 @@ type gatewayHandler struct { config GatewayConfig api coreiface.CoreAPI - // TODO: add metrics for non-unixfs responses (block, car) unixfsGetMetric *prometheus.SummaryVec } @@ -90,6 +89,7 @@ func (sw *statusResponseWriter) WriteHeader(code int) { func newGatewayHandler(c GatewayConfig, api coreiface.CoreAPI) *gatewayHandler { unixfsGetMetric := prometheus.NewSummaryVec( + // TODO: deprecate and switch to content type agnostic metrics: https://github.com/ipfs/go-ipfs/issues/8441 prometheus.SummaryOpts{ Namespace: "ipfs", Subsystem: "http", @@ -305,6 +305,15 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request return } + // Update the global metric of the time it takes to read the final root block of the requested resource + // NOTE: for legacy reasons this happens before we go into content-type specific code paths + _, err = i.api.Block().Get(r.Context(), resolvedPath) + if err != nil { + webError(w, "ipfs block get "+resolvedPath.Cid().String(), err, http.StatusInternalServerError) + return + } + i.unixfsGetMetric.WithLabelValues(parsedPath.Namespace()).Observe(time.Since(begin).Seconds()) + // HTTP Headers i.addUserHeaders(w) // ok, _now_ write user's headers. w.Header().Set("X-Ipfs-Path", urlPath) @@ -348,8 +357,6 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request webError(w, "ipfs cat "+escapedURLPath, err, http.StatusNotFound) return } - // TODO: do we want to reuse unixfsGetMetric for block/car, or should we have separate ones? - i.unixfsGetMetric.WithLabelValues(parsedPath.Namespace()).Observe(time.Since(begin).Seconds()) defer dr.Close() // Handling Unixfs file diff --git a/core/corehttp/gateway_handler_block.go b/core/corehttp/gateway_handler_block.go index 9264e6875a4..d7a3a8c4e8b 100644 --- a/core/corehttp/gateway_handler_block.go +++ b/core/corehttp/gateway_handler_block.go @@ -13,12 +13,12 @@ import ( func (i *gatewayHandler) serveRawBlock(w http.ResponseWriter, r *http.Request, blockCid cid.Cid, contentPath ipath.Path) { blockReader, err := i.api.Block().Get(r.Context(), contentPath) if err != nil { - webError(w, "failed to get block", err, http.StatusInternalServerError) + webError(w, "ipfs block get "+blockCid.String(), err, http.StatusInternalServerError) return } block, err := ioutil.ReadAll(blockReader) if err != nil { - webError(w, "failed to read block", err, http.StatusInternalServerError) + webError(w, "ipfs block get "+blockCid.String(), err, http.StatusInternalServerError) return } content := bytes.NewReader(block) diff --git a/core/corehttp/gateway_handler_car.go b/core/corehttp/gateway_handler_car.go index 5702e86b01a..30a90c5c801 100644 --- a/core/corehttp/gateway_handler_car.go +++ b/core/corehttp/gateway_handler_car.go @@ -45,6 +45,7 @@ func (i *gatewayHandler) serveCar(w http.ResponseWriter, r *http.Request, rootCi if err := car.Write(w); err != nil { // TODO: can we do any error handling here? + // TODO: idea: add best-effort proxy reader which will set http.StatusOK only if the first block is yielded correctly } }