add: Publish GHC runtime metrics to Prometheus metrics endpoint
This commit is contained in:
committed by
Wolfgang Walther
parent
c09394517d
commit
85d91e5c0a
@@ -14,6 +14,7 @@ All notable changes to this project will be documented in this file. From versio
|
||||
- Add `Vary` header to responses by @develop7 in #4609
|
||||
- Add config `db-timezone-enabled` for optional querying of timezones by @taimoorzaeem in #4751
|
||||
- Log schema cache queries timings on `log-level=debug` by @steve-chavez in #4805
|
||||
- Add GHC runtime metrics to the metrics endpoint by @mkleczek in #4862
|
||||
|
||||
### Fixed
|
||||
|
||||
|
||||
+4
-1
@@ -45,7 +45,9 @@ filename
|
||||
FreeBSD
|
||||
fts
|
||||
fullstack
|
||||
GC
|
||||
GeoJSON
|
||||
GHC
|
||||
Github
|
||||
Google
|
||||
grantor
|
||||
@@ -147,6 +149,7 @@ RESTful
|
||||
RLS
|
||||
RPC
|
||||
RSA
|
||||
RTS
|
||||
safeupdate
|
||||
savepoint
|
||||
schemas
|
||||
@@ -200,4 +203,4 @@ webuser
|
||||
wfts
|
||||
www
|
||||
debouncing
|
||||
deduplicates
|
||||
deduplicates
|
||||
|
||||
@@ -238,6 +238,45 @@ pgrst_jwt_cache_evictions_total
|
||||
|
||||
The total number of JWT cache evictions.
|
||||
|
||||
GHC Runtime Metrics
|
||||
-------------------
|
||||
|
||||
PostgREST can also expose GHC runtime system metrics. These use the ``ghc_*``
|
||||
prefix and include
|
||||
`GHC RTS statistics <https://ghc.gitlab.haskell.org/ghc/doc/libraries/base-4.22.0.0-inplace/GHC-Stats.html#g:1>`_
|
||||
for runtime allocation, garbage collection, memory, and CPU/elapsed time.
|
||||
|
||||
These are useful for monitoring PostgREST process health and diagnosing memory
|
||||
pressure or GC behavior.
|
||||
|
||||
To expose these metrics, enable GHC RTS statistics when starting PostgREST:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
postgrest +RTS -T -RTS
|
||||
|
||||
When enabled, the admin ``/metrics`` endpoint includes samples such as:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
# HELP ghc_gcs_total Total number of GCs
|
||||
# TYPE ghc_gcs_total counter
|
||||
ghc_gcs_total 1
|
||||
# HELP ghc_allocated_bytes_total Total bytes allocated
|
||||
# TYPE ghc_allocated_bytes_total counter
|
||||
ghc_allocated_bytes_total 12345678
|
||||
|
||||
Other available GHC runtime metrics include:
|
||||
|
||||
- ``ghc_gcs_total``
|
||||
- ``ghc_major_gcs_total``
|
||||
- ``ghc_allocated_bytes_total``
|
||||
- ``ghc_max_live_bytes``
|
||||
- ``ghc_max_mem_in_use_bytes``
|
||||
- ``ghc_mutator_cpu_seconds_total``
|
||||
- ``ghc_gc_cpu_seconds_total``
|
||||
- ``ghc_elapsed_seconds_total``
|
||||
|
||||
Traces
|
||||
======
|
||||
|
||||
|
||||
@@ -136,6 +136,7 @@ library
|
||||
, parsec >= 3.1.11 && < 3.2
|
||||
, postgresql-libpq >= 0.10
|
||||
, prometheus-client >= 1.1.1 && < 1.2.0
|
||||
, prometheus-metrics-ghc >= 1.0.1.2 && < 1.2
|
||||
, protolude >= 0.3.1 && < 0.4
|
||||
, regex-tdfa >= 1.2.2 && < 1.4
|
||||
, retry >= 0.7.4 && < 0.10
|
||||
|
||||
@@ -13,10 +13,13 @@ module PostgREST.Metrics
|
||||
import qualified Data.ByteString.Lazy as LBS
|
||||
import qualified Hasql.Pool.Observation as SQL
|
||||
|
||||
import Prometheus
|
||||
import GHC.Stats (getRTSStatsEnabled)
|
||||
import Prometheus
|
||||
import qualified Prometheus.Metric.GHC as PMG
|
||||
|
||||
import PostgREST.Observation
|
||||
|
||||
|
||||
import Protolude
|
||||
|
||||
data MetricsState =
|
||||
@@ -34,6 +37,7 @@ data MetricsState =
|
||||
|
||||
init :: Int -> IO MetricsState
|
||||
init configDbPoolSize = do
|
||||
whenM getRTSStatsEnabled $ void $ register PMG.ghcMetrics
|
||||
metricState <- MetricsState <$>
|
||||
register (counter (Info "pgrst_db_pool_timeouts_total" "The total number of pool connection timeouts")) <*>
|
||||
register (gauge (Info "pgrst_db_pool_available" "Available connections in the pool")) <*>
|
||||
|
||||
@@ -84,6 +84,7 @@ def run(
|
||||
configpath=None,
|
||||
stdin=None,
|
||||
env=None,
|
||||
args=None,
|
||||
port=None,
|
||||
admin_port=None,
|
||||
host=None,
|
||||
@@ -122,6 +123,9 @@ def run(
|
||||
command = [POSTGREST_BIN]
|
||||
env["HPCTIXFILE"] = hpctixfile()
|
||||
|
||||
if args:
|
||||
command.extend(args)
|
||||
|
||||
if configpath:
|
||||
command.append(configpath)
|
||||
|
||||
|
||||
@@ -1693,6 +1693,30 @@ def test_admin_metrics(defaultenv):
|
||||
assert "pgrst_db_pool_timeouts_total" in response.text
|
||||
|
||||
|
||||
def test_admin_metrics_include_ghc_runtime_metrics(defaultenv):
|
||||
"Should get GHC runtime metrics from the admin endpoint when RTS stats are enabled"
|
||||
|
||||
with run(env=defaultenv, args=["+RTS", "-T", "-RTS"], port=freeport()) as postgrest:
|
||||
response = postgrest.admin.get("/metrics")
|
||||
assert response.status_code == 200
|
||||
assert "# HELP ghc_gcs_total Total number of GCs" in response.text
|
||||
assert "# TYPE ghc_gcs_total counter" in response.text
|
||||
assert re.search(r"^ghc_gcs_total \d+(?:\.\d+)?$", response.text, re.MULTILINE)
|
||||
assert re.search(
|
||||
r"^ghc_allocated_bytes_total \d+(?:\.\d+)?$", response.text, re.MULTILINE
|
||||
)
|
||||
|
||||
|
||||
def test_admin_metrics_exclude_ghc_runtime_metrics_by_default(defaultenv):
|
||||
"Should not get GHC runtime metrics unless RTS stats are enabled"
|
||||
|
||||
with run(env=defaultenv, port=freeport()) as postgrest:
|
||||
response = postgrest.admin.get("/metrics")
|
||||
assert response.status_code == 200
|
||||
assert "ghc_gcs_total" not in response.text
|
||||
assert "ghc_allocated_bytes_total" not in response.text
|
||||
|
||||
|
||||
def test_schema_cache_startup_load_with_in_db_config(defaultenv, metapostgrest):
|
||||
"verify that the Schema Cache loads correctly at startup, using the in-db `pgrst.db_schemas` config"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user