github.com/cloudfoundry/libcfbuildpack@v1.91.23/logger/logger.go (about) 1 /* 2 * Copyright 2018-2020 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * https://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package logger 18 19 import ( 20 "fmt" 21 "regexp" 22 "strings" 23 24 "github.com/buildpack/libbuildpack/logger" 25 "github.com/fatih/color" 26 ) 27 28 const ( 29 BodyIndent = " " 30 HeaderIndent = " " 31 32 indent = " " 33 ) 34 35 var ( 36 description = color.New(color.FgBlue) 37 error = color.New(color.FgRed, color.Bold) 38 errorName = color.New(color.FgRed, color.Bold) 39 errorDescription = color.New(color.FgRed) 40 lines = regexp.MustCompile(`(?m)^`) 41 name = color.New(color.FgBlue, color.Bold) 42 warning = color.New(color.FgYellow, color.Bold) 43 44 errorEyeCatcher string 45 firstLineEyeCatcher string 46 warningEyeCatcher string 47 ) 48 49 func init() { 50 color.NoColor = false 51 errorEyeCatcher = error.Sprint("----->") 52 firstLineEyeCatcher = color.New(color.FgRed, color.Bold).Sprint("----->") 53 warningEyeCatcher = warning.Sprint("----->") 54 } 55 56 // Logger is an extension to libbuildpack.Logger to add additional functionality. 57 type Logger struct { 58 logger.Logger 59 } 60 61 // Title prints the buildpack description flush left, with an empty line above it. 62 func (l Logger) Title(v Identifiable) { 63 if !l.IsInfoEnabled() { 64 return 65 } 66 67 l.Info("\n%s", l.prettyIdentity(v, name, description)) 68 } 69 70 // Terminal error prints the build description colored red and bold, flush left, with an empty line above it, followed 71 // by the log message message red and bold, and indented two spaces. 72 func (l Logger) TerminalError(v Identifiable, format string, args ...interface{}) { 73 if !l.IsInfoEnabled() { 74 return 75 } 76 77 l.Info("\n%s", l.prettyIdentity(v, errorName, errorDescription)) 78 l.HeaderError(format, args...) 79 } 80 81 // Header prints the log message indented two spaces, with an empty line above it. 82 func (l Logger) Header(format string, args ...interface{}) { 83 if !l.IsInfoEnabled() { 84 return 85 } 86 87 l.Info("%s%s", HeaderIndent, fmt.Sprintf(format, args...)) 88 } 89 90 // HeaderError prints the log message colored red and bold, indented two spaces, with an empty line above it. 91 func (l Logger) HeaderError(format string, args ...interface{}) { 92 if !l.IsInfoEnabled() { 93 return 94 } 95 96 l.Header(error.Sprintf(format, args...)) 97 } 98 99 // HeaderWarning prints the log message colored yellow and bold, indented two spaces, with an empty line above it. 100 func (l Logger) HeaderWarning(format string, args ...interface{}) { 101 if !l.IsInfoEnabled() { 102 return 103 } 104 105 l.Header(warning.Sprintf(format, args...)) 106 } 107 108 // Body prints the log message with each line indented four spaces. 109 func (l Logger) Body(format string, args ...interface{}) { 110 if !l.IsInfoEnabled() { 111 return 112 } 113 114 l.Info(color.New(color.Faint).Sprint( 115 strings.ReplaceAll( 116 l.BodyIndent(format, args...), 117 fmt.Sprintf("\x1b[%dm", color.Reset), 118 fmt.Sprintf("\x1b[%dm\x1b[%dm", color.Reset, color.Faint)))) 119 } 120 121 // BodyError prints the log message colored red and bold with each line indented four spaces. 122 func (l Logger) BodyError(format string, args ...interface{}) { 123 if !l.IsInfoEnabled() { 124 return 125 } 126 127 l.Body(error.Sprintf(format, args...)) 128 } 129 130 // BodyIndent indents each line of a log message to the BodyIndent offset. 131 func (l Logger) BodyIndent(format string, args ...interface{}) string { 132 return lines.ReplaceAllString(fmt.Sprintf(format, args...), BodyIndent) 133 } 134 135 // BodyWarning prints the log message colored yellow and bold with each line indented four spaces. 136 func (l Logger) BodyWarning(format string, args ...interface{}) { 137 if !l.IsInfoEnabled() { 138 return 139 } 140 141 l.Body(warning.Sprintf(format, args...)) 142 } 143 144 func (l Logger) LaunchConfiguration(format string, defaultValue string) { 145 l.Body("%s. Default %s", format, color.New(color.Italic).Sprint(defaultValue)) 146 } 147 148 func (l Logger) prettyIdentity(v Identifiable, nameColor *color.Color, descriptionColor *color.Color) string { 149 if v == nil { 150 return "" 151 } 152 153 name, description := v.Identity() 154 155 if description == "" { 156 return nameColor.Sprint(name) 157 } 158 159 return fmt.Sprintf("%s %s", nameColor.Sprint(name), descriptionColor.Sprint(description)) 160 } 161 162 // PrettyIdentity formats a standard pretty identity of a type. 163 // 164 // Deprecated: Use Title 165 func (l Logger) PrettyIdentity(v Identifiable) string { 166 if v == nil { 167 return "" 168 } 169 170 n, d := v.Identity() 171 172 if d == "" { 173 return name.Sprint(n) 174 } 175 176 return fmt.Sprintf("%s %s", name.Sprint(n), description.Sprint(description)) 177 } 178 179 // Error prints the log message with the error eye catcher. 180 // 181 // Deprecated: Use HeaderError or BodyError 182 func (l Logger) Error(format string, args ...interface{}) { 183 if !l.IsInfoEnabled() { 184 return 185 } 186 187 l.Info("%s %s", errorEyeCatcher, fmt.Sprintf(format, args...)) 188 } 189 190 // FirstLine prints the log messages with the first line eye catcher. 191 // 192 // Deprecated: Use Title 193 func (l Logger) FirstLine(format string, args ...interface{}) { 194 if !l.IsInfoEnabled() { 195 return 196 } 197 198 l.Info("%s %s", firstLineEyeCatcher, fmt.Sprintf(format, args...)) 199 } 200 201 // SubsequentLine prints log message with the subsequent line indent. 202 // 203 // Deprecated: Use Body 204 func (l Logger) SubsequentLine(format string, args ...interface{}) { 205 if !l.IsInfoEnabled() { 206 return 207 } 208 209 l.Info("%s %s", indent, fmt.Sprintf(format, args...)) 210 } 211 212 // Warning prints the log message with the warning eye catcher. 213 // 214 // Deprecated: Use HeaderWarning or BodyWarning 215 func (l Logger) Warning(format string, args ...interface{}) { 216 if !l.IsInfoEnabled() { 217 return 218 } 219 220 l.Info("%s %s", warningEyeCatcher, fmt.Sprintf(format, args...)) 221 }