github.com/aavshr/aws-sdk-go@v1.41.3/example/service/s3/loggingUploadObjectReadBehavior/main.go (about)

     1  //go:build example
     2  // +build example
     3  
     4  package main
     5  
     6  import (
     7  	"fmt"
     8  	"io"
     9  	"log"
    10  	"os"
    11  	"runtime/debug"
    12  
    13  	"github.com/aavshr/aws-sdk-go/aws/request"
    14  	"github.com/aavshr/aws-sdk-go/aws/session"
    15  	"github.com/aavshr/aws-sdk-go/service/s3/s3manager"
    16  )
    17  
    18  // Usage:
    19  //   go run -tags example  <bucket> <key> <file to upload>
    20  //
    21  // Example:
    22  //   AWS_REGION=us-west-2 AWS_PROFILE=default go run . "mybucket" "10MB.file" ./10MB.file
    23  func main() {
    24  	sess, err := session.NewSession()
    25  	if err != nil {
    26  		log.Fatalf("failed to load session, %v", err)
    27  	}
    28  
    29  	uploader := s3manager.NewUploader(sess)
    30  
    31  	file, err := os.Open(os.Args[3])
    32  	if err != nil {
    33  		log.Fatalf("failed to open file, %v", err)
    34  	}
    35  	defer file.Close()
    36  
    37  	// Wrap the readSeeker with a logger that will log usage, and stack traces
    38  	// on errors.
    39  	readLogger := NewReadLogger(file, sess.Config.Logger)
    40  
    41  	// Upload with read logger
    42  	resp, err := uploader.Upload(&s3manager.UploadInput{
    43  		Bucket: &os.Args[1],
    44  		Key:    &os.Args[2],
    45  		Body:   readLogger,
    46  	}, func(u *s3manager.Uploader) {
    47  		u.Concurrency = 1
    48  		u.RequestOptions = append(u.RequestOptions, func(r *request.Request) {
    49  		})
    50  	})
    51  
    52  	fmt.Println(resp, err)
    53  }
    54  
    55  // Logger is a logger use for logging the readers usage.
    56  type Logger interface {
    57  	Log(args ...interface{})
    58  }
    59  
    60  // ReadSeeker interface provides the interface for a Reader, Seeker, and ReadAt.
    61  type ReadSeeker interface {
    62  	io.ReadSeeker
    63  	io.ReaderAt
    64  }
    65  
    66  // ReadLogger wraps an reader with logging for access.
    67  type ReadLogger struct {
    68  	reader ReadSeeker
    69  	logger Logger
    70  }
    71  
    72  // NewReadLogger a ReadLogger that wraps the passed in ReadSeeker (Reader,
    73  // Seeker, ReadAt) with a logger.
    74  func NewReadLogger(r ReadSeeker, logger Logger) *ReadLogger {
    75  	return &ReadLogger{
    76  		reader: r,
    77  		logger: logger,
    78  	}
    79  }
    80  
    81  // Seek offsets the reader's current position for the next read.
    82  func (s *ReadLogger) Seek(offset int64, mode int) (int64, error) {
    83  	newOffset, err := s.reader.Seek(offset, mode)
    84  	msg := fmt.Sprintf(
    85  		"ReadLogger.Seek(offset:%d, mode:%d) (newOffset:%d, err:%v)",
    86  		offset, mode, newOffset, err)
    87  	if err != nil {
    88  		msg += fmt.Sprintf("\n\tStack:\n%s", string(debug.Stack()))
    89  	}
    90  
    91  	s.logger.Log(msg)
    92  	return newOffset, err
    93  }
    94  
    95  // Read attempts to read from the reader, returning the bytes read, or error.
    96  func (s *ReadLogger) Read(b []byte) (int, error) {
    97  	n, err := s.reader.Read(b)
    98  	msg := fmt.Sprintf(
    99  		"ReadLogger.Read(len(bytes):%d) (read:%d, err:%v)",
   100  		len(b), n, err)
   101  	if err != nil {
   102  		msg += fmt.Sprintf("\n\tStack:\n%s", string(debug.Stack()))
   103  	}
   104  
   105  	s.logger.Log(msg)
   106  	return n, err
   107  }
   108  
   109  // ReadAt will read the underlying reader starting at the offset.
   110  func (s *ReadLogger) ReadAt(b []byte, offset int64) (int, error) {
   111  	n, err := s.reader.ReadAt(b, offset)
   112  	msg := fmt.Sprintf(
   113  		"ReadLogger.ReadAt(len(bytes):%d, offset:%d) (read:%d, err:%v)",
   114  		len(b), offset, n, err)
   115  	if err != nil {
   116  		msg += fmt.Sprintf("\n\tStack:\n%s", string(debug.Stack()))
   117  	}
   118  
   119  	s.logger.Log(msg)
   120  	return n, err
   121  }