115 lines
3 KiB
Go
115 lines
3 KiB
Go
package main
|
|
|
|
import (
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"os/signal"
|
|
"syscall"
|
|
|
|
apiv1 "git.ar21.de/yolokube/country-geo-locations/api/v1"
|
|
"git.ar21.de/yolokube/country-geo-locations/internal/cache"
|
|
"git.ar21.de/yolokube/country-geo-locations/internal/cmd"
|
|
csvimporter "git.ar21.de/yolokube/country-geo-locations/internal/csv_importer"
|
|
"git.ar21.de/yolokube/country-geo-locations/internal/database"
|
|
"git.ar21.de/yolokube/country-geo-locations/internal/downloader"
|
|
"git.ar21.de/yolokube/country-geo-locations/internal/exporter"
|
|
"github.com/go-chi/chi/v5"
|
|
"github.com/go-chi/chi/v5/middleware"
|
|
"github.com/go-chi/render"
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
|
)
|
|
|
|
func main() {
|
|
cli := cmd.CLI{}
|
|
queue := exporter.NewRequestDataQueue()
|
|
appSettings, err := cli.Parse()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
handleGracefulShutdown()
|
|
|
|
exporterMiddleware := exporter.NewMiddleware(queue)
|
|
r := chi.NewRouter()
|
|
r.Use(middleware.RequestID)
|
|
r.Use(middleware.Logger)
|
|
r.Use(middleware.Recoverer)
|
|
r.Use(exporterMiddleware)
|
|
r.Use(render.SetContentType(render.ContentTypeJSON))
|
|
|
|
ctx := downloader.NewContext(appSettings.DataFile, appSettings.DataURL)
|
|
if !ctx.FileExists() {
|
|
if downloadErr := ctx.Download(); downloadErr != nil {
|
|
log.Fatal(downloadErr)
|
|
}
|
|
log.Printf("saved file to %s\n", ctx.Filename)
|
|
}
|
|
|
|
cache := cache.NewCache(appSettings.CacheTTL)
|
|
db, err := database.NewDatabase(appSettings)
|
|
if err != nil {
|
|
log.Fatal("database creation failed", err)
|
|
}
|
|
|
|
if appSettings.EnableExporter {
|
|
go func() {
|
|
err = enableExporter(appSettings, cache, db, queue)
|
|
if err != nil {
|
|
log.Panic(err)
|
|
}
|
|
}()
|
|
log.Println("prometheus exporter started at", appSettings.ExporterAddress)
|
|
}
|
|
|
|
log.Println("importing data from file", appSettings.DataFile)
|
|
err = csvimporter.ImportCSV(appSettings.DataFile, db)
|
|
if err != nil {
|
|
log.Fatal("data Import from file failed", err)
|
|
}
|
|
log.Println("imported data from file successful")
|
|
|
|
lh := apiv1.NewLocationHandler(cache, db)
|
|
r.Mount("/api/v1", apiv1.NewRouter(lh))
|
|
|
|
server := &http.Server{
|
|
Addr: appSettings.ServerAddress,
|
|
Handler: r,
|
|
ReadHeaderTimeout: appSettings.ReadHeaderTimeout,
|
|
}
|
|
|
|
log.Println("starting server at", server.Addr)
|
|
if err = server.ListenAndServe(); err != nil {
|
|
log.Panic(err)
|
|
}
|
|
}
|
|
|
|
func enableExporter(
|
|
settings *cmd.AppSettings,
|
|
cache *cache.Cache,
|
|
db *database.Database,
|
|
queue *exporter.RequestDataQueue,
|
|
) error {
|
|
prometheus.MustRegister(exporter.NewCollector(settings, cache, db, queue))
|
|
|
|
metricsServer := &http.Server{
|
|
Addr: settings.ExporterAddress,
|
|
Handler: promhttp.Handler(),
|
|
ReadHeaderTimeout: settings.ReadHeaderTimeout,
|
|
}
|
|
|
|
return metricsServer.ListenAndServe()
|
|
}
|
|
|
|
func handleGracefulShutdown() {
|
|
var signals = make(chan os.Signal, 1)
|
|
|
|
signal.Notify(signals, syscall.SIGTERM, syscall.SIGINT)
|
|
|
|
go func() {
|
|
sig := <-signals
|
|
log.Printf("caught signal: %+v", sig)
|
|
os.Exit(0)
|
|
}()
|
|
}
|