GeoWebCache exposes useful runtime statistics on its status page, but most production monitoring stacks need those values as structured Prometheus metrics.
If you run GeoServer/GeoWebCache behind real user traffic, “CPU and memory look fine” is not observability. You want to know what the cache is doing, what the backend is doing, and when behavior changes.
That gap is exactly why we built gwc-exporter.
You can find the source code here: https://github.com/SysHead-Labs/gwc-exporter,
and docker images here: https://hub.docker.com/r/syshead/gwc-exporter
gwc-exporter scrapes the GeoWebCache HTML status page, parses the runtime values, and exposes them on /metrics in Prometheus format. You can run it standalone, in Docker, or as a Kubernetes service discovered by Prometheus Operator.
What You Get (and Why It Matters)
GeoWebCache provides operational signals such as:
- request totals and rates
- bandwidth / bytes served
- cache hit ratios
- interval statistics (peaks, timestamps)
- startup and uptime metadata
- in-memory cache counters and occupancy (when enabled)
Those values exist, but they are not natively scrapeable as Prometheus metric families. The exporter converts that HTML into labeled, typed metrics you can graph and alert on.
This makes a difference immediately:
- you can alert on cache hit ratio regressions
- you can catch tile generation failures early
- you can detect backend WMS degradation indirectly (miss spikes + latency)
- you can see per-interval behavior instead of reading raw logs
How gwc-exporter Works
At scrape time, the collector:
- Calls the configured GeoWebCache status URL (
GWC_TARGET_URL). - Normalizes the HTML and extracts key fields (regex-based extractors).
- Emits Prometheus metrics under the
gwcnamespace. - Sets
gwc_upto “0” on scrape failures and logs the failure reason.
Stability behavior
GeoWebCache setups vary. Some deployments expose in-memory cache stats; some don’t.
To keep dashboards and alerts stable:
- If in-memory cache stats are absent, the exporter still works.
gwc_memcache_presentis set to “0”.- Memcache metric families are still emitted with “0” values to avoid “missing series” breakage.
Configuration
Environment variables:
GWC_TARGET_URL(defaulthttp://127.0.0.1:8080/geowebcache)GWC_WEB_LISTEN_ADDRESS(default:9109)GWC_WEB_TELEMETRY_PATH(default/metrics)GWC_SCRAPE_TIMEOUT(default5s)
CLI flags are also supported and override env vars when explicitly set.
Run It Standalone
cd src go mod tidy go build -ldflags="-s -w" -o gwc-exporter gwc-exporter.go ./gwc-exporter \ -target.url "http://geowebcache:8080/geowebcache" \ -web.listen-address ":9109" \ -web.telemetry-path "/metrics"
Scrape endpoint:
docker pull syshead/gwc-exporter:latest docker run --rm -p 9109:9109 \ -e GWC_TARGET_URL="http://geowebcache:8080/geowebcache" \ syshead/gwc-exporter:latest
Scrape endpoint:
http://127.0.0.1:9109/metrics
Run It in Docker
docker pull syshead/gwc-exporter:latest docker run --rm -p 9109:9109 \ -e GWC_TARGET_URL="http://geowebcache:8080/geowebcache" \ syshead/gwc-exporter:latest
Multi-arch build (amd64 + arm64):
docker buildx create --use --name gwc-builder docker buildx build \ --platform linux/amd64,linux/arm64 \ -f docker/Dockerfile \ -t syshead/gwc-exporter:latest \ --push \ .
Run It in Kubernetes
Apply the included manifests:
kubectl apply -f kubernetes/configmap.yaml kubectl apply -f kubernetes/deployment.yaml kubectl apply -f kubernetes/service.yaml
The deployment uses envFrom with gwc-exporter-config exposes a named metrics port.
A simple, Prometheus-friendly convention is:
– namespace: monitorng
– service: gwc-exporter
– port name: metrics
Prometheus Operator Integration
Use the included ScrapeConfig example:
prometheus/scrape-gwc-example.yaml
It discovers Kubernetes Endpoints, keeps only:
- namespace
monitoring - service
gwc-exporter - endpoint port
metrics
Then it scrapes /metrics and sets job=gwc-exporter.
Grafana Dashboard
Import:
grafana/gwc-exporter-dashboard.json
The dashboard is aligned with current exporter metric families, including:
– always-available core runtime metrics
– a collapsible in-memory cache section
– total counters and rates for key traffic/cache signals
Operational Notes
- Liveness/readiness probes typically use
/-/healthy(process health). - Target reachability is reflected through
gwc_upand exporter logs. - For alerting, combine
gwc_up == 0with scrape error duration thresholds.
Closing
If you operate GeoServer/GeoWebCache in production, this exporter gives you a practical path from HTML runtime stats to Prometheus-native observability.
GeoWebCache should not be a blind spot.