7
7
"fmt"
8
8
"net/http"
9
9
"regexp"
10
+ "strconv"
10
11
11
12
"github.com/go-kit/log"
12
13
"github.com/prometheus/client_golang/prometheus"
46
47
ErrUnsupportedStorageBackend = errors .New ("unsupported storage backend" )
47
48
ErrInvalidCharactersInStoragePrefix = errors .New ("storage prefix contains invalid characters, it may only contain digits and English alphabet letters" )
48
49
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
+ )
50
61
)
51
62
63
+ func init () {
64
+ prometheus .MustRegister (bucketRequestsTotal )
65
+ metrics = objstore .BucketMetrics (prometheus .WrapRegistererWithPrefix ("loki_" , prometheus .DefaultRegisterer ), "" )
66
+ }
67
+
52
68
// StorageBackendConfig holds configuration for accessing long-term storage.
53
69
type StorageBackendConfig struct {
54
70
// Backends
@@ -176,13 +192,13 @@ func NewClient(ctx context.Context, backend string, cfg Config, name string, log
176
192
// TODO: add support for other backends that loki already supports
177
193
switch backend {
178
194
case S3 :
179
- client , err = s3 .NewBucketClient (cfg .S3 , name , logger )
195
+ client , err = s3 .NewBucketClient (cfg .S3 , name , logger , instrumentTransport () )
180
196
case GCS :
181
- client , err = gcs .NewBucketClient (ctx , cfg .GCS , name , logger )
197
+ client , err = gcs .NewBucketClient (ctx , cfg .GCS , name , logger , instrumentTransport () )
182
198
case Azure :
183
- client , err = azure .NewBucketClient (cfg .Azure , name , logger )
199
+ client , err = azure .NewBucketClient (cfg .Azure , name , logger , instrumentTransport () )
184
200
case Swift :
185
- client , err = swift .NewBucketClient (cfg .Swift , name , logger )
201
+ client , err = swift .NewBucketClient (cfg .Swift , name , logger , instrumentTransport () )
186
202
case Filesystem :
187
203
client , err = filesystem .NewBucketClient (cfg .Filesystem )
188
204
default :
@@ -209,3 +225,24 @@ func NewClient(ctx context.Context, backend string, cfg Config, name string, log
209
225
210
226
return instrumentedClient , nil
211
227
}
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