diff --git a/command/agent/agent.go b/command/agent/agent.go index b9ecbd0f4..ec4d356ca 100644 --- a/command/agent/agent.go +++ b/command/agent/agent.go @@ -87,7 +87,7 @@ type Agent struct { } // NewAgent is used to create a new agent with the given configuration -func NewAgent(config *Config, logOutput io.Writer, inmem *metrics.InmemSink) (*Agent, error) { +func NewAgent(config *Config, logger log.Logger, logOutput io.Writer, inmem *metrics.InmemSink) (*Agent, error) { a := &Agent{ config: config, logOutput: logOutput, @@ -96,12 +96,7 @@ func NewAgent(config *Config, logOutput io.Writer, inmem *metrics.InmemSink) (*A } // Create the loggers - a.logger = log.New(&log.LoggerOptions{ - Name: "agent", - Level: log.LevelFromString(config.LogLevel), - Output: logOutput, - JSONFormat: config.LogJson, - }) + a.logger = logger a.httpLogger = a.logger.ResetNamed("http") // Global logger should match internal logger as much as possible diff --git a/command/agent/command.go b/command/agent/command.go index 47da7e272..a1658eb50 100644 --- a/command/agent/command.go +++ b/command/agent/command.go @@ -15,18 +15,20 @@ import ( "syscall" "time" - metrics "github.com/armon/go-metrics" + "github.com/armon/go-metrics" "github.com/armon/go-metrics/circonus" "github.com/armon/go-metrics/datadog" "github.com/armon/go-metrics/prometheus" "github.com/hashicorp/consul/lib" - checkpoint "github.com/hashicorp/go-checkpoint" - discover "github.com/hashicorp/go-discover" + "github.com/hashicorp/go-checkpoint" + "github.com/hashicorp/go-discover" + "github.com/hashicorp/go-hclog" gsyslog "github.com/hashicorp/go-syslog" "github.com/hashicorp/logutils" "github.com/hashicorp/nomad/helper" flaghelper "github.com/hashicorp/nomad/helper/flag-helpers" gatedwriter "github.com/hashicorp/nomad/helper/gated-writer" + "github.com/hashicorp/nomad/helper/logging" "github.com/hashicorp/nomad/nomad/structs/config" "github.com/hashicorp/nomad/version" "github.com/mitchellh/cli" @@ -402,9 +404,9 @@ func (c *Command) setupLoggers(config *Config) (*gatedwriter.Writer, *logWriter, } // setupAgent is used to start the agent and various interfaces -func (c *Command) setupAgent(config *Config, logOutput io.Writer, inmem *metrics.InmemSink) error { +func (c *Command) setupAgent(config *Config, logger hclog.Logger, logOutput io.Writer, inmem *metrics.InmemSink) error { c.Ui.Output("Starting Nomad agent...") - agent, err := NewAgent(config, logOutput, inmem) + agent, err := NewAgent(config, logger, logOutput, inmem) if err != nil { c.Ui.Error(fmt.Sprintf("Error starting agent: %s", err)) return err @@ -555,6 +557,19 @@ func (c *Command) Run(args []string) int { return 1 } + // Create logger + logger := hclog.New(&hclog.LoggerOptions{ + Name: "agent", + Level: hclog.LevelFromString(config.LogLevel), + Output: logOutput, + JSONFormat: config.LogJson, + }) + + // Swap out UI implementation if json logging is enabled + if config.LogJson { + c.Ui = &logging.HcLogUI{Log: logger} + } + // Log config files if len(config.Files) > 0 { c.Ui.Output(fmt.Sprintf("Loaded configuration from %s", strings.Join(config.Files, ", "))) @@ -570,7 +585,7 @@ func (c *Command) Run(args []string) int { } // Create the agent - if err := c.setupAgent(config, logOutput, inmem); err != nil { + if err := c.setupAgent(config, logger, logOutput, inmem); err != nil { logGate.Flush() return 1 } diff --git a/command/agent/testagent.go b/command/agent/testagent.go index b8d5f55a7..2b2bfedee 100644 --- a/command/agent/testagent.go +++ b/command/agent/testagent.go @@ -17,6 +17,7 @@ import ( metrics "github.com/armon/go-metrics" "github.com/hashicorp/consul/lib/freeport" + "github.com/hashicorp/go-hclog" "github.com/hashicorp/nomad/api" "github.com/hashicorp/nomad/client/fingerprint" "github.com/hashicorp/nomad/helper/testlog" @@ -215,7 +216,14 @@ func (a *TestAgent) start() (*Agent, error) { return nil, fmt.Errorf("unable to set up in memory metrics needed for agent initialization") } - agent, err := NewAgent(a.Config, a.LogOutput, inm) + logger := hclog.New(&hclog.LoggerOptions{ + Name: "agent", + Level: hclog.LevelFromString(a.Config.LogLevel), + Output: a.LogOutput, + JSONFormat: a.Config.LogJson, + }) + + agent, err := NewAgent(a.Config, logger, a.LogOutput, inm) if err != nil { return nil, err } diff --git a/helper/logging/logging.go b/helper/logging/logging.go new file mode 100644 index 000000000..c85659ff0 --- /dev/null +++ b/helper/logging/logging.go @@ -0,0 +1,38 @@ +package logging + +import ( + "fmt" + + "github.com/hashicorp/go-hclog" +) + +// HcLogUI is an implementation of Ui that takes a hclogger +// and uses it to Log the output. It is intended for write only +// use cases and the Ask/AskSecret methods are not implemented. +type HcLogUI struct { + Log hclog.Logger +} + +func (l *HcLogUI) Ask(query string) (string, error) { + return "", fmt.Errorf("Ask is not supported in this implementation") +} + +func (l *HcLogUI) AskSecret(query string) (string, error) { + return "", fmt.Errorf("AskSecret is not supported in this implementation") +} + +func (l *HcLogUI) Output(message string) { + l.Log.Info(message) +} + +func (l *HcLogUI) Info(message string) { + l.Log.Info(message) +} + +func (l *HcLogUI) Error(message string) { + l.Log.Error(message) +} + +func (l *HcLogUI) Warn(message string) { + l.Log.Warn(message) +}