Skip to content

Commit

Permalink
feat!: further log customizations
Browse files Browse the repository at this point in the history
  • Loading branch information
hacdias committed Jul 29, 2024
1 parent d5e5052 commit d7faa1f
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 65 deletions.
39 changes: 25 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,31 @@ modify: true
# Default permissions rules to apply at the paths.
rules: []

# Logging configuration
log:
# Logging format ('console', 'json'). Default is 'console'.
format: console
# Enable or disable colors. Default is 'true'. Only applied if format is 'console'.
colors: true
# Logging outputs. You can have more than one output. Default is only 'stderr'.
outputs:
- stderr

# CORS configuration
cors:
# Whether or not CORS configuration should be applied. Default is 'false'.
enabled: true
credentials: true
allowed_headers:
- Depth
allowed_hosts:
- http://localhost:8080
allowed_methods:
- GET
exposed_headers:
- Content-Length
- Content-Range

# The list of users. If users is empty, then there will be no authentication.
users:
# Example 'admin' user with plaintext password.
Expand Down Expand Up @@ -108,20 +133,6 @@ users:
# a regular expression.
- regex: "^.+\.js$"
modify: true

# CORS configuration
cors:
enabled: true
credentials: true
allowed_headers:
- Depth
allowed_hosts:
- http://localhost:8080
allowed_methods:
- GET
exposed_headers:
- Content-Length
- Content-Range
```
### CORS
Expand Down
31 changes: 7 additions & 24 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,17 @@ import (
"github.com/hacdias/webdav/v5/lib"
"github.com/spf13/cobra"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)

func init() {
flags := rootCmd.Flags()
flags.StringP("config", "c", "", "config file path")
flags.StringP("address", "a", lib.DefaultAddress, "address to listen on")
flags.IntP("port", "p", lib.DefaultPort, "port to listen on")
flags.BoolP("tls", "t", lib.DefaultTLS, "enable TLS")
flags.String("cert", lib.DefaultCert, "path to TLS certificate")
flags.String("key", lib.DefaultKey, "path to TLS key")
flags.StringP("address", "a", lib.DefaultAddress, "address to listen on")
flags.IntP("port", "p", lib.DefaultPort, "port to listen on")
flags.StringP("prefix", "P", lib.DefaultPrefix, "URL path prefix")
flags.String("log_format", lib.DefaultLogFormat, "logging format")
}

var rootCmd = &cobra.Command{
Expand Down Expand Up @@ -57,14 +55,15 @@ set WD_CERT.`,
return err
}

// Create HTTP handler from the config
handler, err := lib.NewHandler(cfg)
// Setup the logger based on the configuration
logger, err := cfg.GetLogger()
if err != nil {
return err
}
zap.ReplaceGlobals(logger)

// Setup the logger based on the configuration
err = setupLogger(cfg)
// Create HTTP handler from the config
handler, err := lib.NewHandler(cfg)
if err != nil {
return err
}
Expand Down Expand Up @@ -126,19 +125,3 @@ func getListener(cfg *lib.Config) (net.Listener, error) {

return net.Listen(network, address)
}

func setupLogger(cfg *lib.Config) error {
loggerConfig := zap.NewProductionConfig()
loggerConfig.DisableCaller = true
if cfg.Debug {
loggerConfig.Level = zap.NewAtomicLevelAt(zap.DebugLevel)
}
loggerConfig.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
loggerConfig.Encoding = cfg.LogFormat
logger, err := loggerConfig.Build()
if err != nil {
return err
}
zap.ReplaceGlobals(logger)
return nil
}
62 changes: 36 additions & 26 deletions lib/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,16 @@ import (
"github.com/spf13/pflag"
"github.com/spf13/viper"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)

const (
DefaultDirectory = "."
DefaultModify = false
DefaultDebug = false
DefaultNoSniff = false
DefaultTLS = false
DefaultCert = "cert.pem"
DefaultKey = "key.pem"
DefaultAddress = "0.0.0.0"
DefaultPort = 6065
DefaultPrefix = "/"
DefaultLogFormat = "console"
DefaultTLS = false
DefaultCert = "cert.pem"
DefaultKey = "key.pem"
DefaultAddress = "0.0.0.0"
DefaultPort = 6065
DefaultPrefix = "/"
)

