Terraformで出力ログレベルを変更するやり方の備忘録です。
- はじめに
- TerraformでDEBUGレベルのログを出力する
- TerraformとProviderで個別にログの出力レベルを設定する
- おまけ: Terraformのソースコードを読む
- おわりに
- 参考
*はじめに*
こんにちは、@bioerrorlogです。
不具合の切り分けをする際、ログは重要な情報源です。
そして十分な情報がログから得られない場合は、ログの出力レベルを上げてログ出力量を増やすのも有効です。
今回は、Terraformでログの出力レベルを変更する方法を備忘にまとめつつ、ついでにソースコードにも目を通してみます。
*TerraformでDEBUGレベルのログを出力する*
Terraformでログの出力レベルを変更するには、環境変数
を設定します。 TF_LOG
ドキュメントはこちら: Debugging | Terraform by HashiCorp
例えば
terraform planでDEBUGレベルのログを出力するには、環境変数
を TF_LOG
DEBUGに設定します。
# コマンド一回限りでTF_LOGを設定する場合 TF_LOG=DEBUG terraform plan # TF_LOGを設定した上でコマンド実行する場合 export TF_LOG=DEBUG terraform plan
TF_LOGに設定できるログレベルは下記の5つです。
必要な情報量に応じて使い分けましょう。
*TerraformとProviderで個別にログの出力レベルを設定する*
TerraformそのものとProviderで別々にログレベルを設定することもできます。
Terraformそのもののログレベルを設定するには環境変数
を、 TF_LOG_CORE
Providerのログレベルを設定するには環境変数
を利用します。 TF_LOG_PROVIDER
# TerraformそのもののログレベルをDEBUGに設定してplan実行 TF_LOG_CORE=DEBUG terraform plan # ProviderのログレベルをDEBUGに設定してplan実行 TF_LOG_PROVIDER=DEBUG terraform plan
TF_LOG_PROVIDERともに、設定できるレベルは
TF_LOGと同じです:
*おまけ: Terraformのソースコードを読む*
せっかくなので、Terraformのログレベルを設定している部分のソースコードにも目を通してみます。
// newHCLogger returns a new hclog.Logger instance with the given name func newHCLogger(name string) hclog.Logger { logOutput := io.Writer(os.Stderr) logLevel, json := globalLogLevel() if logPath := os.Getenv(envLogFile); logPath != "" { f, err := os.OpenFile(logPath, syscall.O_CREAT|syscall.O_RDWR|syscall.O_APPEND, 0666) if err != nil { fmt.Fprintf(os.Stderr, "Error opening log file: %v\n", err) } else { logOutput = f } } return hclog.NewInterceptLogger(&hclog.LoggerOptions{ Name: name, Level: logLevel, Output: logOutput, IndependentLevels: true, JSONFormat: json, }) } // NewLogger returns a new logger based in the current global logger, with the // given name appended. func NewLogger(name string) hclog.Logger { if name == "" { panic("logger name required") } return &logPanicWrapper{ Logger: logger.Named(name), } } // NewProviderLogger returns a logger for the provider plugin, possibly with a // different log level from the global logger. func NewProviderLogger(prefix string) hclog.Logger { l := &logPanicWrapper{ Logger: logger.Named(prefix + "provider"), } level := providerLogLevel() logger.Debug("created provider logger", "level", level) l.SetLevel(level) return l } // CurrentLogLevel returns the current log level string based the environment vars func CurrentLogLevel() string { ll, _ := globalLogLevel() return strings.ToUpper(ll.String()) } func providerLogLevel() hclog.Level { providerEnvLevel := strings.ToUpper(os.Getenv(envLogProvider)) if providerEnvLevel == "" { providerEnvLevel = strings.ToUpper(os.Getenv(envLog)) } return parseLogLevel(providerEnvLevel) } func globalLogLevel() (hclog.Level, bool) { var json bool envLevel := strings.ToUpper(os.Getenv(envLog)) if envLevel == "" { envLevel = strings.ToUpper(os.Getenv(envLogCore)) } if envLevel == "JSON" { json = true } return parseLogLevel(envLevel), json }
Globalなログレベルは
globalLogLevelで取得して
newHCLogger時に設定、Providerのログレベルは
providerLogLevelで取得して
NewProviderLoggerで設定されているのが分かります。
ログレベルとして受け取り可能な値はここで指定されています:
ちなみにログレベルの値の解釈時には
strings.ToUpperで包まれているので、大文字/小文字は影響ないようです。
*おわりに*
以上、Terraformで出力ログレベルを変更するやり方をまとめました。
ちょっと覚えておくだけでも対応スピードが上がるので、こういった引き出しも増やしていきたいものです。
[関連記事]
*参考*