inherit logging config from ocis.yaml, let extensions overwrite their logging. Considering using a package level global logging...

This commit is contained in:
A.Unger
2021-10-31 00:08:46 +02:00
parent 998df71ae3
commit 711acbb354
21 changed files with 180 additions and 126 deletions

View File

@@ -6,7 +6,6 @@ import (
"strings"
"github.com/owncloud/ocis/accounts/pkg/config"
"github.com/owncloud/ocis/accounts/pkg/flagset"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/log"
"github.com/owncloud/ocis/ocis-pkg/sync"
@@ -36,7 +35,7 @@ func Execute(cfg *config.Config) error {
},
},
Flags: flagset.RootWithConfig(cfg),
//Flags: flagset.RootWithConfig(cfg),
Before: func(c *cli.Context) error {
cfg.Server.Version = version.String
@@ -131,6 +130,7 @@ type SutureService struct {
// NewSutureService creates a new accounts.SutureService
func NewSutureService(cfg *ociscfg.Config) suture.Service {
inheritLogging(cfg)
if cfg.Mode == 0 {
cfg.Accounts.Supervised = true
}
@@ -148,3 +148,13 @@ func (s SutureService) Serve(ctx context.Context) error {
return nil
}
// inheritLogging is a poor man's global logging state tip-toeing around circular dependencies. It sets the logging
// of the service to whatever is in the higher config (in this case coming from ocis.yaml) and sets them as defaults,
// being overwritten when the extension parses its config file / env variables.
func inheritLogging(cfg *ociscfg.Config) {
cfg.Accounts.Log.File = cfg.Log.File
cfg.Accounts.Log.Color = cfg.Log.Color
cfg.Accounts.Log.Pretty = cfg.Log.Pretty
cfg.Accounts.Log.Level = cfg.Log.Level
}

View File

@@ -6,7 +6,6 @@ import (
"strings"
"github.com/owncloud/ocis/glauth/pkg/config"
"github.com/owncloud/ocis/glauth/pkg/flagset"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/log"
"github.com/owncloud/ocis/ocis-pkg/sync"
@@ -31,7 +30,7 @@ func Execute(cfg *config.Config) error {
},
},
Flags: flagset.RootWithConfig(cfg),
//Flags: flagset.RootWithConfig(cfg),
Before: func(c *cli.Context) error {
cfg.Version = version.String
@@ -120,6 +119,7 @@ type SutureService struct {
// NewSutureService creates a new glauth.SutureService
func NewSutureService(cfg *ociscfg.Config) suture.Service {
inheritLogging(cfg)
if cfg.Mode == 0 {
cfg.GLAuth.Supervised = true
}
@@ -137,3 +137,13 @@ func (s SutureService) Serve(ctx context.Context) error {
return nil
}
// inheritLogging is a poor man's global logging state tip-toeing around circular dependencies. It sets the logging
// of the service to whatever is in the higher config (in this case coming from ocis.yaml) and sets them as defaults,
// being overwritten when the extension parses its config file / env variables.
func inheritLogging(cfg *ociscfg.Config) {
cfg.GLAuth.Log.File = cfg.Log.File
cfg.GLAuth.Log.Color = cfg.Log.Color
cfg.GLAuth.Log.Pretty = cfg.Log.Pretty
cfg.GLAuth.Log.Level = cfg.Log.Level
}

View File

@@ -6,7 +6,6 @@ import (
"strings"
"github.com/owncloud/ocis/graph-explorer/pkg/config"
"github.com/owncloud/ocis/graph-explorer/pkg/flagset"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/log"
"github.com/owncloud/ocis/ocis-pkg/sync"
@@ -31,7 +30,7 @@ func Execute(cfg *config.Config) error {
},
},
Flags: flagset.RootWithConfig(cfg),
//Flags: flagset.RootWithConfig(cfg),
Before: func(c *cli.Context) error {
cfg.Server.Version = version.String
@@ -91,8 +90,8 @@ func ParseConfig(c *cli.Context, cfg *config.Config) error {
if err := viper.ReadInConfig(); err != nil {
switch err.(type) {
case viper.ConfigFileNotFoundError:
logger.Info().
Msg("Continue without config")
//logger.Info().
// Msg("Continue without config")
case viper.UnsupportedConfigError:
logger.Fatal().
Err(err).
@@ -120,6 +119,7 @@ type SutureService struct {
// NewSutureService creates a new graph-explorer.SutureService
func NewSutureService(cfg *ociscfg.Config) suture.Service {
inheritLogging(cfg)
if cfg.Mode == 0 {
cfg.GraphExplorer.Supervised = true
}
@@ -137,3 +137,13 @@ func (s SutureService) Serve(ctx context.Context) error {
return nil
}
// inheritLogging is a poor man's global logging state tip-toeing around circular dependencies. It sets the logging
// of the service to whatever is in the higher config (in this case coming from ocis.yaml) and sets them as defaults,
// being overwritten when the extension parses its config file / env variables.
func inheritLogging(cfg *ociscfg.Config) {
cfg.GraphExplorer.Log.File = cfg.Log.File
cfg.GraphExplorer.Log.Color = cfg.Log.Color
cfg.GraphExplorer.Log.Pretty = cfg.Log.Pretty
cfg.GraphExplorer.Log.Level = cfg.Log.Level
}

View File

@@ -9,7 +9,6 @@ import (
"github.com/thejerf/suture/v4"
"github.com/owncloud/ocis/graph/pkg/config"
"github.com/owncloud/ocis/graph/pkg/flagset"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/log"
"github.com/owncloud/ocis/ocis-pkg/version"
@@ -32,7 +31,7 @@ func Execute(cfg *config.Config) error {
},
},
Flags: flagset.RootWithConfig(cfg),
//Flags: flagset.RootWithConfig(cfg),
Before: func(c *cli.Context) error {
cfg.Server.Version = version.String
@@ -92,8 +91,8 @@ func ParseConfig(c *cli.Context, cfg *config.Config) error {
if err := viper.ReadInConfig(); err != nil {
switch err.(type) {
case viper.ConfigFileNotFoundError:
logger.Info().
Msg("Continue without config")
//logger.Info().
// Msg("Continue without config")
case viper.UnsupportedConfigError:
logger.Fatal().
Err(err).

View File

@@ -6,7 +6,6 @@ import (
"strings"
"github.com/owncloud/ocis/idp/pkg/config"
"github.com/owncloud/ocis/idp/pkg/flagset"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/log"
"github.com/owncloud/ocis/ocis-pkg/sync"
@@ -31,7 +30,7 @@ func Execute(cfg *config.Config) error {
},
},
Flags: flagset.RootWithConfig(cfg),
//Flags: flagset.RootWithConfig(cfg),
Before: func(c *cli.Context) error {
cfg.Service.Version = version.String
@@ -121,6 +120,7 @@ type SutureService struct {
// NewSutureService creates a new idp.SutureService
func NewSutureService(cfg *ociscfg.Config) suture.Service {
inheritLogging(cfg)
if cfg.Mode == 0 {
cfg.IDP.Supervised = true
}
@@ -138,3 +138,13 @@ func (s SutureService) Serve(ctx context.Context) error {
return nil
}
// inheritLogging is a poor man's global logging state tip-toeing around circular dependencies. It sets the logging
// of the service to whatever is in the higher config (in this case coming from ocis.yaml) and sets them as defaults,
// being overwritten when the extension parses its config file / env variables.
func inheritLogging(cfg *ociscfg.Config) {
cfg.IDP.Log.File = cfg.Log.File
cfg.IDP.Log.Color = cfg.Log.Color
cfg.IDP.Log.Pretty = cfg.Log.Pretty
cfg.IDP.Log.Level = cfg.Log.Level
}

View File

@@ -18,43 +18,43 @@ import (
// Log defines the available logging configuration.
type Log struct {
Level string
Pretty bool
Color bool
File string
Level string `mapstructure:"level"`
Pretty bool `mapstructure:"pretty"`
Color bool `mapstructure:"color"`
File string `mapstructure:"file"`
}
// Debug defines the available debug configuration.
type Debug struct {
Addr string
Token string
Pprof bool
Zpages bool
Addr string `mapstructure:"addr"`
Token string `mapstructure:"token"`
Pprof bool `mapstructure:"pprof"`
Zpages bool `mapstructure:"zpages"`
}
// HTTP defines the available http configuration.
type HTTP struct {
Addr string
Root string
Addr string `mapstructure:"addr"`
Root string `mapstructure:"root"`
}
// GRPC defines the available grpc configuration.
type GRPC struct {
Addr string
Addr string `mapstructure:"addr"`
}
// Tracing defines the available tracing configuration.
type Tracing struct {
Enabled bool
Type string
Endpoint string
Collector string
Service string
Enabled bool `mapstructure:"enabled"`
Type string `mapstructure:"type"`
Endpoint string `mapstructure:"endpoint"`
Collector string `mapstructure:"collector"`
Service string `mapstructure:"service"`
}
// TokenManager is the config for using the reva token manager
type TokenManager struct {
JWTSecret string
JWTSecret string `mapstructure:"jwt_secret"`
}
const (
@@ -69,41 +69,41 @@ type Mode int
// Runtime configures the oCIS runtime when running in supervised mode.
type Runtime struct {
Port string
Host string
Extensions string
Port string `mapstructure:"port"`
Host string `mapstructure:"host"`
Extensions string `mapstructure:"extensions"`
}
// Config combines all available configuration parts.
type Config struct {
// Mode is mostly used whenever we need to run an extension. The technical debt this introduces is in regards of
// Mode is mostly used whenever we need to run an extension. The technical debt this introduces is in regard of
// what it does. Supervised (0) loads configuration from a unified config file because of known limitations of Viper; whereas
// Unsupervised (1) MUST parse config from all known sources.
Mode Mode
File string
Registry string
Log Log
Debug Debug
HTTP HTTP
GRPC GRPC
Tracing Tracing
TokenManager TokenManager
Runtime Runtime
Registry string `mapstructure:"registry"`
Log Log `mapstructure:"log"`
Debug Debug `mapstructure:"debug"`
HTTP HTTP `mapstructure:"http"`
GRPC GRPC `mapstructure:"grpc"`
Tracing Tracing `mapstructure:"tracing"`
TokenManager TokenManager `mapstructure:"token_manager"`
Runtime Runtime `mapstructure:"runtime"`
Accounts *accounts.Config
GLAuth *glauth.Config
Graph *graph.Config
GraphExplorer *graphExplorer.Config
IDP *idp.Config
OCS *ocs.Config
Web *web.Config
Proxy *proxy.Config
Settings *settings.Config
Storage *storage.Config
Store *store.Config
Thumbnails *thumbnails.Config
WebDAV *webdav.Config
Accounts *accounts.Config `mapstructure:"accounts"`
GLAuth *glauth.Config `mapstructure:"glauth"`
Graph *graph.Config `mapstructure:"graph"`
GraphExplorer *graphExplorer.Config `mapstructure:"graph_explorer"`
IDP *idp.Config `mapstructure:"idp"`
OCS *ocs.Config `mapstructure:"ocs"`
Web *web.Config `mapstructure:"web"`
Proxy *proxy.Config `mapstructure:"proxy"`
Settings *settings.Config `mapstructure:"settings"`
Storage *storage.Config `mapstructure:"storage"`
Store *store.Config `mapstructure:"store"`
Thumbnails *thumbnails.Config `mapstructure:"thumbnails"`
WebDAV *webdav.Config `mapstructure:"webdav"`
}
// New initializes a new configuration with or without defaults.

View File

@@ -15,12 +15,6 @@ import (
// NewService initializes a new debug service.
func NewService(opts ...Option) *http.Server {
dopts := newOptions(opts...)
dopts.Logger.Info().
Str("transport", "debug").
Str("addr", dopts.Address).
Msg("starting server")
mux := http.NewServeMux()
mux.Handle("/metrics", alice.New(

View File

@@ -32,11 +32,6 @@ type Service struct {
func NewService(opts ...Option) Service {
sopts := newOptions(opts...)
sopts.Logger.Info().
Str("transport", "grpc").
Str("addr", sopts.Address).
Msg("starting server")
mopts := []micro.Option{
// first add a server because it will reset any options
micro.Server(mgrpcs.NewServer()),

View File

@@ -20,11 +20,6 @@ type Service struct {
// NewService initializes a new http service.
func NewService(opts ...Option) Service {
sopts := newOptions(opts...)
sopts.Logger.Info().
Str("transport", transport(sopts.TLSConfig)).
Str("addr", sopts.Address).
Msg("starting server")
wopts := []micro.Option{
micro.Server(mhttps.NewServer(server.TLSConfig(sopts.TLSConfig))),
micro.Address(sopts.Address),

View File

@@ -0,0 +1,4 @@
log:
pretty: true
color: true
level: info

View File

@@ -2,18 +2,16 @@ package command
import (
"os"
"strings"
"github.com/owncloud/ocis/ocis-pkg/sync"
gofig "github.com/gookit/config/v2"
gooyaml "github.com/gookit/config/v2/yaml"
"github.com/owncloud/ocis/ocis-pkg/log"
"github.com/urfave/cli/v2"
"github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/version"
"github.com/owncloud/ocis/ocis/pkg/flagset"
"github.com/owncloud/ocis/ocis/pkg/register"
"github.com/spf13/viper"
)
// Execute is the entry point for the ocis command.
@@ -25,18 +23,15 @@ func Execute() error {
Version: version.String,
Usage: "ownCloud Infinite Scale Stack",
Compiled: version.Compiled(),
Before: func(c *cli.Context) error {
return ParseConfig(c, cfg)
},
Authors: []*cli.Author{
{
Name: "ownCloud GmbH",
Email: "support@owncloud.com",
},
},
Flags: flagset.RootWithConfig(cfg),
}
for _, fn := range register.Commands {
@@ -70,47 +65,16 @@ func NewLogger(cfg *config.Config) log.Logger {
)
}
// ParseConfig load configuration for every extension
// ParseConfig loads ocis configuration from known paths.
func ParseConfig(c *cli.Context, cfg *config.Config) error {
sync.ParsingViperConfig.Lock()
defer sync.ParsingViperConfig.Unlock()
logger := NewLogger(cfg)
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
viper.SetEnvPrefix("OCIS")
viper.AutomaticEnv()
if c.IsSet("config-file") {
viper.SetConfigFile(c.String("config-file"))
} else {
viper.SetConfigName("ocis")
viper.AddConfigPath("/etc/ocis")
viper.AddConfigPath("$HOME/.ocis")
viper.AddConfigPath("./config")
cnf := gofig.NewWithOptions("ocis", gofig.ParseEnv)
cnf.AddDriver(gooyaml.Driver)
err := cnf.LoadFiles("/Users/aunger/code/owncloud/ocis/ocis/pkg/command/ocis_example_config.yaml")
if err != nil {
return err
}
if err := viper.ReadInConfig(); err != nil {
switch err.(type) {
case viper.ConfigFileNotFoundError:
logger.Debug().
Msg("no config found on preconfigured location")
case viper.UnsupportedConfigError:
logger.Fatal().
Err(err).
Msg("unsupported config type")
default:
logger.Fatal().
Err(err).
Msg("failed to read config")
}
}
if err := viper.Unmarshal(&cfg); err != nil {
logger.Fatal().
Err(err).
Msg("failed to parse config")
}
err = cnf.BindStruct("", cfg)
return nil
}

View File

@@ -119,6 +119,7 @@ type SutureService struct {
// NewSutureService creates a new ocs.SutureService
func NewSutureService(cfg *ociscfg.Config) suture.Service {
inheritLogging(cfg)
if cfg.Mode == 0 {
cfg.OCS.Supervised = true
}
@@ -136,3 +137,13 @@ func (s SutureService) Serve(ctx context.Context) error {
return nil
}
// inheritLogging is a poor man's global logging state tip-toeing around circular dependencies. It sets the logging
// of the service to whatever is in the higher config (in this case coming from ocis.yaml) and sets them as defaults,
// being overwritten when the extension parses its config file / env variables.
func inheritLogging(cfg *ociscfg.Config) {
cfg.OCS.Log.File = cfg.Log.File
cfg.OCS.Log.Color = cfg.Log.Color
cfg.OCS.Log.Pretty = cfg.Log.Pretty
cfg.OCS.Log.Level = cfg.Log.Level
}

View File

@@ -67,7 +67,7 @@ func NewLogger(cfg *config.Config) log.Logger {
)
}
// ParseConfig loads proxy configuration from Viper known paths.
// ParseConfig loads proxy configuration from known paths.
func ParseConfig(c *cli.Context, cfg *config.Config) error {
// create a new config and load files and env values onto it since this needs to be thread-safe.
cnf := gofig.NewWithOptions("proxy", gofig.ParseEnv)

View File

@@ -11,7 +11,6 @@ import (
"github.com/owncloud/ocis/ocis-pkg/log"
"github.com/owncloud/ocis/ocis-pkg/version"
"github.com/owncloud/ocis/settings/pkg/config"
"github.com/owncloud/ocis/settings/pkg/flagset"
"github.com/spf13/viper"
"github.com/thejerf/suture/v4"
"github.com/urfave/cli/v2"
@@ -32,7 +31,7 @@ func Execute(cfg *config.Config) error {
},
},
Flags: flagset.RootWithConfig(cfg),
//Flags: flagset.RootWithConfig(cfg),
Before: func(c *cli.Context) error {
cfg.Service.Version = version.String
@@ -122,6 +121,7 @@ type SutureService struct {
// NewSutureService creates a new settings.SutureService
func NewSutureService(cfg *ociscfg.Config) suture.Service {
inheritLogging(cfg)
if cfg.Mode == 0 {
cfg.Settings.Supervised = true
}
@@ -139,3 +139,13 @@ func (s SutureService) Serve(ctx context.Context) error {
return nil
}
// inheritLogging is a poor man's global logging state tip-toeing around circular dependencies. It sets the logging
// of the service to whatever is in the higher config (in this case coming from ocis.yaml) and sets them as defaults,
// being overwritten when the extension parses its config file / env variables.
func inheritLogging(cfg *ociscfg.Config) {
cfg.Settings.Log.File = cfg.Log.File
cfg.Settings.Log.Color = cfg.Log.Color
cfg.Settings.Log.Pretty = cfg.Log.Pretty
cfg.Settings.Log.Level = cfg.Log.Level
}

View File

@@ -7,7 +7,6 @@ import (
"github.com/owncloud/ocis/ocis-pkg/log"
"github.com/owncloud/ocis/ocis-pkg/version"
"github.com/owncloud/ocis/storage/pkg/config"
"github.com/owncloud/ocis/storage/pkg/flagset"
"github.com/spf13/viper"
"github.com/urfave/cli/v2"
)
@@ -27,7 +26,7 @@ func Execute(cfg *config.Config) error {
},
},
Flags: flagset.RootWithConfig(cfg),
//Flags: flagset.RootWithConfig(cfg),
Before: func(c *cli.Context) error {
logger := NewLogger(cfg)

View File

@@ -31,7 +31,7 @@ func StorageMetadata(cfg *config.Config) *cli.Command {
Name: "storage-metadata",
Usage: "Start storage-metadata service",
// TODO(refs) at this point it might make sense delegate log flags to each individual storage command.
Flags: append(flagset.StorageMetadata(cfg), flagset.RootWithConfig(cfg)...),
Flags: flagset.StorageMetadata(cfg),
Category: "Extensions",
Action: func(c *cli.Context) error {
logger := NewLogger(cfg)

View File

@@ -11,7 +11,6 @@ import (
"github.com/owncloud/ocis/ocis-pkg/log"
"github.com/owncloud/ocis/ocis-pkg/version"
"github.com/owncloud/ocis/store/pkg/config"
"github.com/owncloud/ocis/store/pkg/flagset"
"github.com/spf13/viper"
"github.com/thejerf/suture/v4"
"github.com/urfave/cli/v2"
@@ -32,7 +31,7 @@ func Execute(cfg *config.Config) error {
},
},
Flags: flagset.RootWithConfig(cfg),
//Flags: flagset.RootWithConfig(cfg),
Before: func(c *cli.Context) error {
cfg.Service.Version = version.String
@@ -122,6 +121,7 @@ type SutureService struct {
// NewSutureService creates a new store.SutureService
func NewSutureService(cfg *ociscfg.Config) suture.Service {
inheritLogging(cfg)
if cfg.Mode == 0 {
cfg.Store.Supervised = true
}
@@ -139,3 +139,13 @@ func (s SutureService) Serve(ctx context.Context) error {
return nil
}
// inheritLogging is a poor man's global logging state tip-toeing around circular dependencies. It sets the logging
// of the service to whatever is in the higher config (in this case coming from ocis.yaml) and sets them as defaults,
// being overwritten when the extension parses its config file / env variables.
func inheritLogging(cfg *ociscfg.Config) {
cfg.Store.Log.File = cfg.Log.File
cfg.Store.Log.Color = cfg.Log.Color
cfg.Store.Log.Pretty = cfg.Log.Pretty
cfg.Store.Log.Level = cfg.Log.Level
}

View File

@@ -119,6 +119,7 @@ type SutureService struct {
// NewSutureService creates a new thumbnails.SutureService
func NewSutureService(cfg *ociscfg.Config) suture.Service {
inheritLogging(cfg)
if cfg.Mode == 0 {
cfg.Thumbnails.Supervised = true
}
@@ -136,3 +137,13 @@ func (s SutureService) Serve(ctx context.Context) error {
return nil
}
// inheritLogging is a poor man's global logging state tip-toeing around circular dependencies. It sets the logging
// of the service to whatever is in the higher config (in this case coming from ocis.yaml) and sets them as defaults,
// being overwritten when the extension parses its config file / env variables.
func inheritLogging(cfg *ociscfg.Config) {
cfg.Thumbnails.Log.File = cfg.Log.File
cfg.Thumbnails.Log.Color = cfg.Log.Color
cfg.Thumbnails.Log.Pretty = cfg.Log.Pretty
cfg.Thumbnails.Log.Level = cfg.Log.Level
}

View File

@@ -111,6 +111,7 @@ type SutureService struct {
// NewSutureService creates a new web.SutureService
func NewSutureService(cfg *ociscfg.Config) suture.Service {
inheritLogging(cfg)
if cfg.Mode == 0 {
cfg.Web.Supervised = true
}
@@ -128,3 +129,13 @@ func (s SutureService) Serve(ctx context.Context) error {
return nil
}
// inheritLogging is a poor man's global logging state tip-toeing around circular dependencies. It sets the logging
// of the service to whatever is in the higher config (in this case coming from ocis.yaml) and sets them as defaults,
// being overwritten when the extension parses its config file / env variables.
func inheritLogging(cfg *ociscfg.Config) {
cfg.Web.Log.File = cfg.Log.File
cfg.Web.Log.Color = cfg.Log.Color
cfg.Web.Log.Pretty = cfg.Log.Pretty
cfg.Web.Log.Level = cfg.Log.Level
}

View File

@@ -22,7 +22,7 @@ func Server(cfg *config.Config) *cli.Command {
return &cli.Command{
Name: "server",
Usage: "Start integrated server",
Flags: append(flagset.ServerWithConfig(cfg), flagset.RootWithConfig(cfg)...),
Flags: flagset.ServerWithConfig(cfg),
Before: func(ctx *cli.Context) error {
logger := NewLogger(cfg)
if cfg.HTTP.Root != "/" {

View File

@@ -117,6 +117,7 @@ type SutureService struct {
// NewSutureService creates a new webdav.SutureService
func NewSutureService(cfg *ociscfg.Config) suture.Service {
inheritLogging(cfg)
if cfg.Mode == 0 {
cfg.WebDAV.Supervised = true
}
@@ -134,3 +135,13 @@ func (s SutureService) Serve(ctx context.Context) error {
return nil
}
// inheritLogging is a poor man's global logging state tip-toeing around circular dependencies. It sets the logging
// of the service to whatever is in the higher config (in this case coming from ocis.yaml) and sets them as defaults,
// being overwritten when the extension parses its config file / env variables.
func inheritLogging(cfg *ociscfg.Config) {
cfg.WebDAV.Log.File = cfg.Log.File
cfg.WebDAV.Log.Color = cfg.Log.Color
cfg.WebDAV.Log.Pretty = cfg.Log.Pretty
cfg.WebDAV.Log.Level = cfg.Log.Level
}