func readConfig(path string, pidFile string) (*guerrilla.AppConfig, error) {
	appConfig, err := d.LoadConfig(path)
	if err != nil {
		return &appConfig, fmt.Errorf("could not read config file: %s", err.Error())
	}
	if len(pidFile) > 0 {
		appConfig.PidFile = pidFile
	} else if len(appConfig.PidFile) == 0 {
		appConfig.PidFile = defaultPidFile
	}
	if verbose {
		appConfig.LogLevel = "debug"
	}
	return &appConfig, nil
}
ReadConfig is called at startup, or when a SIG_HUP is caught
package main
import (
	"fmt"
	"os"
	"os/signal"
	"syscall"
	"time"
	"github.com/flashmob/go-guerrilla"
	"github.com/flashmob/go-guerrilla/log"
	_ "github.com/flashmob/go-guerrilla/backends/storage/redigo"
	_ "github.com/flashmob/go-guerrilla/mail/encoding"
	"github.com/spf13/cobra"
	_ "github.com/go-sql-driver/mysql"
)
const (
	defaultPidFile = "/var/run/go-guerrilla.pid"
)
var (
	configPath string
	pidFile    string
	serveCmd = &cobra.Command{
		Use:   "serve",
		Short: "start the daemon and start all available servers",
		Run:   serve,
	}
	signalChannel = make(chan os.Signal, 1)  
	mainlog       log.Logger
	d guerrilla.Daemon
)
func init() {
	var err error
	mainlog, err = log.GetLogger(log.OutputStderr.String(), log.InfoLevel.String())
	if err != nil && mainlog != nil {
		mainlog.WithError(err).Errorf("Failed creating a logger to %s", log.OutputStderr)
	}
	cfgFile := "goguerrilla.conf"  
	if _, err := os.Stat(cfgFile); err != nil {
		cfgFile = "goguerrilla.conf.json"  
	}
	serveCmd.PersistentFlags().StringVarP(&configPath, "config", "c",
		cfgFile, "Path to the configuration file")
	serveCmd.PersistentFlags().StringVarP(&pidFile, "pidFile", "p",
		"", "Path to the pid file")
	rootCmd.AddCommand(serveCmd)
}
func sigHandler() {
	signal.Notify(signalChannel,
		syscall.SIGHUP,
		syscall.SIGTERM,
		syscall.SIGQUIT,
		syscall.SIGINT,
		syscall.SIGKILL,
		syscall.SIGUSR1,
		os.Kill,
	)
	for sig := range signalChannel {
		if sig == syscall.SIGHUP {
			if ac, err := readConfig(configPath, pidFile); err == nil {
				_ = d.ReloadConfig(*ac)
			} else {
				mainlog.WithError(err).Error("Could not reload config")
			}
		} else if sig == syscall.SIGUSR1 {
			if err := d.ReopenLogs(); err != nil {
				mainlog.WithError(err).Error("reopening logs failed")
			}
		} else if sig == syscall.SIGTERM || sig == syscall.SIGQUIT || sig == syscall.SIGINT || sig == os.Kill {
			mainlog.Infof("Shutdown signal caught")
			go func() {
				select {
				case <-time.After(time.Second * 60):
					mainlog.Error("graceful shutdown timed out")
					os.Exit(1)
				}
			}()
			d.Shutdown()
			mainlog.Infof("Shutdown completed, exiting.")
			return
		} else {
			mainlog.Infof("Shutdown, unknown signal caught")
			return
		}
	}
}
func serve(cmd *cobra.Command, args []string) {
	logVersion()
	d = guerrilla.Daemon{Logger: mainlog}
	c, err := readConfig(configPath, pidFile)
	if err != nil {
		mainlog.WithError(err).Fatal("Error while reading config")
	}
	_ = d.SetConfig(*c)
	if ok, maxClients, fileLimit := guerrilla.CheckFileLimit(c); !ok {
		mainlog.Fatalf("Combined max clients for all servers (%d) is greater than open file limit (%d). "+
			"Please increase your open file limit or decrease max clients.", maxClients, fileLimit)
	}
	err = d.Start()
	if err != nil {
		mainlog.WithError(err).Error("Error(s) when creating new server(s)")
		os.Exit(1)
	}
	sigHandler()
}