Repository: ipfs/boxo (language: go)

Issue:
gateway: add metric for implicit `index.html` 
Ref. https://github.com/ipfs/go-libipfs/blob/1c6ed2e96f7753a3452607e2a429311a31099cf4/gateway/handler.go#L244-L253

We track (histograms):
-  `gw_unixfs_file_get_duration_seconds`  (files) and
-   `gw_unixfs_gen_dir_listing_get_duration_seconds` (generated html dir listings). 

We are missing a metric that tracks the case where request was for a directory with index.html. It is necessary to see how popular this use case is, and if we should introduce optimizations to avoid round trips for `index.html`. 

## Proposed change

Add new histogram ([here?](https://github.com/ipfs/go-libipfs/blob/1c6ed2e96f7753a3452607e2a429311a31099cf4/gateway/handler_unixfs_dir.go#L78-L80) for tracking how long it took to find and load `index.html` when a dir path was requested:

-   `gw_unixfs_dir_index-html_get_duration_seconds`  




Discussion / hints:

Fix patch:
diff --git a/gateway/handler.go b/gateway/handler.go
index a4716e2db..c923c3c13 100644
--- a/gateway/handler.go
+++ b/gateway/handler.go
@@ -74,14 +74,15 @@ type handler struct {
 	unixfsGetMetric            *prometheus.SummaryVec // deprecated, use firstContentBlockGetMetric
 
 	// response type metrics
-	getMetric                 *prometheus.HistogramVec
-	unixfsFileGetMetric       *prometheus.HistogramVec
-	unixfsGenDirGetMetric     *prometheus.HistogramVec
-	carStreamGetMetric        *prometheus.HistogramVec
-	rawBlockGetMetric         *prometheus.HistogramVec
-	tarStreamGetMetric        *prometheus.HistogramVec
-	jsoncborDocumentGetMetric *prometheus.HistogramVec
-	ipnsRecordGetMetric       *prometheus.HistogramVec
+	getMetric                    *prometheus.HistogramVec
+	unixfsFileGetMetric          *prometheus.HistogramVec
+	unixfsDirIndexGetMetric      *prometheus.HistogramVec
+	unixfsGenDirListingGetMetric *prometheus.HistogramVec
+	carStreamGetMetric           *prometheus.HistogramVec
+	rawBlockGetMetric            *prometheus.HistogramVec
+	tarStreamGetMetric           *prometheus.HistogramVec
+	jsoncborDocumentGetMetric    *prometheus.HistogramVec
+	ipnsRecordGetMetric          *prometheus.HistogramVec
 }
 
 // StatusResponseWriter enables us to override HTTP Status Code passed to
@@ -246,8 +247,13 @@ func newHandler(c Config, api API) *handler {
 			"gw_unixfs_file_get_duration_seconds",
 			"The time to serve an entire UnixFS file from the gateway.",
 		),
+		// UnixFS: time it takes to find and serve an index.html file on behalf of a directory.
+		unixfsDirIndexGetMetric: newHistogramMetric(
+			"gw_unixfs_dir_indexhtml_get_duration_seconds",
+			"The time to serve an index.html file on behalf of a directory from the gateway. This is a subset of gw_unixfs_file_get_duration_seconds.",
+		),
 		// UnixFS: time it takes to generate static HTML with directory listing
-		unixfsGenDirGetMetric: newHistogramMetric(
+		unixfsGenDirListingGetMetric: newHistogramMetric(
 			"gw_unixfs_gen_dir_listing_get_duration_seconds",
 			"The time to serve a generated UnixFS HTML directory listing from the gateway.",
 		),
diff --git a/gateway/handler_unixfs_dir.go b/gateway/handler_unixfs_dir.go
index b0ad107e5..6caa3f171 100644
--- a/gateway/handler_unixfs_dir.go
+++ b/gateway/handler_unixfs_dir.go
@@ -77,7 +77,11 @@ func (i *handler) serveDirectory(ctx context.Context, w http.ResponseWriter, r *
 
 		logger.Debugw("serving index.html file", "path", idxPath)
 		// write to request
-		return i.serveFile(ctx, w, r, resolvedPath, idxPath, f, begin)
+		success := i.serveFile(ctx, w, r, resolvedPath, idxPath, f, begin)
+		if success {
+			i.unixfsDirIndexGetMetric.WithLabelValues(contentPath.Namespace()).Observe(time.Since(begin).Seconds())
+		}
+		return success
 	case resolver.ErrNoLink:
 		logger.Debugw("no index.html; noop", "path", idxPath)
 	default:
@@ -198,7 +202,7 @@ func (i *handler) serveDirectory(ctx context.Context, w http.ResponseWriter, r *
 	}
 
 	// Update metrics
-	i.unixfsGenDirGetMetric.WithLabelValues(contentPath.Namespace()).Observe(time.Since(begin).Seconds())
+	i.unixfsGenDirListingGetMetric.WithLabelValues(contentPath.Namespace()).Observe(time.Since(begin).Seconds())
 	return true
 }
 


Test patch: