func setLogger(file string) (io.Writer, error) {
	logger := os.Stderr
	if file != "" {
		var err error
		if logger, err = os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666); err != nil {
			return nil, err
		}
	}
	return logger, nil
}
Creates a log file or returns os.Stderr if none is provided.
package main
import (
	"context"
	"flag"
	"fmt"
	"io"
	stdlog "log"
	"net"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"
	"github.com/intuit/ami-query/amicache"
	"github.com/intuit/ami-query/api/query"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/sts"
	"github.com/go-kit/kit/log"
	"github.com/go-kit/kit/log/level"
	"github.com/gorilla/handlers"
	"github.com/gorilla/mux"
	"github.com/oklog/oklog/pkg/group"
)
var httpClient = &http.Client{
	Transport: &http.Transport{
		Proxy:                 http.ProxyFromEnvironment,
		MaxIdleConns:          100,
		IdleConnTimeout:       90 * time.Second,
		ExpectContinueTimeout: 1 * time.Second,
		MaxIdleConnsPerHost:   1,
		DisableKeepAlives:     false,
		Dial: (&net.Dialer{
			Timeout:   30 * time.Second,
			KeepAlive: 30 * time.Second,
		}).Dial,
	},
}
func main() {
	var (
		debug        = flag.Bool("debug", false, "Enable debug logging")
		printVersion = flag.Bool("version", false, "Prints the version and exits")
	)
	stdlog.SetFlags(0)
	flag.Parse()
	if *printVersion {
		stdlog.Print(version)
		os.Exit(0)
	}
	sess, err := session.NewSession(aws.NewConfig().WithHTTPClient(httpClient))
	if err != nil {
		stdlog.Fatalf("failed to create AWS session: %v", err)
	}
	cfg, err := NewConfig()
	if err != nil {
		stdlog.Fatalf("failed to parse configuration: %v", err)
	}
	appLogger, err := setLogger(cfg.AppLog)
	if err != nil {
		stdlog.Fatalf("failed to set application logging output: %v", err)
	}
	httpLogger, err := setLogger(cfg.HTTPLog)
	if err != nil {
		stdlog.Fatalf("failed to set HTTP logging output: %v", err)
	}
	logger := log.NewLogfmtLogger(log.NewSyncWriter(appLogger))
	logger = log.With(logger, "ts", log.TimestampFormat(time.Now, "2006-01-02T15:04:05.000"))
	if *debug {
		logger = level.NewFilter(logger, level.AllowAll())
	} else {
		logger = level.NewFilter(logger, level.AllowInfo())
	}
	stdlog.SetOutput(log.NewStdlibAdapter(logger))
	router := mux.NewRouter()
	server := http.Server{
		Addr:    cfg.ListenAddr,
		Handler: router,
		WriteTimeout: 15 * time.Second,
		ReadTimeout:  15 * time.Second,
	}
	cache := amicache.New(
		sts.New(sess),
		cfg.RoleName,
		cfg.OwnerIDs,
		amicache.TagFilter(cfg.TagFilter),
		amicache.StateTag(cfg.StateTag),
		amicache.Regions(cfg.Regions...),
		amicache.TTL(cfg.CacheTTL),
		amicache.MaxConcurrentRequests(cfg.CacheMaxConcurrentRequests),
		amicache.MaxRequestRetries(cfg.CacheMaxRequestRetries),
		amicache.CollectLaunchPermissions(cfg.CollectLaunchPermissions),
		amicache.HTTPClient(httpClient),
		amicache.Logger(logger),
	)
	api := handlers.CombinedLoggingHandler(
		httpLogger,
		handlers.CompressHandler(query.NewAPI(cache)),
	)
	if len(cfg.CorsAllowedOrigins) > 0 {
		api = handlers.CORS(
			handlers.AllowedMethods([]string{"GET"}),
			handlers.AllowedOrigins(cfg.CorsAllowedOrigins),
		)(api)
	}
	router.Handle(query.APIPathQuery, api).
		HeadersRegexp("Accept", `(application/vnd\.ami-query-v1\+json|\*/\*)`).
		Methods("GET")
	g := group.Group{}
	ctx, cancel := context.WithCancel(context.Background())
	warmed := make(chan struct{})
	g.Add(func() error {
		return cache.Run(ctx, warmed)
	}, func(error) {
		level.Info(logger).Log("msg", "stopping cache")
		cache.Stop()
		level.Info(logger).Log("msg", "cache stopped")
		cancel()
	})
	g.Add(func() error {
		<-warmed  
		if cfg.SSLCert != "" && cfg.SSLKey != "" {
			return server.ListenAndServeTLS(cfg.SSLCert, cfg.SSLKey)
		}
		return server.ListenAndServe()
	}, func(error) {
		ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
		defer cancel()
		level.Info(logger).Log("msg", "gracefully shutting down http server")
		if err := server.Shutdown(ctx); err != nil {
			level.Error(logger).Log("msg", "http graceful shutdown failed", "error", err)
		}
		level.Info(logger).Log("msg", "http server shutdown")
	})
	g.Add(func() error {
		ch := make(chan os.Signal, 1)
		signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
		defer signal.Stop(ch)
		return sigTrapper(ctx, ch)
	}, func(error) {
		cancel()
	})
	if err = g.Run(); err != nil {
		level.Info(logger).Log("service", err)
		os.Exit(1)
	}
}
func sigTrapper(ctx context.Context, ch <-chan os.Signal) error {
	select {
	case sig := <-ch:
		return fmt.Errorf("received signal %s", sig)
	case <-ctx.Done():
		return ctx.Err()
	}
}