github.com/heimweh/terraform@v0.7.4/helper/logging/logging.go (about) 1 package logging 2 3 import ( 4 "io" 5 "io/ioutil" 6 "log" 7 "os" 8 "strings" 9 10 "github.com/hashicorp/logutils" 11 ) 12 13 // These are the environmental variables that determine if we log, and if 14 // we log whether or not the log should go to a file. 15 const ( 16 EnvLog = "TF_LOG" // Set to True 17 EnvLogFile = "TF_LOG_PATH" // Set to a file 18 ) 19 20 var validLevels = []logutils.LogLevel{"TRACE", "DEBUG", "INFO", "WARN", "ERROR"} 21 22 // LogOutput determines where we should send logs (if anywhere) and the log level. 23 func LogOutput() (logOutput io.Writer, err error) { 24 logOutput = ioutil.Discard 25 26 logLevel := LogLevel() 27 if logLevel == "" { 28 return 29 } 30 31 logOutput = os.Stderr 32 if logPath := os.Getenv(EnvLogFile); logPath != "" { 33 var err error 34 logOutput, err = os.Create(logPath) 35 if err != nil { 36 return nil, err 37 } 38 } 39 40 // This was the default since the beginning 41 logOutput = &logutils.LevelFilter{ 42 Levels: validLevels, 43 MinLevel: logutils.LogLevel(logLevel), 44 Writer: logOutput, 45 } 46 47 return 48 } 49 50 // SetOutput checks for a log destination with LogOutput, and calls 51 // log.SetOutput with the result. If LogOutput returns nil, SetOutput uses 52 // ioutil.Discard. Any error from LogOutout is fatal. 53 func SetOutput() { 54 out, err := LogOutput() 55 if err != nil { 56 log.Fatal(err) 57 } 58 59 if out == nil { 60 out = ioutil.Discard 61 } 62 63 log.SetOutput(out) 64 } 65 66 // LogLevel returns the current log level string based the environment vars 67 func LogLevel() string { 68 envLevel := os.Getenv(EnvLog) 69 if envLevel == "" { 70 return "" 71 } 72 73 logLevel := "TRACE" 74 if isValidLogLevel(envLevel) { 75 // allow following for better ux: info, Info or INFO 76 logLevel = strings.ToUpper(envLevel) 77 } else { 78 log.Printf("[WARN] Invalid log level: %q. Defaulting to level: TRACE. Valid levels are: %+v", 79 envLevel, validLevels) 80 } 81 82 return logLevel 83 } 84 85 // IsDebugOrHigher returns whether or not the current log level is debug or trace 86 func IsDebugOrHigher() bool { 87 level := string(LogLevel()) 88 return level == "DEBUG" || level == "TRACE" 89 } 90 91 func isValidLogLevel(level string) bool { 92 for _, l := range validLevels { 93 if strings.ToUpper(level) == string(l) { 94 return true 95 } 96 } 97 98 return false 99 }