Fix traefik logs to behave like configured
This commit is contained in:
parent
1532033a7f
commit
871d097b30
5 changed files with 121 additions and 69 deletions
|
@ -45,19 +45,7 @@ Complete documentation is available at https://traefik.io`,
|
||||||
Config: traefikConfiguration,
|
Config: traefikConfiguration,
|
||||||
DefaultPointersConfig: traefikPointersConfiguration,
|
DefaultPointersConfig: traefikPointersConfiguration,
|
||||||
Run: func() error {
|
Run: func() error {
|
||||||
globalConfiguration := traefikConfiguration.GlobalConfiguration
|
run(&traefikConfiguration.GlobalConfiguration, traefikConfiguration.ConfigFile)
|
||||||
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)
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -222,58 +210,16 @@ Complete documentation is available at https://traefik.io`,
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func run(globalConfiguration *configuration.GlobalConfiguration) {
|
func run(globalConfiguration *configuration.GlobalConfiguration, configFile string) {
|
||||||
fmtlog.SetFlags(fmtlog.Lshortfile | fmtlog.LstdFlags)
|
configureLogging(globalConfiguration)
|
||||||
|
|
||||||
|
if len(configFile) > 0 {
|
||||||
|
log.Infof("Using TOML configuration file %s", configFile)
|
||||||
|
}
|
||||||
|
|
||||||
http.DefaultTransport.(*http.Transport).Proxy = http.ProxyFromEnvironment
|
http.DefaultTransport.(*http.Transport).Proxy = http.ProxyFromEnvironment
|
||||||
|
|
||||||
globalConfiguration.SetEffectiveConfiguration()
|
globalConfiguration.SetEffectiveConfiguration(configFile)
|
||||||
|
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
jsonConf, _ := json.Marshal(globalConfiguration)
|
jsonConf, _ := json.Marshal(globalConfiguration)
|
||||||
log.Infof("Traefik version %s built on %s", version.Version, version.BuildDate)
|
log.Infof("Traefik version %s built on %s", version.Version, version.BuildDate)
|
||||||
|
@ -308,6 +254,64 @@ func run(globalConfiguration *configuration.GlobalConfiguration) {
|
||||||
}
|
}
|
||||||
svr.Wait()
|
svr.Wait()
|
||||||
log.Info("Shutting down")
|
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
|
// CreateKvSource creates KvSource
|
||||||
|
|
|
@ -89,7 +89,7 @@ type GlobalConfiguration struct {
|
||||||
|
|
||||||
// SetEffectiveConfiguration adds missing configuration parameters derived from
|
// SetEffectiveConfiguration adds missing configuration parameters derived from
|
||||||
// existing ones. It also takes care of maintaining backwards compatibility.
|
// 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 {
|
if len(gc.EntryPoints) == 0 {
|
||||||
gc.EntryPoints = map[string]*EntryPoint{"http": {Address: ":80"}}
|
gc.EntryPoints = map[string]*EntryPoint{"http": {Address: ":80"}}
|
||||||
gc.DefaultEntryPoints = []string{"http"}
|
gc.DefaultEntryPoints = []string{"http"}
|
||||||
|
@ -128,8 +128,14 @@ func (gc *GlobalConfiguration) SetEffectiveConfiguration() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if gc.Debug {
|
// Try to fallback to traefik config file in case the file provider is enabled
|
||||||
gc.LogLevel = "DEBUG"
|
// 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")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,14 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containous/flaeg"
|
"github.com/containous/flaeg"
|
||||||
|
"github.com/containous/traefik/provider"
|
||||||
|
"github.com/containous/traefik/provider/file"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const defaultConfigFile = "traefik.toml"
|
||||||
|
|
||||||
func Test_parseEntryPointsConfiguration(t *testing.T) {
|
func Test_parseEntryPointsConfiguration(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
|
@ -196,7 +200,7 @@ func TestEntryPoints_Set(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetEffecticeConfiguration(t *testing.T) {
|
func TestSetEffectiveConfigurationGraceTimeout(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
desc string
|
desc string
|
||||||
legacyGraceTimeout time.Duration
|
legacyGraceTimeout time.Duration
|
||||||
|
@ -235,11 +239,49 @@ func TestSetEffecticeConfiguration(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gc.SetEffectiveConfiguration()
|
gc.SetEffectiveConfiguration(defaultConfigFile)
|
||||||
|
|
||||||
gotGraceTimeout := time.Duration(gc.LifeCycle.GraceTimeOut)
|
gotGraceTimeout := time.Duration(gc.LifeCycle.GraceTimeOut)
|
||||||
if gotGraceTimeout != test.wantGraceTimeout {
|
if gotGraceTimeout != test.wantGraceTimeout {
|
||||||
t.Fatalf("got effective grace timeout %d, want %d", 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)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,7 +157,7 @@ func (provider *Provider) Provide(configurationChan chan<- types.ConfigMessage,
|
||||||
err = http.ListenAndServe(provider.Address, negroniInstance)
|
err = http.ListenAndServe(provider.Address, negroniInstance)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != http.ErrServerClosed {
|
||||||
log.Fatal("Error creating server: ", err)
|
log.Fatal("Error creating server: ", err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -627,7 +627,7 @@ func (server *Server) startServer(serverEntryPoint *serverEntryPoint, globalConf
|
||||||
} else {
|
} else {
|
||||||
err = serverEntryPoint.httpServer.Serve(serverEntryPoint.listener)
|
err = serverEntryPoint.httpServer.Serve(serverEntryPoint.listener)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != http.ErrServerClosed {
|
||||||
log.Error("Error creating server: ", err)
|
log.Error("Error creating server: ", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue