Moves logger setup into its own package. (#2471)
* Moves logger setup into its own package. * Removes a stray regex mark in the test locator.
This commit is contained in:
parent
f4e34397ac
commit
ea95e8f40d
|
@ -25,9 +25,9 @@ import (
|
|||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/hashicorp/consul/lib"
|
||||
"github.com/hashicorp/consul/logger"
|
||||
"github.com/hashicorp/consul/watch"
|
||||
"github.com/hashicorp/go-checkpoint"
|
||||
"github.com/hashicorp/go-syslog"
|
||||
"github.com/hashicorp/logutils"
|
||||
scada "github.com/hashicorp/scada-client/scada"
|
||||
"github.com/mitchellh/cli"
|
||||
|
@ -452,63 +452,8 @@ func (c *Config) discoverEc2Hosts(logger *log.Logger) ([]string, error) {
|
|||
return servers, nil
|
||||
}
|
||||
|
||||
// setupLoggers is used to setup the logGate, logWriter, and our logOutput
|
||||
func (c *Command) setupLoggers(config *Config) (*GatedWriter, *logWriter, io.Writer) {
|
||||
// Setup logging. First create the gated log writer, which will
|
||||
// store logs until we're ready to show them. Then create the level
|
||||
// filter, filtering logs of the specified level.
|
||||
logGate := &GatedWriter{
|
||||
Writer: &cli.UiWriter{Ui: c.Ui},
|
||||
}
|
||||
|
||||
c.logFilter = LevelFilter()
|
||||
c.logFilter.MinLevel = logutils.LogLevel(strings.ToUpper(config.LogLevel))
|
||||
c.logFilter.Writer = logGate
|
||||
if !ValidateLevelFilter(c.logFilter.MinLevel, c.logFilter) {
|
||||
c.Ui.Error(fmt.Sprintf(
|
||||
"Invalid log level: %s. Valid log levels are: %v",
|
||||
c.logFilter.MinLevel, c.logFilter.Levels))
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
// Check if syslog is enabled
|
||||
var syslog io.Writer
|
||||
retries := 12
|
||||
delay := 5 * time.Second
|
||||
if config.EnableSyslog {
|
||||
for i := 0; i <= retries; i++ {
|
||||
l, err := gsyslog.NewLogger(gsyslog.LOG_NOTICE, config.SyslogFacility, "consul")
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Syslog setup error: %v", err))
|
||||
if i == retries {
|
||||
timeout := time.Duration(retries) * delay
|
||||
c.Ui.Error(fmt.Sprintf("Syslog setup did not succeed within timeout (%s).", timeout.String()))
|
||||
return nil, nil, nil
|
||||
} else {
|
||||
c.Ui.Error(fmt.Sprintf("Retrying syslog setup in %s...", delay.String()))
|
||||
time.Sleep(delay)
|
||||
}
|
||||
} else {
|
||||
syslog = &SyslogWrapper{l, c.logFilter}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a log writer, and wrap a logOutput around it
|
||||
logWriter := NewLogWriter(512)
|
||||
var logOutput io.Writer
|
||||
if syslog != nil {
|
||||
logOutput = io.MultiWriter(c.logFilter, logWriter, syslog)
|
||||
} else {
|
||||
logOutput = io.MultiWriter(c.logFilter, logWriter)
|
||||
}
|
||||
c.logOutput = logOutput
|
||||
return logGate, logWriter, logOutput
|
||||
}
|
||||
|
||||
// setupAgent is used to start the agent and various interfaces
|
||||
func (c *Command) setupAgent(config *Config, logOutput io.Writer, logWriter *logWriter) error {
|
||||
func (c *Command) setupAgent(config *Config, logOutput io.Writer, logWriter *logger.LogWriter) error {
|
||||
c.Ui.Output("Starting Consul agent...")
|
||||
agent, err := Create(config, logOutput)
|
||||
if err != nil {
|
||||
|
@ -779,10 +724,17 @@ func (c *Command) Run(args []string) int {
|
|||
}
|
||||
|
||||
// Setup the log outputs
|
||||
logGate, logWriter, logOutput := c.setupLoggers(config)
|
||||
if logWriter == nil {
|
||||
logConfig := &logger.Config{
|
||||
LogLevel: config.LogLevel,
|
||||
EnableSyslog: config.EnableSyslog,
|
||||
SyslogFacility: config.SyslogFacility,
|
||||
}
|
||||
logFilter, logGate, logWriter, logOutput, ok := logger.Setup(logConfig, c.Ui)
|
||||
if !ok {
|
||||
return 1
|
||||
}
|
||||
c.logFilter = logFilter
|
||||
c.logOutput = logOutput
|
||||
|
||||
/* Setup telemetry
|
||||
Aggregate on 10 second intervals for 1 minute. Expose the
|
||||
|
@ -1055,7 +1007,7 @@ func (c *Command) handleReload(config *Config) *Config {
|
|||
|
||||
// Change the log level
|
||||
minLevel := logutils.LogLevel(strings.ToUpper(newConf.LogLevel))
|
||||
if ValidateLevelFilter(minLevel, c.logFilter) {
|
||||
if logger.ValidateLevelFilter(minLevel, c.logFilter) {
|
||||
c.logFilter.SetMinLevel(minLevel)
|
||||
} else {
|
||||
c.Ui.Error(fmt.Sprintf(
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/consul/logger"
|
||||
"github.com/hashicorp/consul/testutil"
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
@ -337,7 +338,7 @@ func TestSetupAgent_RPCUnixSocket_FileExists(t *testing.T) {
|
|||
Ui: new(cli.MockUi),
|
||||
}
|
||||
|
||||
logWriter := NewLogWriter(512)
|
||||
logWriter := logger.NewLogWriter(512)
|
||||
logOutput := new(bytes.Buffer)
|
||||
|
||||
// Ensure the server is created
|
||||
|
|
|
@ -32,6 +32,7 @@ import (
|
|||
"sync"
|
||||
|
||||
"github.com/hashicorp/consul/consul/structs"
|
||||
"github.com/hashicorp/consul/logger"
|
||||
"github.com/hashicorp/go-msgpack/codec"
|
||||
"github.com/hashicorp/logutils"
|
||||
"github.com/hashicorp/serf/serf"
|
||||
|
@ -171,7 +172,7 @@ type AgentRPC struct {
|
|||
clients map[string]*rpcClient
|
||||
listener net.Listener
|
||||
logger *log.Logger
|
||||
logWriter *logWriter
|
||||
logWriter *logger.LogWriter
|
||||
reloadCh chan struct{}
|
||||
stop bool
|
||||
stopCh chan struct{}
|
||||
|
@ -218,7 +219,7 @@ func (c *rpcClient) String() string {
|
|||
|
||||
// NewAgentRPC is used to create a new Agent RPC handler
|
||||
func NewAgentRPC(agent *Agent, listener net.Listener,
|
||||
logOutput io.Writer, logWriter *logWriter) *AgentRPC {
|
||||
logOutput io.Writer, logWriter *logger.LogWriter) *AgentRPC {
|
||||
if logOutput == nil {
|
||||
logOutput = os.Stderr
|
||||
}
|
||||
|
@ -513,9 +514,9 @@ func (i *AgentRPC) handleMonitor(client *rpcClient, seq uint64) error {
|
|||
req.LogLevel = strings.ToUpper(req.LogLevel)
|
||||
|
||||
// Create a level filter
|
||||
filter := LevelFilter()
|
||||
filter := logger.LevelFilter()
|
||||
filter.MinLevel = logutils.LogLevel(req.LogLevel)
|
||||
if !ValidateLevelFilter(filter.MinLevel, filter) {
|
||||
if !logger.ValidateLevelFilter(filter.MinLevel, filter) {
|
||||
resp.Error = fmt.Sprintf("Unknown log level: %s", filter.MinLevel)
|
||||
goto SEND
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/consul/logger"
|
||||
"github.com/hashicorp/consul/testutil"
|
||||
"github.com/hashicorp/serf/serf"
|
||||
)
|
||||
|
@ -38,7 +39,7 @@ func testRPCClient(t *testing.T) *rpcParts {
|
|||
}
|
||||
|
||||
func testRPCClientWithConfig(t *testing.T, cb func(c *Config)) *rpcParts {
|
||||
lw := NewLogWriter(512)
|
||||
lw := logger.NewLogWriter(512)
|
||||
mult := io.MultiWriter(os.Stderr, lw)
|
||||
|
||||
configTry := 0
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
package agent
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/logutils"
|
||||
"log"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/consul/logger"
|
||||
"github.com/hashicorp/logutils"
|
||||
)
|
||||
|
||||
type MockStreamClient struct {
|
||||
|
@ -22,7 +24,7 @@ func (m *MockStreamClient) Send(h *responseHeader, o interface{}) error {
|
|||
|
||||
func TestRPCLogStream(t *testing.T) {
|
||||
sc := &MockStreamClient{}
|
||||
filter := LevelFilter()
|
||||
filter := logger.LevelFilter()
|
||||
filter.MinLevel = logutils.LogLevel("INFO")
|
||||
|
||||
ls := newLogStream(sc, filter, 42, log.New(os.Stderr, "", log.LstdFlags))
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
"github.com/hashicorp/consul/api"
|
||||
"github.com/hashicorp/consul/command/agent"
|
||||
"github.com/hashicorp/consul/consul"
|
||||
"github.com/hashicorp/consul/logger"
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
|
@ -61,7 +62,7 @@ func testAgentWithConfig(t *testing.T, cb func(c *agent.Config)) *agentWrapper {
|
|||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
lw := agent.NewLogWriter(512)
|
||||
lw := logger.NewLogWriter(512)
|
||||
mult := io.MultiWriter(os.Stderr, lw)
|
||||
|
||||
conf := nextConfig()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package agent
|
||||
package logger
|
||||
|
||||
import (
|
||||
"io"
|
|
@ -1,4 +1,4 @@
|
|||
package agent
|
||||
package logger
|
||||
|
||||
import (
|
||||
"bytes"
|
|
@ -1,8 +1,9 @@
|
|||
package agent
|
||||
package logger
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/logutils"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/hashicorp/logutils"
|
||||
)
|
||||
|
||||
// LevelFilter returns a LevelFilter that is configured with the log
|
|
@ -1,4 +1,4 @@
|
|||
package agent
|
||||
package logger
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
@ -10,19 +10,19 @@ type LogHandler interface {
|
|||
HandleLog(string)
|
||||
}
|
||||
|
||||
// logWriter implements io.Writer so it can be used as a log sink.
|
||||
// LogWriter implements io.Writer so it can be used as a log sink.
|
||||
// It maintains a circular buffer of logs, and a set of handlers to
|
||||
// which it can stream the logs to.
|
||||
type logWriter struct {
|
||||
type LogWriter struct {
|
||||
sync.Mutex
|
||||
logs []string
|
||||
index int
|
||||
handlers map[LogHandler]struct{}
|
||||
}
|
||||
|
||||
// NewLogWriter creates a logWriter with the given buffer capacity
|
||||
func NewLogWriter(buf int) *logWriter {
|
||||
return &logWriter{
|
||||
// NewLogWriter creates a LogWriter with the given buffer capacity
|
||||
func NewLogWriter(buf int) *LogWriter {
|
||||
return &LogWriter{
|
||||
logs: make([]string, buf),
|
||||
index: 0,
|
||||
handlers: make(map[LogHandler]struct{}),
|
||||
|
@ -31,7 +31,7 @@ func NewLogWriter(buf int) *logWriter {
|
|||
|
||||
// RegisterHandler adds a log handler to receive logs, and sends
|
||||
// the last buffered logs to the handler
|
||||
func (l *logWriter) RegisterHandler(lh LogHandler) {
|
||||
func (l *LogWriter) RegisterHandler(lh LogHandler) {
|
||||
l.Lock()
|
||||
defer l.Unlock()
|
||||
|
||||
|
@ -55,14 +55,14 @@ func (l *logWriter) RegisterHandler(lh LogHandler) {
|
|||
}
|
||||
|
||||
// DeregisterHandler removes a LogHandler and prevents more invocations
|
||||
func (l *logWriter) DeregisterHandler(lh LogHandler) {
|
||||
func (l *LogWriter) DeregisterHandler(lh LogHandler) {
|
||||
l.Lock()
|
||||
defer l.Unlock()
|
||||
delete(l.handlers, lh)
|
||||
}
|
||||
|
||||
// Write is used to accumulate new logs
|
||||
func (l *logWriter) Write(p []byte) (n int, err error) {
|
||||
func (l *LogWriter) Write(p []byte) (n int, err error) {
|
||||
l.Lock()
|
||||
defer l.Unlock()
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package agent
|
||||
package logger
|
||||
|
||||
import (
|
||||
"testing"
|
|
@ -0,0 +1,89 @@
|
|||
package logger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/go-syslog"
|
||||
"github.com/hashicorp/logutils"
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
// Config is used to set up logging.
|
||||
type Config struct {
|
||||
// LogLevel is the minimum level to be logged.
|
||||
LogLevel string
|
||||
|
||||
// EnableSyslog controls forwarding to syslog.
|
||||
EnableSyslog bool
|
||||
|
||||
// SyslogFacility is the destination for syslog forwarding.
|
||||
SyslogFacility string
|
||||
}
|
||||
|
||||
// Setup is used to perform setup of several logging objects:
|
||||
//
|
||||
// * A LevelFilter is used to perform filtering by log level.
|
||||
// * A GatedWriter is used to buffer logs until startup UI operations are
|
||||
// complete. After this is flushed then logs flow directly to output
|
||||
// destinations.
|
||||
// * A LogWriter provides a mean to temporarily hook logs, such as for running
|
||||
// a command like "consul monitor".
|
||||
// * An io.Writer is provided as the sink for all logs to flow to.
|
||||
//
|
||||
// The provided ui object will get any log messages related to setting up
|
||||
// logging itself, and will also be hooked up to the gated logger. The final bool
|
||||
// parameter indicates if logging was set up successfully.
|
||||
func Setup(config *Config, ui cli.Ui) (*logutils.LevelFilter, *GatedWriter, *LogWriter, io.Writer, bool) {
|
||||
// The gated writer buffers logs at startup and holds until it's flushed.
|
||||
logGate := &GatedWriter{
|
||||
Writer: &cli.UiWriter{ui},
|
||||
}
|
||||
|
||||
// Set up the level filter.
|
||||
logFilter := LevelFilter()
|
||||
logFilter.MinLevel = logutils.LogLevel(strings.ToUpper(config.LogLevel))
|
||||
logFilter.Writer = logGate
|
||||
if !ValidateLevelFilter(logFilter.MinLevel, logFilter) {
|
||||
ui.Error(fmt.Sprintf(
|
||||
"Invalid log level: %s. Valid log levels are: %v",
|
||||
logFilter.MinLevel, logFilter.Levels))
|
||||
return nil, nil, nil, nil, false
|
||||
}
|
||||
|
||||
// Set up syslog if it's enabled.
|
||||
var syslog io.Writer
|
||||
if config.EnableSyslog {
|
||||
retries := 12
|
||||
delay := 5 * time.Second
|
||||
for i := 0; i <= retries; i++ {
|
||||
l, err := gsyslog.NewLogger(gsyslog.LOG_NOTICE, config.SyslogFacility, "consul")
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Syslog setup error: %v", err))
|
||||
if i == retries {
|
||||
timeout := time.Duration(retries) * delay
|
||||
ui.Error(fmt.Sprintf("Syslog setup did not succeed within timeout (%s).", timeout.String()))
|
||||
return nil, nil, nil, nil, false
|
||||
} else {
|
||||
ui.Error(fmt.Sprintf("Retrying syslog setup in %s...", delay.String()))
|
||||
time.Sleep(delay)
|
||||
}
|
||||
} else {
|
||||
syslog = &SyslogWrapper{l, logFilter}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a log writer, and wrap a logOutput around it
|
||||
logWriter := NewLogWriter(512)
|
||||
var logOutput io.Writer
|
||||
if syslog != nil {
|
||||
logOutput = io.MultiWriter(logFilter, logWriter, syslog)
|
||||
} else {
|
||||
logOutput = io.MultiWriter(logFilter, logWriter)
|
||||
}
|
||||
return logFilter, logGate, logWriter, logOutput, true
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
package agent
|
||||
package logger
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/hashicorp/go-syslog"
|
||||
"github.com/hashicorp/logutils"
|
||||
)
|
|
@ -1,4 +1,4 @@
|
|||
package agent
|
||||
package logger
|
||||
|
||||
import (
|
||||
"os"
|
|
@ -11,4 +11,4 @@ go build -tags="${BUILD_TAGS}" -o $TEMPDIR/consul || exit 1
|
|||
|
||||
# Run the tests
|
||||
echo "--> Running tests"
|
||||
go list ./... | grep -v '^/vendor/' | PATH=$TEMPDIR:$PATH xargs -n1 go test -tags="${BUILD_TAGS}" ${GOTEST_FLAGS:--cover -timeout=360s}
|
||||
go list ./... | grep -v '/vendor/' | PATH=$TEMPDIR:$PATH xargs -n1 go test -tags="${BUILD_TAGS}" ${GOTEST_FLAGS:--cover -timeout=360s}
|
||||
|
|
Loading…
Reference in New Issue