github.com/nathanielks/terraform@v0.6.1-0.20170509030759-13e1a62319dc/helper/logging/logging.go (about)

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