Name: v.Bucket,
},
}
+ // Set up prometheus metrics
+ lbls := prometheus.Labels{"device_id": v.DeviceID()}
+ v.bucket.stats.opsCounters = opsCounters.MustCurryWith(lbls)
+ v.bucket.stats.errCounters = errCounters.MustCurryWith(lbls)
+ v.bucket.stats.ioBytes = ioBytes.MustCurryWith(lbls)
+
return nil
}
}
func (lister *s3Lister) getPage() {
+ lister.Stats.TickOps("list")
lister.Stats.Tick(&lister.Stats.Ops, &lister.Stats.ListOps)
resp, err := lister.Bucket.List(lister.Prefix, "", lister.nextMarker, lister.PageSize)
lister.nextMarker = ""
func (b *s3bucket) GetReader(path string) (io.ReadCloser, error) {
rdr, err := b.Bucket.GetReader(path)
+ b.stats.TickOps("get")
b.stats.Tick(&b.stats.Ops, &b.stats.GetOps)
b.stats.TickErr(err)
- return NewCountingReader(rdr, b.stats.TickInBytes), err
+ return NewCountingReader(
+ rdr,
+ func(c uint64) {
+ b.stats.CountBytesIn(c)
+ b.stats.TickInBytes(c)
+ }), err
}
func (b *s3bucket) Head(path string, headers map[string][]string) (*http.Response, error) {
resp, err := b.Bucket.Head(path, headers)
+ b.stats.TickOps("head")
b.stats.Tick(&b.stats.Ops, &b.stats.HeadOps)
b.stats.TickErr(err)
return resp, err
// empty objects.
r = nil
} else {
- r = NewCountingReader(r, b.stats.TickOutBytes)
+ r = NewCountingReader(
+ r,
+ func(c uint64) {
+ b.stats.CountBytesOut(c)
+ b.stats.TickOutBytes(c)
+ })
}
err := b.Bucket.PutReader(path, r, length, contType, perm, options)
+ b.stats.TickOps("put")
b.stats.Tick(&b.stats.Ops, &b.stats.PutOps)
b.stats.TickErr(err)
return err
func (b *s3bucket) Del(path string) error {
err := b.Bucket.Del(path)
+ b.stats.TickOps("delete")
b.stats.Tick(&b.stats.Ops, &b.stats.DelOps)
b.stats.TickErr(err)
return err
HeadOps uint64
DelOps uint64
ListOps uint64
+
+ opsCounters *prometheus.CounterVec
+ errCounters *prometheus.CounterVec
+ ioBytes *prometheus.CounterVec
}
func (s *s3bucketStats) TickErr(err error) {
if err, ok := err.(*s3.Error); ok {
errType = errType + fmt.Sprintf(" %d %s", err.StatusCode, err.Code)
}
+ if s.errCounters != nil {
+ s.errCounters.With(prometheus.Labels{"error_type": errType}).Inc()
+ }
s.statsTicker.TickErr(err, errType)
}
+
+func (s *s3bucketStats) TickOps(operations ...string) {
+ if s.opsCounters == nil {
+ return
+ }
+ for _, opType := range operations {
+ s.opsCounters.With(prometheus.Labels{"operation": opType}).Inc()
+ }
+}
+
+func (s *s3bucketStats) CountBytesIn(b uint64) {
+ s.countBytes("in", float64(b))
+}
+
+func (s *s3bucketStats) CountBytesOut(b uint64) {
+ s.countBytes("out", float64(b))
+}
+
+func (s *s3bucketStats) countBytes(direction string, bytes float64) {
+ if s.ioBytes == nil {
+ return
+ }
+ s.ioBytes.With(prometheus.Labels{"direction": direction}).Add(bytes)
+}