package main import ( "context" "flag" "go/weather/internal" "go/weather/internal/version" "go/weather/internal/web" "go/weather/pkg/logger" "log" "os" "os/signal" "strings" "time" "go.uber.org/zap" "go.uber.org/zap/zapcore" ) type flagParameter struct { configFile string logLevel zapcore.Level logOutput string wait time.Duration } func main() { f := flagParameter{} var logLevel string flag.DurationVar(&f.wait, "graceful-timeout", time.Second*15, "the duration for which the server gracefully wait for existing connections to finish - e.g. 15s or 1m") flag.StringVar(&f.configFile, "filename", "config.hcl", "configuration filename") flag.StringVar(&logLevel, "logLevel", "info", "Log level") flag.StringVar(&f.logOutput, "logOutput", "logs/weather.log", "Output log path") flag.Parse() f.logLevel = parseLogLevel(logLevel) //logger loggerLevel := zap.NewAtomicLevelAt(f.logLevel) defaultLogger := logger.NewLogger("weather", f.logOutput, loggerLevel) defer defaultLogger.Sync() //configuration parsing config := internal.ParseConfiguration(defaultLogger.Sugar(), f.configFile) //http addr := web.NewListenAddr(config.Listen, config.Port) defaultLogger.Sugar().Infof("Weather server is listening on %s", addr) server := web.New(defaultLogger, addr, version.String()). WithTLSConfigure(). WithHandler(config). WithHTTPLogging(). WithErrorLogging() go func() { if err := server.Serve(); err != nil { defaultLogger.Sugar().Info(err) } }() c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt) <-c ctx, cancel := context.WithTimeout(context.Background(), f.wait) defer cancel() server.Shutdown(ctx) log.Println("shutting down") os.Exit(0) } func parseLogLevel(logLevel string) zapcore.Level { zapLevel := zap.InfoLevel switch strings.ToUpper(logLevel) { case "DEBUG": zapLevel = zapcore.DebugLevel case "INFO": zapLevel = zapcore.InfoLevel case "WARN": zapLevel = zapcore.WarnLevel case "ERROR": zapLevel = zapcore.ErrorLevel case "PANIC": zapLevel = zapcore.PanicLevel case "FATAL": zapLevel = zapcore.FatalLevel } return zapLevel }