code.cloudfoundry.org/cli@v7.1.0+incompatible/util/ui/request_logger_file_writer.go (about)

     1  package ui
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  	"regexp"
     8  	"sync"
     9  	"time"
    10  )
    11  
    12  type RequestLoggerFileWriter struct {
    13  	ui            *UI
    14  	lock          *sync.Mutex
    15  	filePaths     []string
    16  	logFiles      []*os.File
    17  	dumpSanitizer *regexp.Regexp
    18  }
    19  
    20  func newRequestLoggerFileWriter(ui *UI, lock *sync.Mutex, filePaths []string) *RequestLoggerFileWriter {
    21  	return &RequestLoggerFileWriter{
    22  		ui:            ui,
    23  		lock:          lock,
    24  		filePaths:     filePaths,
    25  		logFiles:      []*os.File{},
    26  		dumpSanitizer: regexp.MustCompile(tokenRegexp),
    27  	}
    28  }
    29  
    30  func (display *RequestLoggerFileWriter) DisplayBody([]byte) error {
    31  	for _, logFile := range display.logFiles {
    32  		_, err := logFile.WriteString(RedactedValue)
    33  		if err != nil {
    34  			return err
    35  		}
    36  	}
    37  	return nil
    38  }
    39  
    40  func (display *RequestLoggerFileWriter) DisplayDump(dump string) error {
    41  	sanitized := display.dumpSanitizer.ReplaceAllString(dump, RedactedValue)
    42  	cookieCutter := regexp.MustCompile("Set-Cookie:.*")
    43  	sanitized = cookieCutter.ReplaceAllString(sanitized, "Set-Cookie: "+RedactedValue)
    44  	for _, logFile := range display.logFiles {
    45  		_, err := logFile.WriteString(sanitized)
    46  		if err != nil {
    47  			return err
    48  		}
    49  	}
    50  	return nil
    51  }
    52  
    53  func (display *RequestLoggerFileWriter) DisplayHeader(name string, value string) error {
    54  	return display.DisplayMessage(fmt.Sprintf("%s: %s", name, value))
    55  }
    56  
    57  func (display *RequestLoggerFileWriter) DisplayHost(name string) error {
    58  	return display.DisplayMessage(fmt.Sprintf("Host: %s", name))
    59  }
    60  
    61  func (display *RequestLoggerFileWriter) DisplayJSONBody(body []byte) error {
    62  	if len(body) == 0 {
    63  		return nil
    64  	}
    65  
    66  	sanitized, err := SanitizeJSON(body)
    67  	if err != nil {
    68  		return display.DisplayMessage(string(body))
    69  	}
    70  
    71  	for _, logFile := range display.logFiles {
    72  		_, err = logFile.Write(sanitized)
    73  		if err != nil {
    74  			return err
    75  		}
    76  	}
    77  	return nil
    78  }
    79  
    80  func (display *RequestLoggerFileWriter) DisplayMessage(msg string) error {
    81  	for _, logFile := range display.logFiles {
    82  		_, err := logFile.WriteString(fmt.Sprintf("%s\n", msg))
    83  		if err != nil {
    84  			return err
    85  		}
    86  	}
    87  	return nil
    88  }
    89  
    90  func (display *RequestLoggerFileWriter) DisplayRequestHeader(method string, uri string, httpProtocol string) error {
    91  	return display.DisplayMessage(fmt.Sprintf("%s %s %s", method, uri, httpProtocol))
    92  }
    93  
    94  func (display *RequestLoggerFileWriter) DisplayResponseHeader(httpProtocol string, status string) error {
    95  	return display.DisplayMessage(fmt.Sprintf("%s %s", httpProtocol, status))
    96  }
    97  
    98  func (display *RequestLoggerFileWriter) DisplayType(name string, requestDate time.Time) error {
    99  	return display.DisplayMessage(fmt.Sprintf("%s: [%s]", name, requestDate.Format(time.RFC3339)))
   100  }
   101  
   102  func (display *RequestLoggerFileWriter) HandleInternalError(err error) {
   103  	display.ui.DisplayWarning(err.Error())
   104  }
   105  
   106  func (display *RequestLoggerFileWriter) Start() error {
   107  	display.lock.Lock()
   108  	for _, filePath := range display.filePaths {
   109  		err := os.MkdirAll(filepath.Dir(filePath), os.ModeDir|os.ModePerm)
   110  		if err != nil {
   111  			return err
   112  		}
   113  
   114  		logFile, err := os.OpenFile(filePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
   115  		if err != nil {
   116  			return err
   117  		}
   118  
   119  		display.logFiles = append(display.logFiles, logFile)
   120  	}
   121  	return nil
   122  }
   123  
   124  func (display *RequestLoggerFileWriter) Stop() error {
   125  	var err error
   126  
   127  	for _, logFile := range display.logFiles {
   128  		_, lastLineErr := logFile.WriteString("\n")
   129  		closeErr := logFile.Close()
   130  		switch {
   131  		case closeErr != nil:
   132  			err = closeErr
   133  		case lastLineErr != nil:
   134  			err = lastLineErr
   135  		}
   136  	}
   137  	display.logFiles = []*os.File{}
   138  	display.lock.Unlock()
   139  	return err
   140  }
   141  
   142  // RequestLoggerFileWriter returns a RequestLoggerFileWriter that cannot
   143  // overwrite another RequestLoggerFileWriter.
   144  func (ui *UI) RequestLoggerFileWriter(filePaths []string) *RequestLoggerFileWriter {
   145  	return newRequestLoggerFileWriter(ui, ui.fileLock, filePaths)
   146  }