@@ -128,6 +128,7 @@ type Handler struct {
128128
129129 writeSamplesTotal * prometheus.HistogramVec
130130 writeTimeseriesTotal * prometheus.HistogramVec
131+ writeE2eLatency * prometheus.HistogramVec
131132
132133 Limiter * Limiter
133134}
@@ -208,6 +209,15 @@ func NewHandler(logger log.Logger, o *Options) *Handler {
208209 Buckets : []float64 {10 , 50 , 100 , 500 , 1000 , 5000 , 10000 },
209210 }, []string {"code" , "tenant" },
210211 ),
212+ writeE2eLatency : promauto .With (registerer ).NewHistogramVec (
213+ prometheus.HistogramOpts {
214+ Namespace : "thanos" ,
215+ Subsystem : "receive" ,
216+ Name : "write_e2e_latency_seconds" ,
217+ Help : "The end-to-end latency of the oldest sample in write requests." ,
218+ Buckets : []float64 {0.01 , 0.05 , 0.1 , 0.25 , 0.5 , 0.75 , 1.0 , 2.0 , 3.0 , 4.0 , 5.0 , 7.0 , 9.0 , 11.0 , 13.0 , 15.0 , 17.0 , 19.0 , 21.0 , 23.0 , 25.0 , 27.0 , 29.0 , 30.0 },
219+ }, []string {"code" , "tenant" },
220+ ),
211221 }
212222
213223 h .forwardRequests .WithLabelValues (labelSuccess )
@@ -462,6 +472,17 @@ func newWriteResponse(seriesIDs []int, err error, er endpointReplica) writeRespo
462472 }
463473}
464474
475+ func secondsSinceOldestSample (ts prompb.TimeSeries ) float64 {
476+ now := time .Now ().UnixNano () / int64 (time .Millisecond )
477+ oldestTs := now
478+ for _ , s := range ts .Samples {
479+ if s .Timestamp < oldestTs {
480+ oldestTs = s .Timestamp
481+ }
482+ }
483+ return float64 (now - oldestTs ) / 1000
484+ }
485+
465486func (h * Handler ) receiveHTTP (w http.ResponseWriter , r * http.Request ) {
466487 var err error
467488 span , ctx := tracing .StartSpan (r .Context (), "receive_http" )
@@ -606,6 +627,11 @@ func (h *Handler) receiveHTTP(w http.ResponseWriter, r *http.Request) {
606627 h .writeTimeseriesTotal .WithLabelValues (strconv .Itoa (responseStatusCode ), tenant ).Observe (float64 (stats .timeseries ))
607628 h .writeSamplesTotal .WithLabelValues (strconv .Itoa (responseStatusCode ), tenant ).Observe (float64 (stats .totalSamples ))
608629 }
630+ for _ , ts := range wreq .Timeseries {
631+ if lat := secondsSinceOldestSample (ts ); lat > 0 {
632+ h .writeE2eLatency .WithLabelValues (strconv .Itoa (responseStatusCode ), tenantHTTP ).Observe (secondsSinceOldestSample (ts ))
633+ }
634+ }
609635}
610636
611637type requestStats struct {
0 commit comments