package main import ( "context" "flag" "go/weather/internal" "go/weather/internal/poller" "go/weather/internal/storage" "go/weather/internal/web" "go/weather/pkg/logger" "io" "os" "os/signal" "strings" "time" "go.uber.org/zap" "go.uber.org/zap/zapcore" ) func main() { f := flagDefinition() loggerLevel := zap.NewAtomicLevelAt(f.logLevel) defaultLogger := logger.NewLogger("poller", f.logOutput, loggerLevel) sLogger := defaultLogger.Sugar() defer defaultLogger.Sync() config := internal.ParseConfiguration(sLogger, f.filename) addr := web.NewListenAddr("api.openweathermap.org", 443) poller := poller.NewWeatherPoller(defaultLogger, addr, 45.75, 4.85, config.OpenweatherSecret) s3storage := storage.NewS3Storage(defaultLogger, &config.S3Storage) var data io.ReadCloser go func() { for { data = poller.Poll() if data != nil { s3storage.Store(context.Background(), data) } defaultLogger.Sugar().Debug("Wait next poll") time.Sleep(f.interval) } }() c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt) <-c data.Close() defaultLogger.Sugar().Info("shutting down") os.Exit(0) } //flagParameter contain all application customizable parameter type flagParameter struct { interval time.Duration filename string logLevel zapcore.Level logOutput string } func flagDefinition() flagParameter { var logLevel string f := flagParameter{} flag.DurationVar(&f.interval, "check-interval", time.Second*30, "the sleep duration between multiple call to remote weather api") flag.StringVar(&f.filename, "filename", "config.hcl", "configuration filename") flag.StringVar(&logLevel, "logLevel", "info", "Log level") flag.StringVar(&f.logOutput, "logOutput", "weather.log", "Output log path") flag.Parse() f.logLevel = parseLogLevel(logLevel) return f } 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 }