[FEATURE] [BREAKING] Support writing logs in a file. (#686)

* [FEATURE] Support writing logs in a file.

* Add documentation about logs file path.

* Rename logs_level and logs_file_path into log_level and log_file_path.

* Update BREAKING.md

Fixes #338

Co-authored-by: Amir Zarrinkafsh <nightah@me.com>
pull/698/head
Clément Michaud 2020-03-09 20:57:53 +01:00 committed by GitHub
parent 6af27cb3f9
commit c429488738
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 108 additions and 40 deletions

View File

@ -6,6 +6,10 @@ recommended not to use the 'latest' Docker image tag blindly but pick a version
and read this documentation before upgrading. This is where you will get information about
breaking changes and about what you should do to overcome those changes.
## Breaking in v4.7.0
`logs_level` configuration key has been renamed to `log_level`.
## Breaking in v4.0.0
Authelia has been rewritten in Go for better code maintainability and for performance and

View File

@ -29,10 +29,6 @@ func startServer() {
log.Fatal(errors.New("No config file path provided"))
}
if os.Getenv("ENVIRONMENT") == "dev" {
logging.Logger().Info("===> Authelia is running in development mode. <===")
}
config, errs := configuration.Read(configPathFlag)
if len(errs) > 0 {
@ -42,7 +38,11 @@ func startServer() {
panic(errors.New("Some errors have been reported"))
}
switch config.LogsLevel {
if err := logging.InitializeLogger(config.LogFilePath); err != nil {
log.Fatalf("Cannot initialize logger: %v", err)
}
switch config.LogLevel {
case "info":
logging.Logger().Info("Logging severity set to info")
logging.SetLevel(logrus.InfoLevel)
@ -56,6 +56,10 @@ func startServer() {
logging.SetLevel(logrus.TraceLevel)
}
if os.Getenv("ENVIRONMENT") == "dev" {
logging.Logger().Info("===> Authelia is running in development mode. <===")
}
var userProvider authentication.UserProvider
if config.AuthenticationBackend.File != nil {

View File

@ -9,7 +9,9 @@ port: 9091
# tls_cert: /var/lib/authelia/ssl/cert.pem
# Level of verbosity for logs: info, debug, trace
logs_level: debug
log_level: debug
## File path where the logs will be written. If not set logs are written to stdout.
# log_file_path: /var/log/authelia
# The secret used to generate JWT tokens when validating user identity by
# email confirmation.

View File

@ -29,14 +29,25 @@ following configuration options:
tls_cert: /var/lib/authelia/ssl/cert.pem
## Logs level
## Log
### Log level
`optional: true`
Defines the level of logs used by Authelia. This level can be set to
`trace`, `debug`, `info`.
logs_level: debug
log_level: debug
### Log file path
`optional: true`
Logs can be stored in a file when file path is provided. Otherwise logs
are written to standard output.
log_file_path: /var/log/authelia.log
## JWT Secret

View File

@ -23,7 +23,7 @@ func TestShouldParseConfigFile(t *testing.T) {
require.Len(t, errors, 0)
assert.Equal(t, 9091, config.Port)
assert.Equal(t, "debug", config.LogsLevel)
assert.Equal(t, "debug", config.LogLevel)
assert.Equal(t, "https://home.example.com:8080/", config.DefaultRedirectionURL)
assert.Equal(t, "authelia.com", config.TOTP.Issuer)
assert.Equal(t, "secret_from_env", config.JWTSecret)

View File

@ -7,7 +7,8 @@ type Configuration struct {
TLSCert string `mapstructure:"tls_cert"`
TLSKey string `mapstructure:"tls_key"`
LogsLevel string `mapstructure:"logs_level"`
LogLevel string `mapstructure:"log_level"`
LogFilePath string `mapstructure:"log_file_path"`
// This secret is used by the identity validation process to forge JWT tokens
// representing the permission to proceed with the operation.

View File

@ -5,7 +5,7 @@
host: 127.0.0.1
port: 9091
logs_level: debug
log_level: debug
default_redirection_url: https://home.example.com:8080/
totp:

View File

@ -8,7 +8,7 @@ import (
)
var defaultPort = 8080
var defaultLogsLevel = "info"
var defaultLogLevel = "info"
// Validate and adapt the configuration read from file.
func Validate(configuration *schema.Configuration, validator *schema.StructValidator) {
@ -20,8 +20,8 @@ func Validate(configuration *schema.Configuration, validator *schema.StructValid
configuration.Port = defaultPort
}
if configuration.LogsLevel == "" {
configuration.LogsLevel = defaultLogsLevel
if configuration.LogLevel == "" {
configuration.LogLevel = defaultLogLevel
}
if configuration.TLSKey != "" && configuration.TLSCert == "" {

View File

@ -12,7 +12,7 @@ func newDefaultConfig() schema.Configuration {
config := schema.Configuration{}
config.Host = "127.0.0.1"
config.Port = 9090
config.LogsLevel = "info"
config.LogLevel = "info"
config.JWTSecret = "a_secret"
config.AuthenticationBackend.File = new(schema.FileAuthenticationBackendConfiguration)
config.AuthenticationBackend.File.Path = "/a/path"
@ -40,7 +40,7 @@ func TestShouldNotUpdateConfig(t *testing.T) {
require.Len(t, validator.Errors(), 0)
assert.Equal(t, 9090, config.Port)
assert.Equal(t, "info", config.LogsLevel)
assert.Equal(t, "info", config.LogLevel)
}
func TestShouldValidateAndUpdatePort(t *testing.T) {
@ -68,12 +68,12 @@ func TestShouldValidateAndUpdateHost(t *testing.T) {
func TestShouldValidateAndUpdateLogsLevel(t *testing.T) {
validator := schema.NewStructValidator()
config := newDefaultConfig()
config.LogsLevel = ""
config.LogLevel = ""
Validate(&config, validator)
require.Len(t, validator.Errors(), 0)
assert.Equal(t, "info", config.LogsLevel)
assert.Equal(t, "info", config.LogLevel)
}
func TestShouldEnsureNotifierConfigIsProvided(t *testing.T) {

View File

@ -1,16 +1,12 @@
package logging
import (
"os"
logrus_stack "github.com/Gurpartap/logrus-stack"
"github.com/sirupsen/logrus"
)
func init() {
callerLevels := []logrus.Level{}
stackLevels := []logrus.Level{logrus.PanicLevel, logrus.FatalLevel, logrus.ErrorLevel}
logrus.AddHook(logrus_stack.NewHook(callerLevels, stackLevels))
}
// Logger return the standard logrus logger.
func Logger() *logrus.Logger {
return logrus.StandardLogger()
@ -20,3 +16,19 @@ func Logger() *logrus.Logger {
func SetLevel(level logrus.Level) {
logrus.SetLevel(level)
}
// InitializeLogger initialize logger
func InitializeLogger(filename string) error {
callerLevels := []logrus.Level{}
stackLevels := []logrus.Level{logrus.PanicLevel, logrus.FatalLevel, logrus.ErrorLevel}
logrus.AddHook(logrus_stack.NewHook(callerLevels, stackLevels))
if filename != "" {
f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE, 0600)
if err != nil {
return err
}
logrus.SetOutput(f)
}
return nil
}

View File

@ -0,0 +1,34 @@
package logging
import (
"fmt"
"io/ioutil"
"log"
"os"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestShouldWriteLogsToFile(t *testing.T) {
dir, err := ioutil.TempDir("/tmp", "logs-dir")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(dir)
path := fmt.Sprintf("%s/authelia.log", dir)
err = InitializeLogger(path)
require.NoError(t, err)
Logger().Info("This is a test")
f, err := os.OpenFile(path, os.O_RDONLY, 0)
require.NoError(t, err)
b, err := ioutil.ReadAll(f)
require.NoError(t, err)
assert.Contains(t, string(b), "level=info msg=\"This is a test\"\n")
}

View File

@ -4,7 +4,7 @@
port: 9091
logs_level: debug
log_level: debug
jwt_secret: unsecure_secret

View File

@ -4,7 +4,7 @@
port: 9091
logs_level: debug
log_level: debug
default_redirection_url: https://home.example.com:8080/

View File

@ -4,7 +4,7 @@
port: 9091
logs_level: trace
log_level: trace
default_redirection_url: https://home.example.com:8080/

View File

@ -4,7 +4,7 @@
port: 9091
logs_level: debug
log_level: debug
jwt_secret: unsecure_secret

View File

@ -8,7 +8,7 @@ port: 9091
# Log level
#
# Level of verbosity for logs
logs_level: debug
log_level: debug
jwt_secret: unsecure_secret

View File

@ -4,7 +4,7 @@
port: 9091
logs_level: debug
log_level: debug
default_redirection_url: https://home.example.com:8080/

View File

@ -4,7 +4,7 @@
port: 9091
logs_level: debug
log_level: debug
default_redirection_url: https://home.example.com:8080/

View File

@ -4,7 +4,7 @@
port: 9091
logs_level: debug
log_level: debug
default_redirection_url: https://home.example.com:8080/

View File

@ -4,7 +4,7 @@
port: 9091
logs_level: debug
log_level: debug
jwt_secret: unsecure_password

View File

@ -4,7 +4,7 @@
port: 9091
logs_level: debug
log_level: debug
default_redirection_url: https://home.example.com:8080/

View File

@ -4,7 +4,7 @@
port: 9091
logs_level: debug
log_level: debug
default_redirection_url: https://home.example.com:8080/

View File

@ -4,7 +4,7 @@
port: 9091
logs_level: debug
log_level: debug
jwt_secret: unsecure_secret

View File

@ -6,7 +6,7 @@ port: 9091
tls_cert: /var/lib/authelia/ssl/cert.pem
tls_key: /var/lib/authelia/ssl/key.pem
logs_level: debug
log_level: debug
authentication_backend:
file:

View File

@ -4,7 +4,7 @@
port: 9091
logs_level: debug
log_level: debug
jwt_secret: unsecure_secret

View File

@ -4,7 +4,7 @@
port: 9091
logs_level: debug
log_level: debug
jwt_secret: unsecure_secret

View File

@ -3,7 +3,7 @@
###############################################################
port: 80
logs_level: debug
log_level: debug
default_redirection_url: https://home.example.com:8080