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 }