agent: fix agent logging

Remove the leading whitespace on every log line. This was causing problems for
a customer because their logging system was interpretting the logs as a single
multi-line log.
This commit is contained in:
Daniel Nephin 2021-06-02 17:12:44 -04:00
parent 5086baeb7f
commit 63c737017d
2 changed files with 46 additions and 26 deletions

View File

@ -13,10 +13,11 @@ import (
"github.com/hashicorp/go-checkpoint" "github.com/hashicorp/go-checkpoint"
"github.com/hashicorp/go-hclog" "github.com/hashicorp/go-hclog"
"github.com/mitchellh/cli" mcli "github.com/mitchellh/cli"
"github.com/hashicorp/consul/agent" "github.com/hashicorp/consul/agent"
"github.com/hashicorp/consul/agent/config" "github.com/hashicorp/consul/agent/config"
"github.com/hashicorp/consul/command/cli"
"github.com/hashicorp/consul/command/flags" "github.com/hashicorp/consul/command/flags"
"github.com/hashicorp/consul/lib" "github.com/hashicorp/consul/lib"
"github.com/hashicorp/consul/logging" "github.com/hashicorp/consul/logging"
@ -25,15 +26,8 @@ import (
) )
func New(ui cli.Ui) *cmd { func New(ui cli.Ui) *cmd {
ui = &cli.PrefixedUi{
OutputPrefix: "==> ",
InfoPrefix: " ",
ErrorPrefix: "==> ",
Ui: ui,
}
c := &cmd{ c := &cmd{
UI: ui, ui: ui,
revision: consulversion.GitCommit, revision: consulversion.GitCommit,
version: consulversion.Version, version: consulversion.Version,
versionPrerelease: consulversion.VersionPrerelease, versionPrerelease: consulversion.VersionPrerelease,
@ -50,7 +44,7 @@ func New(ui cli.Ui) *cmd {
// ShutdownCh. If two messages are sent on the ShutdownCh it will forcibly // ShutdownCh. If two messages are sent on the ShutdownCh it will forcibly
// exit. // exit.
type cmd struct { type cmd struct {
UI cli.Ui ui cli.Ui
flags *flag.FlagSet flags *flag.FlagSet
http *flags.HTTPFlags http *flags.HTTPFlags
help string help string
@ -118,7 +112,7 @@ func (c *cmd) startupJoin(agent *agent.Agent, cfg *config.RuntimeConfig) error {
return nil return nil
} }
c.UI.Output("Joining cluster...") c.logger.Info("Joining cluster")
n, err := agent.JoinLAN(cfg.StartJoinAddrsLAN) n, err := agent.JoinLAN(cfg.StartJoinAddrsLAN)
if err != nil { if err != nil {
return err return err
@ -134,43 +128,52 @@ func (c *cmd) startupJoinWan(agent *agent.Agent, cfg *config.RuntimeConfig) erro
return nil return nil
} }
c.UI.Output("Joining -wan cluster...") c.logger.Info("Joining wan cluster")
n, err := agent.JoinWAN(cfg.StartJoinAddrsWAN) n, err := agent.JoinWAN(cfg.StartJoinAddrsWAN)
if err != nil { if err != nil {
return err return err
} }
c.logger.Info("Join -wan completed. Initial agents synced with", "agent_count", n) c.logger.Info("Join wan completed. Initial agents synced with", "agent_count", n)
return nil return nil
} }
func (c *cmd) run(args []string) int { func (c *cmd) run(args []string) int {
ui := &mcli.PrefixedUi{
OutputPrefix: "==> ",
InfoPrefix: " ",
ErrorPrefix: "==> ",
Ui: c.ui,
}
if err := c.flags.Parse(args); err != nil { if err := c.flags.Parse(args); err != nil {
if !strings.Contains(err.Error(), "help requested") { if !strings.Contains(err.Error(), "help requested") {
c.UI.Error(fmt.Sprintf("error parsing flags: %v", err)) ui.Error(fmt.Sprintf("error parsing flags: %v", err))
} }
return 1 return 1
} }
if len(c.flags.Args()) > 0 { if len(c.flags.Args()) > 0 {
c.UI.Error(fmt.Sprintf("Unexpected extra arguments: %v", c.flags.Args())) ui.Error(fmt.Sprintf("Unexpected extra arguments: %v", c.flags.Args()))
return 1 return 1
} }
logGate := &logging.GatedWriter{Writer: &cli.UiWriter{Ui: c.UI}} // FIXME: logs should always go to stderr, but previously they were sent to
// stdout, so continue to use Stdout for now, and fix this in a future release.
logGate := &logging.GatedWriter{Writer: c.ui.Stdout()}
loader := func(source config.Source) (config.LoadResult, error) { loader := func(source config.Source) (config.LoadResult, error) {
c.configLoadOpts.DefaultConfig = source c.configLoadOpts.DefaultConfig = source
return config.Load(c.configLoadOpts) return config.Load(c.configLoadOpts)
} }
bd, err := agent.NewBaseDeps(loader, logGate) bd, err := agent.NewBaseDeps(loader, logGate)
if err != nil { if err != nil {
c.UI.Error(err.Error()) ui.Error(err.Error())
return 1 return 1
} }
c.logger = bd.Logger c.logger = bd.Logger
agent, err := agent.New(bd) agent, err := agent.New(bd)
if err != nil { if err != nil {
c.UI.Error(err.Error()) ui.Error(err.Error())
return 1 return 1
} }
@ -179,7 +182,7 @@ func (c *cmd) run(args []string) int {
// Setup gate to check if we should output CLI information // Setup gate to check if we should output CLI information
cli := GatedUi{ cli := GatedUi{
JSONoutput: config.Logging.LogJSON, JSONoutput: config.Logging.LogJSON,
ui: c.UI, ui: ui,
} }
// Create the agent // Create the agent
@ -255,12 +258,12 @@ func (c *cmd) run(args []string) int {
} }
if err := c.startupJoin(agent, config); err != nil { if err := c.startupJoin(agent, config); err != nil {
c.logger.Error((err.Error())) c.logger.Error(err.Error())
return 1 return 1
} }
if err := c.startupJoinWan(agent, config); err != nil { if err := c.startupJoinWan(agent, config); err != nil {
c.logger.Error((err.Error())) c.logger.Error(err.Error())
return 1 return 1
} }
@ -340,7 +343,7 @@ func (c *cmd) run(args []string) int {
type GatedUi struct { type GatedUi struct {
JSONoutput bool JSONoutput bool
ui cli.Ui ui mcli.Ui
} }
func (g *GatedUi) output(s string) { func (g *GatedUi) output(s string) {

View File

@ -2,6 +2,7 @@ package agent
import ( import (
"fmt" "fmt"
"io"
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
@ -120,7 +121,7 @@ func TestRetryJoinFail(t *testing.T) {
t.Parallel() t.Parallel()
tmpDir := testutil.TempDir(t, "consul") tmpDir := testutil.TempDir(t, "consul")
ui := cli.NewMockUi() ui := newCaptureUI()
cmd := New(ui) cmd := New(ui)
args := []string{ args := []string{
@ -144,7 +145,7 @@ func TestRetryJoinWanFail(t *testing.T) {
t.Parallel() t.Parallel()
tmpDir := testutil.TempDir(t, "consul") tmpDir := testutil.TempDir(t, "consul")
ui := cli.NewMockUi() ui := newCaptureUI()
cmd := New(ui) cmd := New(ui)
args := []string{ args := []string{
@ -183,7 +184,7 @@ func TestProtectDataDir(t *testing.T) {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
ui := cli.NewMockUi() ui := newCaptureUI()
cmd := New(ui) cmd := New(ui)
args := []string{"-config-file=" + cfgFile.Name()} args := []string{"-config-file=" + cfgFile.Name()}
if code := cmd.Run(args); code == 0 { if code := cmd.Run(args); code == 0 {
@ -202,7 +203,7 @@ func TestBadDataDirPermissions(t *testing.T) {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
ui := cli.NewMockUi() ui := newCaptureUI()
cmd := New(ui) cmd := New(ui)
args := []string{"-data-dir=" + dataDir, "-server=true", "-bind=10.0.0.1"} args := []string{"-data-dir=" + dataDir, "-server=true", "-bind=10.0.0.1"}
if code := cmd.Run(args); code == 0 { if code := cmd.Run(args); code == 0 {
@ -212,3 +213,19 @@ func TestBadDataDirPermissions(t *testing.T) {
t.Fatalf("expected permission denied error, got: %s", out) t.Fatalf("expected permission denied error, got: %s", out)
} }
} }
type captureUI struct {
*cli.MockUi
}
func (c *captureUI) Stdout() io.Writer {
return c.MockUi.OutputWriter
}
func (c *captureUI) Stderr() io.Writer {
return c.MockUi.ErrorWriter
}
func newCaptureUI() *captureUI {
return &captureUI{MockUi: cli.NewMockUi()}
}