bsClient *azureBlobClient
}
-// azureBlobClient wraps storage.BlobStorageClient in order to count
-// I/O and API usage stats.
-type azureBlobClient struct {
- client *storage.BlobStorageClient
- stats azureBlobStats
-}
-
-type azureBlobStats struct {
- statsTicker
- Ops uint64
- GetOps uint64
- GetRangeOps uint64
- CreateOps uint64
- SetMetadataOps uint64
- DelOps uint64
- ListOps uint64
-
- lock sync.Mutex
-}
-
// Examples implements VolumeWithExamples.
func (*AzureBlobVolume) Examples() []Volume {
return []Volume{
return &v.bsClient.stats
}
+type azureBlobStats struct {
+ statsTicker
+ Ops uint64
+ GetOps uint64
+ GetRangeOps uint64
+ CreateOps uint64
+ SetMetadataOps uint64
+ DelOps uint64
+ ListOps uint64
+}
+
+func (s *azureBlobStats) TickErr(err error) {
+ if err == nil {
+ return
+ }
+ errType := fmt.Sprintf("%T", err)
+ if err, ok := err.(storage.AzureStorageServiceError); ok {
+ errType = errType + fmt.Sprintf(" %d (%s)", err.StatusCode, err.Code)
+ }
+ log.Printf("errType %T, err %s", err, err)
+ s.statsTicker.TickErr(err, errType)
+}
+
+// azureBlobClient wraps storage.BlobStorageClient in order to count
+// I/O and API usage stats.
+type azureBlobClient struct {
+ client *storage.BlobStorageClient
+ stats azureBlobStats
+}
+
func (c *azureBlobClient) ContainerExists(cname string) (bool, error) {
c.stats.Tick(&c.stats.Ops)
ok, err := c.client.ContainerExists(cname)
}
gotHash := fmt.Sprintf("%x", md5.Sum(gotData))
if gotLen != size {
- t.Error("length mismatch: got %d != %d", gotLen, size)
+ t.Errorf("length mismatch: got %d != %d", gotLen, size)
}
if gotHash != hash {
- t.Error("hash mismatch: got %s != %s", gotHash, hash)
+ t.Errorf("hash mismatch: got %s != %s", gotHash, hash)
}
}
}
c.Check(err, check.NotNil)
c.Check(stats(), check.Matches, `.*"Ops":[^0],.*`)
c.Check(stats(), check.Matches, `.*"Errors":[^0],.*`)
+ c.Check(stats(), check.Matches, `.*"storage\.AzureStorageServiceError 404 \(404 Not Found\)":[^0].*`)
c.Check(stats(), check.Matches, `.*"InBytes":0,.*`)
err = s.volume.Put(context.Background(), loc, []byte("foo"))
func (b *s3bucket) GetReader(path string) (io.ReadCloser, error) {
rdr, err := b.Bucket.GetReader(path)
b.stats.Tick(&b.stats.Ops, &b.stats.GetOps)
- b.stats.tickErr(err)
+ b.stats.TickErr(err)
return NewCountingReader(rdr, b.stats.TickInBytes), err
}
func (b *s3bucket) Head(path string, headers map[string][]string) (*http.Response, error) {
resp, err := b.Bucket.Head(path, headers)
b.stats.Tick(&b.stats.Ops, &b.stats.HeadOps)
- b.stats.tickErr(err)
+ b.stats.TickErr(err)
return resp, err
}
func (b *s3bucket) PutReader(path string, r io.Reader, length int64, contType string, perm s3.ACL, options s3.Options) error {
err := b.Bucket.PutReader(path, NewCountingReader(r, b.stats.TickOutBytes), length, contType, perm, options)
b.stats.Tick(&b.stats.Ops, &b.stats.PutOps)
- b.stats.tickErr(err)
+ b.stats.TickErr(err)
return err
}
func (b *s3bucket) Put(path string, data []byte, contType string, perm s3.ACL, options s3.Options) error {
err := b.Bucket.PutReader(path, NewCountingReader(bytes.NewBuffer(data), b.stats.TickOutBytes), int64(len(data)), contType, perm, options)
b.stats.Tick(&b.stats.Ops, &b.stats.PutOps)
- b.stats.tickErr(err)
+ b.stats.TickErr(err)
return err
}
func (b *s3bucket) Del(path string) error {
err := b.Bucket.Del(path)
b.stats.Tick(&b.stats.Ops, &b.stats.DelOps)
- b.stats.tickErr(err)
+ b.stats.TickErr(err)
return err
}
HeadOps uint64
DelOps uint64
ListOps uint64
-
- ErrorCodes map[string]uint64 `json:",omitempty"`
-
- lock sync.Mutex
}
-func (s *s3bucketStats) tickErr(err error) {
+func (s *s3bucketStats) TickErr(err error) {
if err == nil {
return
}
- s.TickErr(err)
- errStr := fmt.Sprintf("%T", err)
+ errType := fmt.Sprintf("%T", err)
if err, ok := err.(*s3.Error); ok {
- errStr = errStr + fmt.Sprintf(" %d %s", err.StatusCode, err.Code)
- }
- s.lock.Lock()
- if s.ErrorCodes == nil {
- s.ErrorCodes = make(map[string]uint64)
+ errType = errType + fmt.Sprintf(" %d %s", err.StatusCode, err.Code)
}
- s.ErrorCodes[errStr]++
- s.lock.Unlock()
+ s.statsTicker.TickErr(err, errType)
}
package main
import (
+ "sync"
"sync/atomic"
)
Errors uint64
InBytes uint64
OutBytes uint64
+
+ ErrorCodes map[string]uint64 `json:",omitempty"`
+ lock sync.Mutex
}
// Tick increments each of the given counters by 1 using
}
}
-func (s *statsTicker) TickErr(err error) {
+func (s *statsTicker) TickErr(err error, errType string) {
if err == nil {
return
}
s.Tick(&s.Errors)
+
+ s.lock.Lock()
+ if s.ErrorCodes == nil {
+ s.ErrorCodes = make(map[string]uint64)
+ }
+ s.ErrorCodes[errType]++
+ s.lock.Unlock()
}
func (s *statsTicker) TickInBytes(n uint64) {