diff --git a/cmd/traefik/configuration.go b/cmd/traefik/configuration.go index b61c9d50d..c461dba93 100644 --- a/cmd/traefik/configuration.go +++ b/cmd/traefik/configuration.go @@ -153,6 +153,12 @@ func NewTraefikDefaultPointersConfiguration() *TraefikConfiguration { var defaultEureka eureka.Provider defaultEureka.Delay = "30s" + // default TraefikLog + defaultTraefikLog := types.TraefikLog{ + Format: "common", + FilePath: "", + } + // default AccessLog defaultAccessLog := types.AccessLog{ Format: accesslog.CommonFormat, @@ -177,6 +183,7 @@ func NewTraefikDefaultPointersConfiguration() *TraefikConfiguration { DynamoDB: &defaultDynamoDB, Retry: &configuration.Retry{}, HealthCheck: &configuration.HealthCheckConfig{}, + TraefikLog: &defaultTraefikLog, AccessLog: &defaultAccessLog, } diff --git a/cmd/traefik/traefik.go b/cmd/traefik/traefik.go index 2b4f7f8c9..23e097bc8 100644 --- a/cmd/traefik/traefik.go +++ b/cmd/traefik/traefik.go @@ -265,15 +265,36 @@ func run(globalConfiguration *configuration.GlobalConfiguration) { log.Error("Error getting level", err) } log.SetLevel(level) - if len(globalConfiguration.TraefikLogsFile) > 0 { - dir := filepath.Dir(globalConfiguration.TraefikLogsFile) + + 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(globalConfiguration.TraefikLogsFile) + err = log.OpenFile(logFile) defer func() { if err := log.CloseFile(); err != nil { log.Error("Error closing log", err) @@ -281,12 +302,9 @@ func run(globalConfiguration *configuration.GlobalConfiguration) { }() if err != nil { log.Error("Error opening file", err) - } else { - log.SetFormatter(&logrus.TextFormatter{DisableColors: true, FullTimestamp: true, DisableSorting: true}) } - } else { - log.SetFormatter(&logrus.TextFormatter{FullTimestamp: true, DisableSorting: true}) } + jsonConf, _ := json.Marshal(globalConfiguration) log.Infof("Traefik version %s built on %s", version.Version, version.BuildDate) diff --git a/configuration/configuration.go b/configuration/configuration.go index 2a21ab398..088537321 100644 --- a/configuration/configuration.go +++ b/configuration/configuration.go @@ -47,7 +47,8 @@ type GlobalConfiguration struct { CheckNewVersion bool `description:"Periodically check if a new version has been released"` AccessLogsFile string `description:"(Deprecated) Access logs file"` // Deprecated AccessLog *types.AccessLog `description:"Access log settings"` - TraefikLogsFile string `description:"Traefik logs file. Stdout is used when omitted or empty"` + TraefikLogsFile string `description:"(Deprecated) Traefik logs file. Stdout is used when omitted or empty"` // Deprecated + TraefikLog *types.TraefikLog `description:"Traefik log settings"` LogLevel string `short:"l" description:"Log level"` EntryPoints EntryPoints `description:"Entrypoints definition using format: --entryPoints='Name:http Address::8000 Redirect.EntryPoint:https' --entryPoints='Name:https Address::4442 TLS:tests/traefik.crt,tests/traefik.key;prod/traefik.crt,prod/traefik.key'"` Cluster *types.Cluster `description:"Enable clustering"` diff --git a/docs/configuration/commons.md b/docs/configuration/commons.md index f46118210..bbeda32c2 100644 --- a/docs/configuration/commons.md +++ b/docs/configuration/commons.md @@ -152,6 +152,11 @@ constraints = ["tag==api", "tag!=v*-beta"] ```toml # Traefik logs file # If not defined, logs to stdout +# +# DEPRECATED - see [traefikLog] lower down +# In case both traefikLogsFile and traefikLog.filePath are specified, the latter will take precedence. +# Optional +# traefikLogsFile = "log/traefik.log" # Log level @@ -165,6 +170,23 @@ traefikLogsFile = "log/traefik.log" logLevel = "ERROR" ``` +## Traefik Logs + +By default the Traefik log is written to stdout in text format. + +To write the logs into a logfile specify the `filePath`. +```toml +[traefikLog] + filePath = "/path/to/traefik.log" +``` + +To write JSON format logs, specify `json` as the format: +```toml +[traefikLog] + filePath = "/path/to/traefik.log" + format = "json" +``` + ### Access Logs Access logs are written when `[accessLog]` is defined. diff --git a/traefik.sample.toml b/traefik.sample.toml index ac2e94d9f..60eb3acd7 100644 --- a/traefik.sample.toml +++ b/traefik.sample.toml @@ -9,13 +9,6 @@ # # debug = true -# Traefik logs file -# If not defined, logs to stdout -# -# Optional -# -# traefikLogsFile = "log/traefik.log" - # Log level # # Optional @@ -39,6 +32,28 @@ [entryPoints.http] address = ":80" +# Traefik logs +# Enabled by default and log to stdout +# +# Optional +# +# [traefikLog] + +# Sets the filepath for the traefik log. If not specified, stdout will be used. +# Intermediate directories are created if necessary. +# +# Optional +# Default: os.Stdout +# +# filePath = "log/traefik.log" + +# Format is either "json" or "common". +# +# Optional +# Default: "common" +# +# format = "common" + # Enable access logs # By default it will write to stdout and produce logs in the textual # Common Log Format (CLF), extended with additional fields. diff --git a/types/types.go b/types/types.go index e47e6e79f..8f2e00bda 100644 --- a/types/types.go +++ b/types/types.go @@ -412,6 +412,12 @@ func (b *Buckets) SetValue(val interface{}) { *b = Buckets(val.(Buckets)) } +// TraefikLog holds the configuration settings for the traefik logger. +type TraefikLog struct { + FilePath string `json:"file,omitempty" description:"Traefik log file path. Stdout is used when omitted or empty"` + Format string `json:"format,omitempty" description:"Traefik log format: json | common"` +} + // AccessLog holds the configuration settings for the access logger (middlewares/accesslog). type AccessLog struct { FilePath string `json:"file,omitempty" description:"Access log file path. Stdout is used when omitted or empty"`