From 0b5c4a6a2ce21eb653c8fe25a4790a665fd0a559 Mon Sep 17 00:00:00 2001 From: Paddy Date: Tue, 16 Mar 2021 14:59:15 -0700 Subject: [PATCH] Accept TF_LOG=json to enable TRACE logs in JSON format This is not currently a supported interface, but we plan to release tool(s) that consume parts of it that are more dependable later, separately from Terraform CLI itself. --- internal/logging/logging.go | 20 ++++++++++++++------ website/docs/internals/debugging.html.md | 4 ++++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/internal/logging/logging.go b/internal/logging/logging.go index 6e2c948ad..11bdd4748 100644 --- a/internal/logging/logging.go +++ b/internal/logging/logging.go @@ -81,7 +81,7 @@ func HCLogger() hclog.Logger { // newHCLogger returns a new hclog.Logger instance with the given name func newHCLogger(name string) hclog.Logger { logOutput := io.Writer(os.Stderr) - logLevel := globalLogLevel() + logLevel, json := globalLogLevel() if logPath := os.Getenv(envLogFile); logPath != "" { f, err := os.OpenFile(logPath, syscall.O_CREAT|syscall.O_RDWR|syscall.O_APPEND, 0666) @@ -97,6 +97,7 @@ func newHCLogger(name string) hclog.Logger { Level: logLevel, Output: logOutput, IndependentLevels: true, + JSONFormat: json, }) } @@ -127,7 +128,8 @@ func NewProviderLogger(prefix string) hclog.Logger { // CurrentLogLevel returns the current log level string based the environment vars func CurrentLogLevel() string { - return strings.ToUpper(globalLogLevel().String()) + ll, _ := globalLogLevel() + return strings.ToUpper(ll.String()) } func providerLogLevel() hclog.Level { @@ -139,19 +141,25 @@ func providerLogLevel() hclog.Level { return parseLogLevel(providerEnvLevel) } -func globalLogLevel() hclog.Level { +func globalLogLevel() (hclog.Level, bool) { + var json bool envLevel := strings.ToUpper(os.Getenv(envLog)) if envLevel == "" { envLevel = strings.ToUpper(os.Getenv(envLogCore)) - } - return parseLogLevel(envLevel) + if envLevel == "JSON" { + json = true + } + return parseLogLevel(envLevel), json } func parseLogLevel(envLevel string) hclog.Level { if envLevel == "" { return hclog.Off } + if envLevel == "JSON" { + envLevel = "TRACE" + } logLevel := hclog.Trace if isValidLogLevel(envLevel) { @@ -166,7 +174,7 @@ func parseLogLevel(envLevel string) hclog.Level { // IsDebugOrHigher returns whether or not the current log level is debug or trace func IsDebugOrHigher() bool { - level := globalLogLevel() + level, _ := globalLogLevel() return level == hclog.Debug || level == hclog.Trace } diff --git a/website/docs/internals/debugging.html.md b/website/docs/internals/debugging.html.md index 6d41f13d3..b822f29d3 100644 --- a/website/docs/internals/debugging.html.md +++ b/website/docs/internals/debugging.html.md @@ -12,6 +12,10 @@ Terraform has detailed logs which can be enabled by setting the `TF_LOG` environ You can set `TF_LOG` to one of the log levels `TRACE`, `DEBUG`, `INFO`, `WARN` or `ERROR` to change the verbosity of the logs. +Setting `TF_LOG` to `JSON` outputs logs at the `TRACE` level or higher, and uses a parseable JSON encoding as the formatting. + +~> **Warning:** The JSON encoding of log files is not considered a stable interface. It may change at any time, without warning. It is meant to support tooling that will be forthcoming, and that tooling is the only supported way to interact with JSON formatted logs. + Logging can be enabled separately for terraform itself and the provider plugins using the `TF_LOG_CORE` or `TF_LOG_PROVIDER` environment variables. These take the same level arguments as `TF_LOG`, but only activate a subset of the logs.