diff --git a/config/config.go b/config/config.go index a04fbaf9..a6aa39fc 100644 --- a/config/config.go +++ b/config/config.go @@ -4,7 +4,6 @@ package config import ( "errors" "fmt" - "log" "os" "github.com/creasty/defaults" @@ -219,21 +218,17 @@ type License struct { func setDefaults(config *Config) error { // process 'default' tags - log.Println("Start setting defaults") if err := defaults.Set(config); err != nil { return fmt.Errorf("failed to set default configuration: %w", err) } // custom default logic if len(config.AvailableLanguages) == 0 { - log.Println("Setting language defaults") config.AvailableLanguages = append(config.AvailableLanguages, Language{language.Dutch}) // default to Dutch only } if config.OgcAPI.Tiles != nil { - log.Println("Setting tiles defaults") config.OgcAPI.Tiles.Defaults() } - log.Println("Done setting defaults") return nil } diff --git a/config/ogcapi_tiles.go b/config/ogcapi_tiles.go index b01ff3b9..0bd85862 100644 --- a/config/ogcapi_tiles.go +++ b/config/ogcapi_tiles.go @@ -2,7 +2,6 @@ package config import ( "fmt" - "log" "slices" "sort" @@ -23,8 +22,13 @@ type OgcAPITiles struct { func (o *OgcAPITiles) Defaults() { if o.DatasetTiles != nil && o.DatasetTiles.HealthCheck.Srs == DefaultSrs && o.DatasetTiles.HealthCheck.TilePath == nil { - log.Println("Setting dataset tiles healthcheck") o.DatasetTiles.deriveHealthCheckTilePath() + } else if o.Collections != nil { + for _, coll := range o.Collections { + if coll.Tiles != nil && coll.Tiles.GeoDataTiles.HealthCheck.Srs == DefaultSrs && coll.Tiles.GeoDataTiles.HealthCheck.TilePath == nil { + coll.Tiles.GeoDataTiles.deriveHealthCheckTilePath() + } + } } } diff --git a/internal/engine/health.go b/internal/engine/health.go index 17097824..1fe05a55 100644 --- a/internal/engine/health.go +++ b/internal/engine/health.go @@ -1,11 +1,44 @@ package engine import ( + "log" "net/http" + "net/url" + "time" ) func newHealthEndpoint(e *Engine) { - e.Router.Get("/health", func(w http.ResponseWriter, _ *http.Request) { - SafeWrite(w.Write, []byte("OK")) - }) + var target *url.URL + if tilesConfig := e.Config.OgcAPI.Tiles; tilesConfig != nil { + var err error + switch { + case tilesConfig.DatasetTiles != nil: + target, err = url.Parse(tilesConfig.DatasetTiles.TileServer.String() + *tilesConfig.DatasetTiles.HealthCheck.TilePath) + case len(tilesConfig.Collections) > 0 && tilesConfig.Collections[0].Tiles != nil: + target, err = url.Parse(tilesConfig.Collections[0].Tiles.GeoDataTiles.TileServer.String() + *tilesConfig.Collections[0].Tiles.GeoDataTiles.HealthCheck.TilePath) + default: + log.Println("cannot determine health check tilepath, falling back to basic check") + } + if err != nil { + log.Fatalf("invalid health check tilepath: %v", err) + } + } + if target != nil { + client := &http.Client{Timeout: time.Duration(500) * time.Millisecond} + e.Router.Get("/health", func(w http.ResponseWriter, _ *http.Request) { + resp, err := client.Head(target.String()) + if err != nil { + // exact error is irrelevant for health monitoring, but log it for insight + log.Printf("healthcheck failed: %v", err) + w.WriteHeader(http.StatusNotFound) + } else { + w.WriteHeader(resp.StatusCode) + resp.Body.Close() + } + }) + } else { + e.Router.Get("/health", func(w http.ResponseWriter, _ *http.Request) { + SafeWrite(w.Write, []byte("OK")) + }) + } }