diff --git a/config_unix.go b/config_unix.go index c51ea5ec4f..69d76278af 100644 --- a/config_unix.go +++ b/config_unix.go @@ -33,7 +33,7 @@ func configDir() (string, error) { func homeDir() (string, error) { // First prefer the HOME environmental variable if home := os.Getenv("HOME"); home != "" { - log.Printf("Detected home directory from env var: %s", home) + log.Printf("[DEBUG] Detected home directory from env var: %s", home) return home, nil } diff --git a/log.go b/log.go index 70046b3477..1077c3e558 100644 --- a/log.go +++ b/log.go @@ -2,28 +2,65 @@ package main import ( "io" + "log" "os" + "strings" + + "github.com/hashicorp/logutils" ) // These are the environmental variables that determine if we log, and if // we log whether or not the log should go to a file. -const EnvLog = "TF_LOG" //Set to True -const EnvLogFile = "TF_LOG_PATH" //Set to a file +const ( + EnvLog = "TF_LOG" // Set to True + EnvLogFile = "TF_LOG_PATH" // Set to a file +) -// logOutput determines where we should send logs (if anywhere). +var validLevels = []logutils.LogLevel{"TRACE", "DEBUG", "INFO", "WARN", "ERROR"} + +// logOutput determines where we should send logs (if anywhere) and the log level. func logOutput() (logOutput io.Writer, err error) { logOutput = nil - if os.Getenv(EnvLog) != "" { - logOutput = os.Stderr + envLevel := os.Getenv(EnvLog) + if envLevel == "" { + return + } - if logPath := os.Getenv(EnvLogFile); logPath != "" { - var err error - logOutput, err = os.Create(logPath) - if err != nil { - return nil, err - } + logOutput = os.Stderr + if logPath := os.Getenv(EnvLogFile); logPath != "" { + var err error + logOutput, err = os.Create(logPath) + if err != nil { + return nil, err } } + // This was the default since the beginning + logLevel := logutils.LogLevel("TRACE") + + if isValidLogLevel(envLevel) { + // allow following for better ux: info, Info or INFO + logLevel = logutils.LogLevel(strings.ToUpper(envLevel)) + } else { + log.Printf("[WARN] Invalid log level: %q. Defaulting to level: TRACE. Valid levels are: %+v", + envLevel, validLevels) + } + + logOutput = &logutils.LevelFilter{ + Levels: validLevels, + MinLevel: logLevel, + Writer: logOutput, + } + return } + +func isValidLogLevel(level string) bool { + for _, l := range validLevels { + if strings.ToUpper(level) == string(l) { + return true + } + } + + return false +} diff --git a/plugin/client.go b/plugin/client.go index be54526c73..8a3b03fc0a 100644 --- a/plugin/client.go +++ b/plugin/client.go @@ -88,7 +88,7 @@ func CleanupClients() { }(client) } - log.Println("waiting for all plugin processes to complete...") + log.Println("[DEBUG] waiting for all plugin processes to complete...") wg.Wait() } @@ -326,7 +326,7 @@ func (c *Client) logStderr(r io.Reader) { c.config.Stderr.Write([]byte(line)) line = strings.TrimRightFunc(line, unicode.IsSpace) - log.Printf("%s: %s", filepath.Base(c.config.Cmd.Path), line) + log.Printf("[DEBUG] %s: %s", filepath.Base(c.config.Cmd.Path), line) } if err == io.EOF { diff --git a/terraform/context.go b/terraform/context.go index 0f567ddf24..d91a851765 100644 --- a/terraform/context.go +++ b/terraform/context.go @@ -513,7 +513,7 @@ func (c *Context) releaseRun(ch chan<- struct{}) { func (c *Context) walk( graph *Graph, operation walkOperation) (*ContextGraphWalker, error) { // Walk the graph - log.Printf("[INFO] Starting graph walk: %s", operation.String()) + log.Printf("[DEBUG] Starting graph walk: %s", operation.String()) walker := &ContextGraphWalker{Context: c, Operation: operation} return walker, graph.Walk(walker) } diff --git a/terraform/eval_validate.go b/terraform/eval_validate.go index e808240a02..5337882305 100644 --- a/terraform/eval_validate.go +++ b/terraform/eval_validate.go @@ -49,9 +49,12 @@ func (n *EvalValidateCount) Eval(ctx EvalContext) (interface{}, error) { } RETURN: - return nil, &EvalValidateError{ - Errors: errs, + if len(errs) != 0 { + err = &EvalValidateError{ + Errors: errs, + } } + return nil, err } // EvalValidateProvider is an EvalNode implementation that validates