77 "fmt"
88 "net/http"
99 "regexp"
10+ "strconv"
1011
1112 "github.com/go-kit/log"
1213 "github.com/prometheus/client_golang/prometheus"
4647 ErrUnsupportedStorageBackend = errors .New ("unsupported storage backend" )
4748 ErrInvalidCharactersInStoragePrefix = errors .New ("storage prefix contains invalid characters, it may only contain digits and English alphabet letters" )
4849
49- metrics = objstore .BucketMetrics (prometheus .WrapRegistererWithPrefix ("loki_" , prometheus .DefaultRegisterer ), "" )
50+ metrics * objstore.Metrics
51+
52+ // added to track the status codes by method
53+ bucketRequestsTotal = prometheus .NewCounterVec (
54+ prometheus.CounterOpts {
55+ Namespace : "loki" ,
56+ Name : "objstore_bucket_transport_requests_total" ,
57+ Help : "Total number of HTTP transport requests made to the bucket backend by status code and method." ,
58+ },
59+ []string {"status_code" , "method" },
60+ )
5061)
5162
63+ func init () {
64+ prometheus .MustRegister (bucketRequestsTotal )
65+ metrics = objstore .BucketMetrics (prometheus .WrapRegistererWithPrefix ("loki_" , prometheus .DefaultRegisterer ), "" )
66+ }
67+
5268// StorageBackendConfig holds configuration for accessing long-term storage.
5369type StorageBackendConfig struct {
5470 // Backends
@@ -176,13 +192,13 @@ func NewClient(ctx context.Context, backend string, cfg Config, name string, log
176192 // TODO: add support for other backends that loki already supports
177193 switch backend {
178194 case S3 :
179- client , err = s3 .NewBucketClient (cfg .S3 , name , logger )
195+ client , err = s3 .NewBucketClient (cfg .S3 , name , logger , instrumentTransport () )
180196 case GCS :
181- client , err = gcs .NewBucketClient (ctx , cfg .GCS , name , logger )
197+ client , err = gcs .NewBucketClient (ctx , cfg .GCS , name , logger , instrumentTransport () )
182198 case Azure :
183- client , err = azure .NewBucketClient (cfg .Azure , name , logger )
199+ client , err = azure .NewBucketClient (cfg .Azure , name , logger , instrumentTransport () )
184200 case Swift :
185- client , err = swift .NewBucketClient (cfg .Swift , name , logger )
201+ client , err = swift .NewBucketClient (cfg .Swift , name , logger , instrumentTransport () )
186202 case Filesystem :
187203 client , err = filesystem .NewBucketClient (cfg .Filesystem )
188204 default :
@@ -209,3 +225,24 @@ func NewClient(ctx context.Context, backend string, cfg Config, name string, log
209225
210226 return instrumentedClient , nil
211227}
228+
229+ type instrumentedRoundTripper struct {
230+ next http.RoundTripper
231+ }
232+
233+ func instrumentTransport () func (http.RoundTripper ) http.RoundTripper {
234+ return func (rt http.RoundTripper ) http.RoundTripper {
235+ return & instrumentedRoundTripper {next : rt }
236+ }
237+ }
238+
239+ func (i * instrumentedRoundTripper ) RoundTrip (req * http.Request ) (* http.Response , error ) {
240+ resp , err := i .next .RoundTrip (req )
241+ if err != nil {
242+ return resp , err
243+ }
244+
245+ // Record status code and method metrics
246+ bucketRequestsTotal .WithLabelValues (strconv .Itoa (resp .StatusCode ), req .Method ).Inc ()
247+ return resp , nil
248+ }
0 commit comments