diff --git a/dendrite-config.yaml b/dendrite-config.yaml index fa915e503..7091414c4 100644 --- a/dendrite-config.yaml +++ b/dendrite-config.yaml @@ -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" diff --git a/src/github.com/matrix-org/dendrite/common/config/config.go b/src/github.com/matrix-org/dendrite/common/config/config.go index 5cfb4b797..3cd9d09bd 100644 --- a/src/github.com/matrix-org/dendrite/common/config/config.go +++ b/src/github.com/matrix-org/dendrite/common/config/config.go @@ -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} } diff --git a/src/github.com/matrix-org/dendrite/common/config/config_test.go b/src/github.com/matrix-org/dendrite/common/config/config_test.go index 5d3b40cd9..a57458c3f 100644 --- a/src/github.com/matrix-org/dendrite/common/config/config_test.go +++ b/src/github.com/matrix-org/dendrite/common/config/config_test.go @@ -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