1package hclog 2 3import ( 4 "bytes" 5 "strings" 6) 7 8// Provides a io.Writer to shim the data out of *log.Logger 9// and back into our Logger. This is basically the only way to 10// build upon *log.Logger. 11type stdlogAdapter struct { 12 log Logger 13 inferLevels bool 14 forceLevel Level 15} 16 17// Take the data, infer the levels if configured, and send it through 18// a regular Logger. 19func (s *stdlogAdapter) Write(data []byte) (int, error) { 20 str := string(bytes.TrimRight(data, " \t\n")) 21 22 if s.forceLevel != NoLevel { 23 // Use pickLevel to strip log levels included in the line since we are 24 // forcing the level 25 _, str := s.pickLevel(str) 26 27 // Log at the forced level 28 switch s.forceLevel { 29 case Trace: 30 s.log.Trace(str) 31 case Debug: 32 s.log.Debug(str) 33 case Info: 34 s.log.Info(str) 35 case Warn: 36 s.log.Warn(str) 37 case Error: 38 s.log.Error(str) 39 default: 40 s.log.Info(str) 41 } 42 } else if s.inferLevels { 43 level, str := s.pickLevel(str) 44 switch level { 45 case Trace: 46 s.log.Trace(str) 47 case Debug: 48 s.log.Debug(str) 49 case Info: 50 s.log.Info(str) 51 case Warn: 52 s.log.Warn(str) 53 case Error: 54 s.log.Error(str) 55 default: 56 s.log.Info(str) 57 } 58 } else { 59 s.log.Info(str) 60 } 61 62 return len(data), nil 63} 64 65// Detect, based on conventions, what log level this is. 66func (s *stdlogAdapter) pickLevel(str string) (Level, string) { 67 switch { 68 case strings.HasPrefix(str, "[DEBUG]"): 69 return Debug, strings.TrimSpace(str[7:]) 70 case strings.HasPrefix(str, "[TRACE]"): 71 return Trace, strings.TrimSpace(str[7:]) 72 case strings.HasPrefix(str, "[INFO]"): 73 return Info, strings.TrimSpace(str[6:]) 74 case strings.HasPrefix(str, "[WARN]"): 75 return Warn, strings.TrimSpace(str[7:]) 76 case strings.HasPrefix(str, "[ERROR]"): 77 return Error, strings.TrimSpace(str[7:]) 78 case strings.HasPrefix(str, "[ERR]"): 79 return Error, strings.TrimSpace(str[5:]) 80 default: 81 return Info, str 82 } 83} 84