Fix traefik logs to behave like configured

This commit is contained in:
Marco Jantke 2017-10-11 10:38:03 +02:00 committed by Traefiker
parent 1532033a7f
commit 871d097b30
5 changed files with 121 additions and 69 deletions

View file

@ -45,19 +45,7 @@ Complete documentation is available at https://traefik.io`,
Config: traefikConfiguration,
DefaultPointersConfig: traefikPointersConfiguration,
Run: func() error {
globalConfiguration := traefikConfiguration.GlobalConfiguration
if globalConfiguration.File != nil && len(globalConfiguration.File.Filename) == 0 {
// no filename, setting to global config file
if len(traefikConfiguration.ConfigFile) != 0 {
globalConfiguration.File.Filename = traefikConfiguration.ConfigFile
} else {
log.Errorln("Error using file configuration backend, no filename defined")
}
}
if len(traefikConfiguration.ConfigFile) != 0 {
log.Infof("Using TOML configuration file %s", traefikConfiguration.ConfigFile)
}
run(&globalConfiguration)
run(&traefikConfiguration.GlobalConfiguration, traefikConfiguration.ConfigFile)
return nil
},
}
@ -222,58 +210,16 @@ Complete documentation is available at https://traefik.io`,
os.Exit(0)
}
func run(globalConfiguration *configuration.GlobalConfiguration) {
fmtlog.SetFlags(fmtlog.Lshortfile | fmtlog.LstdFlags)
func run(globalConfiguration *configuration.GlobalConfiguration, configFile string) {
configureLogging(globalConfiguration)
if len(configFile) > 0 {
log.Infof("Using TOML configuration file %s", configFile)
}
http.DefaultTransport.(*http.Transport).Proxy = http.ProxyFromEnvironment
globalConfiguration.SetEffectiveConfiguration()
// logging
level, err := logrus.ParseLevel(strings.ToLower(globalConfiguration.LogLevel))
if err != nil {
log.Error("Error getting level", err)
}
log.SetLevel(level)
logFile := globalConfiguration.TraefikLogsFile
if len(logFile) > 0 {
log.Warn("top-level traefiklogsfile has been deprecated -- please use traefiklog.filepath")
}
if globalConfiguration.TraefikLog != nil && len(globalConfiguration.TraefikLog.FilePath) > 0 {
logFile = globalConfiguration.TraefikLog.FilePath
}
var formatter logrus.Formatter
if globalConfiguration.TraefikLog != nil && globalConfiguration.TraefikLog.Format == "json" {
formatter = &logrus.JSONFormatter{}
} else {
disableColors := false
if len(logFile) > 0 {
disableColors = true
}
formatter = &logrus.TextFormatter{DisableColors: disableColors, FullTimestamp: true, DisableSorting: true}
}
log.SetFormatter(formatter)
if len(logFile) > 0 {
dir := filepath.Dir(logFile)
err := os.MkdirAll(dir, 0755)
if err != nil {
log.Errorf("Failed to create log path %s: %s", dir, err)
}
err = log.OpenFile(logFile)
defer func() {
if err := log.CloseFile(); err != nil {
log.Error("Error closing log", err)
}
}()
if err != nil {
log.Error("Error opening file", err)
}
}
globalConfiguration.SetEffectiveConfiguration(configFile)
jsonConf, _ := json.Marshal(globalConfiguration)
log.Infof("Traefik version %s built on %s", version.Version, version.BuildDate)
@ -308,6 +254,64 @@ func run(globalConfiguration *configuration.GlobalConfiguration) {
}
svr.Wait()
log.Info("Shutting down")
logrus.Exit(0)
}
func configureLogging(globalConfiguration *configuration.GlobalConfiguration) {
// configure default log flags
fmtlog.SetFlags(fmtlog.Lshortfile | fmtlog.LstdFlags)
if globalConfiguration.Debug {
globalConfiguration.LogLevel = "DEBUG"
}
// configure log level
level, err := logrus.ParseLevel(strings.ToLower(globalConfiguration.LogLevel))
if err != nil {
log.Error("Error getting level", err)
}
log.SetLevel(level)
// configure log output file
logFile := globalConfiguration.TraefikLogsFile
if len(logFile) > 0 {
log.Warn("top-level traefiklogsfile has been deprecated -- please use traefiklog.filepath")
}
if globalConfiguration.TraefikLog != nil && len(globalConfiguration.TraefikLog.FilePath) > 0 {
logFile = globalConfiguration.TraefikLog.FilePath
}
// configure log format
var formatter logrus.Formatter
if globalConfiguration.TraefikLog != nil && globalConfiguration.TraefikLog.Format == "json" {
formatter = &logrus.JSONFormatter{}
} else {
disableColors := false
if len(logFile) > 0 {
disableColors = true
}
formatter = &logrus.TextFormatter{DisableColors: disableColors, FullTimestamp: true, DisableSorting: true}
}
log.SetFormatter(formatter)
if len(logFile) > 0 {
dir := filepath.Dir(logFile)
err := os.MkdirAll(dir, 0755)
if err != nil {
log.Errorf("Failed to create log path %s: %s", dir, err)
}
err = log.OpenFile(logFile)
logrus.RegisterExitHandler(func() {
if err := log.CloseFile(); err != nil {
log.Error("Error closing log", err)
}
})
if err != nil {
log.Error("Error opening file", err)
}
}
}
// CreateKvSource creates KvSource

View file

@ -89,7 +89,7 @@ type GlobalConfiguration struct {
// SetEffectiveConfiguration adds missing configuration parameters derived from
// existing ones. It also takes care of maintaining backwards compatibility.
func (gc *GlobalConfiguration) SetEffectiveConfiguration() {
func (gc *GlobalConfiguration) SetEffectiveConfiguration(configFile string) {
if len(gc.EntryPoints) == 0 {
gc.EntryPoints = map[string]*EntryPoint{"http": {Address: ":80"}}
gc.DefaultEntryPoints = []string{"http"}
@ -128,8 +128,14 @@ func (gc *GlobalConfiguration) SetEffectiveConfiguration() {
}
}
if gc.Debug {
gc.LogLevel = "DEBUG"
// Try to fallback to traefik config file in case the file provider is enabled
// but has no file name configured.
if gc.File != nil && len(gc.File.Filename) == 0 {
if len(configFile) > 0 {
gc.File.Filename = configFile
} else {
log.Errorln("Error using file configuration backend, no filename defined")
}
}
}

View file

@ -6,10 +6,14 @@ import (
"time"
"github.com/containous/flaeg"
"github.com/containous/traefik/provider"
"github.com/containous/traefik/provider/file"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
const defaultConfigFile = "traefik.toml"
func Test_parseEntryPointsConfiguration(t *testing.T) {
testCases := []struct {
name string
@ -196,7 +200,7 @@ func TestEntryPoints_Set(t *testing.T) {
}
}
func TestSetEffecticeConfiguration(t *testing.T) {
func TestSetEffectiveConfigurationGraceTimeout(t *testing.T) {
tests := []struct {
desc string
legacyGraceTimeout time.Duration
@ -235,11 +239,49 @@ func TestSetEffecticeConfiguration(t *testing.T) {
}
}
gc.SetEffectiveConfiguration()
gc.SetEffectiveConfiguration(defaultConfigFile)
gotGraceTimeout := time.Duration(gc.LifeCycle.GraceTimeOut)
if gotGraceTimeout != test.wantGraceTimeout {
t.Fatalf("got effective grace timeout %d, want %d", gotGraceTimeout, test.wantGraceTimeout)
}
})
}
}
func TestSetEffectiveConfigurationFileProviderFilename(t *testing.T) {
tests := []struct {
desc string
fileProvider *file.Provider
wantFileProviderFilename string
}{
{
desc: "no filename for file provider given",
fileProvider: &file.Provider{},
wantFileProviderFilename: defaultConfigFile,
},
{
desc: "filename for file provider given",
fileProvider: &file.Provider{BaseProvider: provider.BaseProvider{Filename: "other.toml"}},
wantFileProviderFilename: "other.toml",
},
}
for _, test := range tests {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
gc := &GlobalConfiguration{
File: test.fileProvider,
}
gc.SetEffectiveConfiguration(defaultConfigFile)
gotFileProviderFilename := gc.File.Filename
if gotFileProviderFilename != test.wantFileProviderFilename {
t.Fatalf("got file provider file name %q, want %q", gotFileProviderFilename, test.wantFileProviderFilename)
}
})
}
}

View file

@ -157,7 +157,7 @@ func (provider *Provider) Provide(configurationChan chan<- types.ConfigMessage,
err = http.ListenAndServe(provider.Address, negroniInstance)
}
if err != nil {
if err != http.ErrServerClosed {
log.Fatal("Error creating server: ", err)
}
})

View file

@ -627,7 +627,7 @@ func (server *Server) startServer(serverEntryPoint *serverEntryPoint, globalConf
} else {
err = serverEntryPoint.httpServer.Serve(serverEntryPoint.listener)
}
if err != nil {
if err != http.ErrServerClosed {
log.Error("Error creating server: ", err)
}
}