TF_LOG_CORE is ignored if TF_LOG is set
Terraform Version
current main branch
Terraform Configuration Files
TF_LOG=JSON
TF_LOG_CORE=ERROR
TF_LOG_PROVIDER=INFO
JSON logs with configurable log-level.
Debug Output
{"@level":"trace","@message":"Completed graph transform *terraform.DestroyEdgeTransformer (no changes)","@timestamp":"..."}
{"@level":"trace","@message":"Executing graph transform *terraform.CBDEdgeTransformer","@timestamp":"..."}
{"@level":"trace","@message":"Completed graph transform *terraform.CBDEdgeTransformer (no changes)","@timestamp":".."}
{"@level":"trace","@message":"Executing graph transform *terraform.pruneUnusedNodesTransformer","@timestamp":"..."}
{"@level":"debug","@message":"pruneUnusedNodes: REDACTED (expand) is no longer needed, removing","@timestamp":"..."}
megabytes of trace logs
Expected Behavior
TF_LOG=JSON variable setting output to be json, since there is no other way of doing that.
Then, more specific configs like TF_LOG_CORE or TF_LOG_PROVIDER should take precedence over global TF_LOG, and overwrite log levels.
Terraform is silent unless an error happens, and providers stream [INFO] level logs ``
Actual Behavior
Full [TRACE] mode.
Steps to Reproduce
set logs levels as following: (or any non-trace value)
TF_LOG=JSON
TF_LOG_CORE=ERROR
TF_LOG_PROVIDER=INFO
Additional Context
No response
References
https://github.com/hashicorp/terraform/blob/aa680aad84ecef089b3177e39099ba47816fedbe/internal/logging/logging.go#L171-L181
cab be replaced with something like:
func globalLogLevel() (level hclog.Level, json bool) {
// set TF_LOG as default
envLevel := strings.ToUpper(os.Getenv(envLog))
json = envLevel == "JSON"
level = parseLogLevel(envLevel) // defaults to TRACE
// overwrite with more specific TF_LOG_CORE
if envLevel = strings.ToUpper(os.Getenv(envLogCore)); envLevel != "" {
level = parseLogLevel(envLevel)
}
return level, json
}
Hi @ubombi! Thanks for reporting this.
I think the situation is a little different than you described it, but your request is still valid.
Terraform effectively treats the log level json as meaning "trace but in JSON format". You can set TF_LOG_CORE=json to get just the Terraform Core logs as "trace but in JSON format".
What you cannot do, and what I think you are asking for, is request logs in JSON format while selecting a log level other than trace. Is that right?
Assuming that's a correct interpretation of your goal, I think a more direct way to solve it would be to introduce a syntax which separates the log level decision from the formatting decision. For example, we could say that if the environment variable value contains one colon then the part before the colon is the level and the part after the colon is the format.
Then in your example you might set the variables like this:
TF_LOG_CORE=ERROR:JSON
TF_LOG_PROVIDER=INFO:JSON
# TF_LOG not set at all, because that means to set the level and format for both of them at once
I think it's also reasonable to say that TF_LOG_CORE and TF_LOG_PROVIDER should override TF_LOG when both are present, since those are indeed more specific, but I'd prefer the more specific ones to override the less specific ones entirely, rather than having a special case where we'd take the format selection from TF_LOG while only overriding the level.
In other words, TF_LOG_CORE=ERROR would always mean "core's error logs in human-oriented format", regardless of what TF_LOG is set to, and you'd need to set TF_LOG_CORE=ERROR:JSON if you want core's error logs in JSON format.