Make logging configuration more extensible

Signed-off-by: Tristan Claverie <public@tclaverie.eu>
This commit is contained in:
Tristan Claverie 2017-12-19 07:39:43 +01:00
parent c26d23b89f
commit 473c5efe59
3 changed files with 67 additions and 24 deletions

View file

@ -121,9 +121,19 @@ tracing:
jaeger:
disabled: true
# The configuration for logs of dendrite
# The configuration for dendrite logs
logging:
# The logging level, must be one of debug, info, warn, error, fatal, panic.
level: "info"
# The file on which save logs. If commented, logs won't be saved by dendrite and only printed to stdout
# path: /var/log/dendrite.log
# The logging type, only "file" is supported at the moment
- type: "file"
# The logging level, must be one of debug, info, warn, error, fatal, panic.
level: "info"
# Parameters for this type of log
params:
# File logging must be given a path to a directory. Each component will write to a different file. Logs are rotated each day and gzipped
path: "/var/log/dendrite"
# It is possible to have multiple logging hooks at the same time.
# To save only errors in a different directory, uncomment the following.
# - type: "file"
# level: "error"
# params:
# path: "/var/log/dendrite/errors"

View file

@ -206,14 +206,8 @@ type Dendrite struct {
Jaeger jaegerconfig.Configuration `yaml:"jaeger"`
}
// The config for logging informations
Logging struct {
// The path to the log file
FPath Path `yaml:"path"`
// The logging level
Level string `yaml:"level"`
} `yaml:"logging"`
// The config for logging informations. Each hook will be added to logrus.
Logging []Hook `yaml:"logging"`
// Any information derived from the configuration options for later use.
Derived struct {
@ -228,9 +222,6 @@ type Dendrite struct {
// registration in order to complete registration stages.
Params map[string]interface{} `json:"params"`
}
// The logrus level used for logging configuration
LogLevel logrus.Level
}
}
@ -261,6 +252,52 @@ type ThumbnailSize struct {
ResizeMethod string `yaml:"method,omitempty"`
}
// Hook represents a single logrus hook. At this point, only parsing and
// verification of the proper values for type and level are done.
// Validity/integrity checks on the parameters are done when configuring logrus.
type Hook struct {
// The type of hook, currently only "file" is supported.
// Yaml key is "type"
Type string
// The level of the logs to produce. Will output only this level and above.
//Yaml key is "level"
Level logrus.Level
// The parameters for this hook.
// Yaml key is "params"
Params map[string]interface{}
}
// UnmarshalYAML performs type coercion for a logrus hook. Additionally,
// it ensures the type is one supported.
func (hook *Hook) UnmarshalYAML(unmarshaler func(interface{}) error) error {
var tmp struct {
Type string `yaml:"type"`
Level string `yaml:"level"`
Params map[string]interface{} `yaml:"params"`
}
if err := unmarshaler(&tmp); err != nil {
return err
}
if tmp.Type != "file" {
return fmt.Errorf("Unknown value for %q: %s, want one of [file]", "logging.type", tmp.Type)
}
level, err := logrus.ParseLevel(tmp.Level)
if err != nil {
return fmt.Errorf("Unknown value for %q: %s, want one of [debug,info,warn,error,fatal,panic]", "logging.level", tmp.Level)
}
hook.Type = tmp.Type
hook.Level = level
hook.Params = tmp.Params
return nil
}
// Load a yaml config file for a server run as multiple processes.
// Checks the config to ensure that it is valid.
// The checks are different if the server is run as a monolithic process instead
@ -484,12 +521,6 @@ func (config *Dendrite) check(monolithic bool) error {
checkNotEmpty("listen.room_server", string(config.Listen.RoomServer))
}
if level, err := logrus.ParseLevel(config.Logging.Level); err != nil {
problems = append(problems, fmt.Sprintf("Invalid value for key logging.level: %s", config.Logging.Level))
} else {
config.Derived.LogLevel = level
}
if problems != nil {
return Error{problems}
}

View file

@ -60,8 +60,10 @@ listen:
sync_api: "localhost:7773"
media_api: "localhost:7774"
logging:
level: "debug"
path: "/my/log/dir/dendrite.log"
- type: "file"
level: "info"
params:
path: "/my/log/dir"
`
type mockReadFile map[string]string