type Config struct {
Expand All @@ -36,7 +32,7 @@ type Config struct {
Key string
Prefix string
NoSniff bool
LogFormat string `mapstructure:"log_format"`
Log Log
CORS CORS
Users []User
}
Expand All @@ -50,11 +46,6 @@ func ParseConfig(filename string, flags *pflag.FlagSet) (*Config, error) {
if err != nil {
return nil, err
}

err = v.BindPFlag("LogFormat", flags.Lookup("log_format"))
if err != nil {
return nil, err
}
}

// Configuration file settings
Expand All @@ -74,19 +65,21 @@ func ParseConfig(filename string, flags *pflag.FlagSet) (*Config, error) {
// empty or false.

// Defaults shared with flags
v.SetDefault("Directory", DefaultDirectory)
v.SetDefault("Modify", DefaultModify)
v.SetDefault("Debug", DefaultDebug)
v.SetDefault("NoSniff", DefaultNoSniff)
v.SetDefault("TLS", DefaultTLS)
v.SetDefault("Cert", DefaultCert)
v.SetDefault("Key", DefaultKey)
v.SetDefault("Address", DefaultAddress)
v.SetDefault("Port", DefaultPort)
v.SetDefault("Prefix", DefaultPrefix)
v.SetDefault("Log_Format", DefaultLogFormat)

// Other defaults
v.SetDefault("Directory", ".")
v.SetDefault("Modify", false)
v.SetDefault("Debug", false)
v.SetDefault("NoSniff", false)
v.SetDefault("Log.Format", "console")
v.SetDefault("Log.Outputs", []string{"stderr"})
v.SetDefault("Log.Colors", true)
v.SetDefault("CORS.Allowed_Headers", []string{"*"})
v.SetDefault("CORS.Allowed_Hosts", []string{"*"})
v.SetDefault("CORS.Allowed_Methods", []string{"*"})
Expand Down Expand Up @@ -135,10 +128,6 @@ func ParseConfig(filename string, flags *pflag.FlagSet) (*Config, error) {
func (c *Config) Validate() error {
var err error

if len(c.Users) == 0 {
zap.L().Warn("unprotected config: no users have been set, so no authentication will be used")
}

c.Directory, err = filepath.Abs(c.Directory)
if err != nil {
return fmt.Errorf("invalid config: %w", err)
Expand Down Expand Up @@ -179,6 +168,27 @@ func (c *Config) Validate() error {
return nil
}

func (cfg *Config) GetLogger() (*zap.Logger, error) {
loggerConfig := zap.NewProductionConfig()
loggerConfig.DisableCaller = true
if cfg.Debug {
loggerConfig.Level = zap.NewAtomicLevelAt(zap.DebugLevel)
}
if cfg.Log.Colors && cfg.Log.Format != "json" {
loggerConfig.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
}
loggerConfig.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
loggerConfig.Encoding = cfg.Log.Format
loggerConfig.OutputPaths = cfg.Log.Outputs
return loggerConfig.Build()
}

type Log struct {
Format string
Colors bool
Outputs []string
}

type CORS struct {
Enabled bool
Credentials bool
Expand Down
4 changes: 3 additions & 1 deletion lib/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ func TestConfigDefaults(t *testing.T) {
require.EqualValues(t, DefaultAddress, cfg.Address)
require.EqualValues(t, DefaultPort, cfg.Port)
require.EqualValues(t, DefaultPrefix, cfg.Prefix)
require.EqualValues(t, DefaultLogFormat, cfg.LogFormat)
require.EqualValues(t, "console", cfg.Log.Format)
require.EqualValues(t, true, cfg.Log.Colors)
require.EqualValues(t, []string{"stderr"}, cfg.Log.Outputs)

dir, err := os.Getwd()
require.NoError(t, err)
Expand Down
4 changes: 4 additions & 0 deletions lib/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ func NewHandler(c *Config) (http.Handler, error) {
}).Handler(h), nil
}

if len(c.Users) == 0 {
zap.L().Warn("unprotected config: no users have been set, so no authentication will be used")
}

return h, nil
}

Expand Down

0 comments on commit d7faa1f

Please sign in to comment.