diff options
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/helper/logging')
-rw-r--r-- | vendor/github.com/hashicorp/terraform/helper/logging/logging.go | 100 | ||||
-rw-r--r-- | vendor/github.com/hashicorp/terraform/helper/logging/transport.go | 53 |
2 files changed, 153 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/helper/logging/logging.go b/vendor/github.com/hashicorp/terraform/helper/logging/logging.go new file mode 100644 index 0000000..433cd77 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/helper/logging/logging.go | |||
@@ -0,0 +1,100 @@ | |||
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 | } | ||
diff --git a/vendor/github.com/hashicorp/terraform/helper/logging/transport.go b/vendor/github.com/hashicorp/terraform/helper/logging/transport.go new file mode 100644 index 0000000..4477924 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/helper/logging/transport.go | |||
@@ -0,0 +1,53 @@ | |||
1 | package logging | ||
2 | |||
3 | import ( | ||
4 | "log" | ||
5 | "net/http" | ||
6 | "net/http/httputil" | ||
7 | ) | ||
8 | |||
9 | type transport struct { | ||
10 | name string | ||
11 | transport http.RoundTripper | ||
12 | } | ||
13 | |||
14 | func (t *transport) RoundTrip(req *http.Request) (*http.Response, error) { | ||
15 | if IsDebugOrHigher() { | ||
16 | reqData, err := httputil.DumpRequestOut(req, true) | ||
17 | if err == nil { | ||
18 | log.Printf("[DEBUG] "+logReqMsg, t.name, string(reqData)) | ||
19 | } else { | ||
20 | log.Printf("[ERROR] %s API Request error: %#v", t.name, err) | ||
21 | } | ||
22 | } | ||
23 | |||
24 | resp, err := t.transport.RoundTrip(req) | ||
25 | if err != nil { | ||
26 | return resp, err | ||
27 | } | ||
28 | |||
29 | if IsDebugOrHigher() { | ||
30 | respData, err := httputil.DumpResponse(resp, true) | ||
31 | if err == nil { | ||
32 | log.Printf("[DEBUG] "+logRespMsg, t.name, string(respData)) | ||
33 | } else { | ||
34 | log.Printf("[ERROR] %s API Response error: %#v", t.name, err) | ||
35 | } | ||
36 | } | ||
37 | |||
38 | return resp, nil | ||
39 | } | ||
40 | |||
41 | func NewTransport(name string, t http.RoundTripper) *transport { | ||
42 | return &transport{name, t} | ||
43 | } | ||
44 | |||
45 | const logReqMsg = `%s API Request Details: | ||
46 | ---[ REQUEST ]--------------------------------------- | ||
47 | %s | ||
48 | -----------------------------------------------------` | ||
49 | |||
50 | const logRespMsg = `%s API Response Details: | ||
51 | ---[ RESPONSE ]-------------------------------------- | ||
52 | %s | ||
53 | -----------------------------------------------------` | ||