LCOV - code coverage report
Current view: top level - pebble/objstorage/remote - logging.go (source / functions) Hit Total Coverage
Test: 2024-02-29 08:15Z 7531ef4d - tests + meta.lcov Lines: 68 81 84.0 %
Date: 2024-02-29 08:16:37 Functions: 0 0 -

          Line data    Source code
       1             : // Copyright 2023 The LevelDB-Go and Pebble Authors. All rights reserved. Use
       2             : // of this source code is governed by a BSD-style license that can be found in
       3             : // the LICENSE file.
       4             : 
       5             : package remote
       6             : 
       7             : import (
       8             :         "context"
       9             :         "fmt"
      10             :         "io"
      11             :         "sort"
      12             : )
      13             : 
      14             : // WithLogging wraps the given Storage implementation and emits logs for various
      15             : // operations.
      16           1 : func WithLogging(wrapped Storage, logf func(fmt string, args ...interface{})) Storage {
      17           1 :         return &loggingStore{
      18           1 :                 logf:    logf,
      19           1 :                 wrapped: wrapped,
      20           1 :         }
      21           1 : }
      22             : 
      23             : // loggingStore wraps a remote.Storage implementation and emits logs of the
      24             : // operations.
      25             : type loggingStore struct {
      26             :         logf    func(fmt string, args ...interface{})
      27             :         wrapped Storage
      28             : }
      29             : 
      30             : var _ Storage = (*loggingStore)(nil)
      31             : 
      32           0 : func (l *loggingStore) Close() error {
      33           0 :         l.logf("close")
      34           0 :         return l.wrapped.Close()
      35           0 : }
      36             : 
      37             : func (l *loggingStore) ReadObject(
      38             :         ctx context.Context, objName string,
      39           1 : ) (_ ObjectReader, objSize int64, _ error) {
      40           1 :         r, size, err := l.wrapped.ReadObject(ctx, objName)
      41           1 :         l.logf("create reader for object %q: %s", objName, errOrPrintf(err, "%d bytes", size))
      42           1 :         if err != nil {
      43           0 :                 return nil, 0, err
      44           0 :         }
      45           1 :         return &loggingReader{
      46           1 :                 l:       l,
      47           1 :                 name:    objName,
      48           1 :                 wrapped: r,
      49           1 :         }, size, nil
      50             : }
      51             : 
      52             : type loggingReader struct {
      53             :         l       *loggingStore
      54             :         name    string
      55             :         wrapped ObjectReader
      56             : }
      57             : 
      58             : var _ ObjectReader = (*loggingReader)(nil)
      59             : 
      60           1 : func (l *loggingReader) ReadAt(ctx context.Context, p []byte, offset int64) error {
      61           1 :         if err := l.wrapped.ReadAt(ctx, p, offset); err != nil {
      62           0 :                 l.l.logf("read object %q at %d (length %d): error %v", l.name, offset, len(p), err)
      63           0 :                 return err
      64           0 :         }
      65           1 :         l.l.logf("read object %q at %d (length %d)", l.name, offset, len(p))
      66           1 :         return nil
      67             : }
      68             : 
      69           1 : func (l *loggingReader) Close() error {
      70           1 :         l.l.logf("close reader for %q", l.name)
      71           1 :         return l.wrapped.Close()
      72           1 : }
      73             : 
      74           1 : func (l *loggingStore) CreateObject(objName string) (io.WriteCloser, error) {
      75           1 :         l.logf("create object %q", objName)
      76           1 :         writer, err := l.wrapped.CreateObject(objName)
      77           1 :         if err != nil {
      78           0 :                 return nil, err
      79           0 :         }
      80           1 :         return &loggingWriter{
      81           1 :                 l:           l,
      82           1 :                 name:        objName,
      83           1 :                 WriteCloser: writer,
      84           1 :         }, nil
      85             : }
      86             : 
      87             : type loggingWriter struct {
      88             :         l            *loggingStore
      89             :         name         string
      90             :         bytesWritten int64
      91             :         io.WriteCloser
      92             : }
      93             : 
      94           1 : func (l *loggingWriter) Write(p []byte) (n int, err error) {
      95           1 :         n, err = l.WriteCloser.Write(p)
      96           1 :         l.bytesWritten += int64(n)
      97           1 :         return n, err
      98           1 : }
      99             : 
     100           1 : func (l *loggingWriter) Close() error {
     101           1 :         l.l.logf("close writer for %q after %d bytes", l.name, l.bytesWritten)
     102           1 :         return l.WriteCloser.Close()
     103           1 : }
     104             : 
     105           1 : func (l *loggingStore) List(prefix, delimiter string) ([]string, error) {
     106           1 :         l.logf("list (prefix=%q, delimiter=%q)", prefix, delimiter)
     107           1 :         res, err := l.wrapped.List(prefix, delimiter)
     108           1 :         if err != nil {
     109           0 :                 return nil, err
     110           0 :         }
     111           1 :         sorted := append([]string(nil), res...)
     112           1 :         sort.Strings(sorted)
     113           1 :         for _, s := range sorted {
     114           1 :                 l.logf(" - %s", s)
     115           1 :         }
     116           1 :         return res, nil
     117             : }
     118             : 
     119           1 : func (l *loggingStore) Delete(objName string) error {
     120           1 :         l.logf("delete object %q", objName)
     121           1 :         return l.wrapped.Delete(objName)
     122           1 : }
     123             : 
     124           1 : func (l *loggingStore) Size(objName string) (int64, error) {
     125           1 :         size, err := l.wrapped.Size(objName)
     126           1 :         l.logf("size of object %q: %s", objName, errOrPrintf(err, "%d", size))
     127           1 :         return size, err
     128           1 : }
     129             : 
     130           1 : func errOrPrintf(err error, format string, args ...interface{}) string {
     131           1 :         if err != nil {
     132           1 :                 return fmt.Sprintf("error: %v", err)
     133           1 :         }
     134           1 :         return fmt.Sprintf(format, args...)
     135             : }
     136             : 
     137           1 : func (l *loggingStore) IsNotExistError(err error) bool {
     138           1 :         return l.wrapped.IsNotExistError(err)
     139           1 : }

Generated by: LCOV version 1.14