...

Source file src/github.com/Shopify/go-storage/stats_wrapper.go

Documentation: github.com/Shopify/go-storage

     1  package storage
     2  
     3  import (
     4  	"context"
     5  	"expvar"
     6  	"io"
     7  )
     8  
     9  const (
    10  	StatOpenTotal    = "open.total"
    11  	StatOpenErrors   = "open.errors"
    12  	StatAttrsTotal   = "attrs.total"
    13  	StatAttrsErrors  = "attrs.errors"
    14  	StatCreateTotal  = "create.total"
    15  	StatCreateErrors = "create.errors"
    16  	StatDeleteTotal  = "delete.total"
    17  	StatDeleteErrors = "delete.errors"
    18  	StatURLTotal     = "url.total"
    19  	StatURLErrors    = "url.errors"
    20  )
    21  
    22  // NewStatsWrapper creates an FS which records accesses for an FS.
    23  // To retrieve the stats:
    24  // stats := expvar.Get(name).(*expvar.Map)
    25  // total := stats.Get("open.total").(*expvar.Int).Value() // int64
    26  func NewStatsWrapper(fs FS, name string) FS {
    27  	status := expvar.NewMap(name)
    28  	status.Set(StatOpenTotal, new(expvar.Int))
    29  	status.Set(StatOpenErrors, new(expvar.Int))
    30  
    31  	status.Set(StatAttrsTotal, new(expvar.Int))
    32  	status.Set(StatAttrsErrors, new(expvar.Int))
    33  
    34  	status.Set(StatCreateTotal, new(expvar.Int))
    35  	status.Set(StatCreateErrors, new(expvar.Int))
    36  
    37  	status.Set(StatDeleteTotal, new(expvar.Int))
    38  	status.Set(StatDeleteErrors, new(expvar.Int))
    39  
    40  	status.Set(StatURLTotal, new(expvar.Int))
    41  	status.Set(StatURLErrors, new(expvar.Int))
    42  
    43  	return &statsWrapper{
    44  		fs:     fs,
    45  		status: status,
    46  	}
    47  }
    48  
    49  // statsWrapper is an FS which records accesses for an FS.
    50  type statsWrapper struct {
    51  	fs     FS
    52  	status *expvar.Map
    53  }
    54  
    55  // Open implements FS.  All errors from Open are counted.
    56  func (s *statsWrapper) Open(ctx context.Context, path string, options *ReaderOptions) (*File, error) {
    57  	f, err := s.fs.Open(ctx, path, options)
    58  	if err != nil {
    59  		s.status.Add(StatOpenErrors, 1)
    60  	}
    61  	s.status.Add(StatOpenTotal, 1)
    62  
    63  	return f, err
    64  }
    65  
    66  // Attributes implements FS.  All errors from Attributes are counted.
    67  func (s *statsWrapper) Attributes(ctx context.Context, path string, options *ReaderOptions) (*Attributes, error) {
    68  	a, err := s.fs.Attributes(ctx, path, options)
    69  	if err != nil {
    70  		s.status.Add(StatAttrsErrors, 1)
    71  	}
    72  	s.status.Add(StatAttrsTotal, 1)
    73  
    74  	return a, err
    75  }
    76  
    77  // Create implements FS.  All errors from Create are counted.
    78  func (s *statsWrapper) Create(ctx context.Context, path string, options *WriterOptions) (io.WriteCloser, error) {
    79  	wc, err := s.fs.Create(ctx, path, options)
    80  	if err != nil {
    81  		s.status.Add(StatCreateErrors, 1)
    82  	}
    83  	s.status.Add(StatCreateTotal, 1)
    84  
    85  	return wc, err
    86  }
    87  
    88  // Delete implements FS.  All errors from Delete are counted.
    89  func (s *statsWrapper) Delete(ctx context.Context, path string) error {
    90  	err := s.fs.Delete(ctx, path)
    91  	if err != nil {
    92  		s.status.Add(StatDeleteErrors, 1)
    93  	}
    94  	s.status.Add(StatDeleteTotal, 1)
    95  
    96  	return err
    97  }
    98  
    99  // Walk implements FS.  No stats are recorded at this time.
   100  func (s *statsWrapper) Walk(ctx context.Context, path string, fn WalkFn) error {
   101  	return s.fs.Walk(ctx, path, fn)
   102  }
   103  
   104  func (s *statsWrapper) URL(ctx context.Context, path string, options *SignedURLOptions) (string, error) {
   105  	url, err := s.fs.URL(ctx, path, options)
   106  	if err != nil {
   107  		s.status.Add(StatURLErrors, 1)
   108  	}
   109  	s.status.Add(StatURLTotal, 1)
   110  
   111  	return url, err
   112  }
   113  

View as plain text