Skip to content

Commit

Permalink
Logging to file
Browse files Browse the repository at this point in the history
- Consul-like CLI flags used to control the behaviour of the feature
- `log_file` configuration stanza
- updated docs for CLI and config

Fixes hashicorp#1416

Signed-off-by: Alessandro De Blasis <alex@deblasis.net>
  • Loading branch information
deblasis committed Nov 12, 2021
1 parent a1e9af8 commit a3eb778
Show file tree
Hide file tree
Showing 11 changed files with 758 additions and 8 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,15 @@ this functionality might prove useful.
- [Math Functions](docs/templating-language.md#math-functions)
- [Observability](docs/observability.md)
- [Logging](docs/observability.md#logging)
- [Logging to file](docs/observability.md#logging-to-file)
- [Modes](docs/modes.md)
- [Once Mode](docs/modes.md#once-mode)
- [De-Duplication Mode](docs/modes.md#de-duplication-mode)
- [Exec Mode](docs/modes.md#exec-mode)
- [Plugins](docs/plugins.md)
- [Caveats](#caveats)
- [Docker Image Use](#docker-image-use)
- [Dots in Service Names](#dots-in-service-names)
- [Dots in Service Names](#dots-in-service-names)
- [Termination on Error](#termination-on-error)
- [Commands](#commands)
- [Environment](#environment)
Expand Down Expand Up @@ -235,7 +236,7 @@ users the ability to further customize their command script.
#### Multiple Commands

The command configured for running on template rendering must take one of two
forms.
forms.

The first is as a single command without spaces in its name and no arguments.
This form of command will be called directly by consul-template and is good for
Expand Down
34 changes: 29 additions & 5 deletions cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,26 @@ func (cli *CLI) ParseFlags(args []string) (
return nil
}), "log-level", "")

flags.Var((funcVar)(func(s string) error {
c.FileLog.LogFilePath = config.String(s)
return nil
}), "log-file", "")

flags.Var((funcIntVar)(func(i int) error {
c.FileLog.LogRotateBytes = config.Int(i)
return nil
}), "log-rotate-bytes", "")

flags.Var((funcDurationVar)(func(d time.Duration) error {
c.FileLog.LogRotateDuration = config.TimeDuration(d)
return nil
}), "log-rotate-duration", "")

flags.Var((funcIntVar)(func(i int) error {
c.FileLog.LogRotateMaxFiles = config.Int(i)
return nil
}), "log-rotate-max-files", "")

flags.Var((funcDurationVar)(func(d time.Duration) error {
c.MaxStale = config.TimeDuration(d)
return nil
Expand Down Expand Up @@ -605,11 +625,15 @@ func logError(err error, status int) int {

func (cli *CLI) setup(conf *config.Config) (*config.Config, error) {
if err := logging.Setup(&logging.Config{
Level: config.StringVal(conf.LogLevel),
Syslog: config.BoolVal(conf.Syslog.Enabled),
SyslogFacility: config.StringVal(conf.Syslog.Facility),
SyslogName: config.StringVal(conf.Syslog.Name),
Writer: cli.errStream,
Level: config.StringVal(conf.LogLevel),
LogFilePath: config.StringVal(conf.FileLog.LogFilePath),
LogRotateBytes: config.IntVal(conf.FileLog.LogRotateBytes),
LogRotateDuration: config.TimeDurationVal(conf.FileLog.LogRotateDuration),
LogRotateMaxFiles: config.IntVal(conf.FileLog.LogRotateMaxFiles),
Syslog: config.BoolVal(conf.Syslog.Enabled),
SyslogFacility: config.StringVal(conf.Syslog.Facility),
SyslogName: config.StringVal(conf.Syslog.Name),
Writer: cli.errStream,
}); err != nil {
return nil, err
}
Expand Down
40 changes: 40 additions & 0 deletions cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,46 @@ func TestCLI_ParseFlags(t *testing.T) {
},
false,
},
{
"log-file",
[]string{"-log-file", "something.log"},
&config.Config{
FileLog: &config.LogFileConfig{
LogFilePath: config.String("something.log"),
},
},
false,
},
{
"log-rotate-bytes",
[]string{"-log-rotate-bytes", "102400"},
&config.Config{
FileLog: &config.LogFileConfig{
LogRotateBytes: config.Int(102400),
},
},
false,
},
{
"log-rotate-duration",
[]string{"-log-rotate-duration", "24h"},
&config.Config{
FileLog: &config.LogFileConfig{
LogRotateDuration: config.TimeDuration(24 * time.Hour),
},
},
false,
},
{
"log-rotate-max-files",
[]string{"-log-rotate-max-files", "10"},
&config.Config{
FileLog: &config.LogFileConfig{
LogRotateMaxFiles: config.Int(10),
},
},
false,
},
{
"max-stale",
[]string{"-max-stale", "10s"},
Expand Down
20 changes: 20 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ type Config struct {
// LogLevel is the level with which to log for this config.
LogLevel *string `mapstructure:"log_level"`

// FileLog is the configuration for file logging.
FileLog *LogFileConfig `mapstructure:"log_file"`

// MaxStale is the maximum amount of time for staleness from Consul as given
// by LastContact. If supplied, Consul Template will query all servers instead
// of just the leader.
Expand Down Expand Up @@ -131,6 +134,10 @@ func (c *Config) Copy() *Config {

o.ReloadSignal = c.ReloadSignal

if c.FileLog != nil {
o.FileLog = c.FileLog.Copy()
}

if c.Syslog != nil {
o.Syslog = c.Syslog.Copy()
}
Expand Down Expand Up @@ -206,6 +213,10 @@ func (c *Config) Merge(o *Config) *Config {
r.ReloadSignal = o.ReloadSignal
}

if o.FileLog != nil {
r.FileLog = r.FileLog.Merge(o.FileLog)
}

if o.Syslog != nil {
r.Syslog = r.Syslog.Merge(o.Syslog)
}
Expand Down Expand Up @@ -256,6 +267,7 @@ func Parse(s string) (*Config, error) {
"env",
"exec",
"exec.env",
"log_file",
"ssl",
"syslog",
"vault",
Expand Down Expand Up @@ -414,6 +426,7 @@ func (c *Config) GoString() string {
"MaxStale:%s, "+
"PidFile:%s, "+
"ReloadSignal:%s, "+
"FileLog:%#v, "+
"Syslog:%#v, "+
"Templates:%#v, "+
"Vault:%#v, "+
Expand All @@ -430,6 +443,7 @@ func (c *Config) GoString() string {
TimeDurationGoString(c.MaxStale),
StringGoString(c.PidFile),
SignalGoString(c.ReloadSignal),
c.FileLog,
c.Syslog,
c.Templates,
c.Vault,
Expand Down Expand Up @@ -474,6 +488,7 @@ func DefaultConfig() *Config {
Dedup: DefaultDedupConfig(),
DefaultDelims: DefaultDefaultDelims(),
Exec: DefaultExecConfig(),
FileLog: DefaultLogFileConfig(),
Syslog: DefaultSyslogConfig(),
Templates: DefaultTemplateConfigs(),
Vault: DefaultVaultConfig(),
Expand Down Expand Up @@ -533,6 +548,11 @@ func (c *Config) Finalize() {
c.ReloadSignal = Signal(DefaultReloadSignal)
}

if c.FileLog == nil {
c.FileLog = DefaultLogFileConfig()
}
c.FileLog.Finalize()

if c.Syslog == nil {
c.Syslog = DefaultSyslogConfig()
}
Expand Down
86 changes: 86 additions & 0 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,74 @@ func TestParse(t *testing.T) {
},
false,
},
{
"log_file",
`log_file {}`,
&Config{
FileLog: &LogFileConfig{},
},
false,
},
{
"log_file_path",
`log_file {
path = "something.log"
}`,
&Config{
FileLog: &LogFileConfig{
LogFilePath: String("something.log"),
},
},
false,
},
{
"log_file_path_no_filename",
`log_file {
path = "./logs"
}`,
&Config{
FileLog: &LogFileConfig{
LogFilePath: String("./logs"),
},
},
false,
},
{
"log_file_log_rotate_bytes",
`log_file {
log_rotate_bytes = 102400
}`,
&Config{
FileLog: &LogFileConfig{
LogRotateBytes: Int(102400),
},
},
false,
},
{
"log_file_log_rotate_duration",
`log_file {
log_rotate_duration = "24h"
}`,
&Config{
FileLog: &LogFileConfig{
LogRotateDuration: TimeDuration(24 * time.Hour),
},
},
false,
},
{
"log_file_log_rotate_max_files",
`log_file {
log_rotate_max_files = 10
}`,
&Config{
FileLog: &LogFileConfig{
LogRotateMaxFiles: Int(10),
},
},
false,
},
{
"max_stale",
`max_stale = "10s"`,
Expand Down Expand Up @@ -1783,6 +1851,24 @@ func TestConfig_Merge(t *testing.T) {
LogLevel: String("log_level-diff"),
},
},
{
"file_log",
&Config{
FileLog: &LogFileConfig{
LogFilePath: String("something.log"),
},
},
&Config{
FileLog: &LogFileConfig{
LogFilePath: String("somethingelse.log"),
},
},
&Config{
FileLog: &LogFileConfig{
LogFilePath: String("somethingelse.log"),
},
},
},
{
"max_stale",
&Config{
Expand Down
Loading

0 comments on commit a3eb778

Please sign in to comment.