package setup import ( "io" "log" "os" "github.com/hashicorp/go-syslog" "github.com/mholt/caddy/middleware" caddylog "github.com/mholt/caddy/middleware/log" "github.com/mholt/caddy/server" "gopkg.in/natefinch/lumberjack.v2" ) // Log sets up the logging middleware. func Log(c *Controller) (middleware.Middleware, error) { rules, err := logParse(c) if err != nil { return nil, err } // Open the log files for writing when the server starts c.Startup = append(c.Startup, func() error { for i := 0; i < len(rules); i++ { var err error var file io.Writer if rules[i].OutputFile == "stdout" { file = os.Stdout } else if rules[i].OutputFile == "stderr" { file = os.Stderr } else if rules[i].OutputFile == "syslog" { file, err = gsyslog.NewLogger(gsyslog.LOG_INFO, "LOCAL0", "caddy") if err != nil { return err } } else { _, err = os.OpenFile(rules[i].OutputFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644) if err != nil { return err } file = &lumberjack.Logger{ Filename: rules[i].OutputFile, MaxSize: 20, MaxBackups: 10, } } rules[i].Log = log.New(file, "", 0) } return nil }) return func(next middleware.Handler) middleware.Handler { return caddylog.Logger{Next: next, Rules: rules, ErrorFunc: server.DefaultErrorFunc} }, nil } func logParse(c *Controller) ([]caddylog.Rule, error) { var rules []caddylog.Rule for c.Next() { args := c.RemainingArgs() if len(args) == 0 { // Nothing specified; use defaults rules = append(rules, caddylog.Rule{ PathScope: "/", OutputFile: caddylog.DefaultLogFilename, Format: caddylog.DefaultLogFormat, }) } else if len(args) == 1 { // Only an output file specified rules = append(rules, caddylog.Rule{ PathScope: "/", OutputFile: args[0], Format: caddylog.DefaultLogFormat, }) } else { // Path scope, output file, and maybe a format specified format := caddylog.DefaultLogFormat if len(args) > 2 { switch args[2] { case "{common}": format = caddylog.CommonLogFormat case "{combined}": format = caddylog.CombinedLogFormat default: format = args[2] } } rules = append(rules, caddylog.Rule{ PathScope: args[0], OutputFile: args[1], Format: format, }) } } return rules, nil }