For PostgreSQL versions 10 and above, use the built-in pg_monitor role:
-- Create the monitoring userCREATE USER postgres_exporter WITH PASSWORD 'secure_password';-- Grant the monitoring roleGRANT pg_monitor TO postgres_exporter;-- Grant connection permissionGRANT CONNECT ON DATABASE postgres TO postgres_exporter;-- Set search pathALTER USER postgres_exporter SET SEARCH_PATH TO postgres_exporter,pg_catalog;
The pg_monitor role provides read access to all pg_stat_* views and functions needed for monitoring.
Here’s a complete SQL script that safely creates the monitoring user:
-- Create function to safely create user if not existsCREATE OR REPLACE FUNCTION __tmp_create_user() returns void as $$BEGIN IF NOT EXISTS ( SELECT FROM pg_catalog.pg_user WHERE usename = 'postgres_exporter' ) THEN CREATE USER postgres_exporter; END IF;END;$$ language plpgsql;SELECT __tmp_create_user();DROP FUNCTION __tmp_create_user();ALTER USER postgres_exporter WITH PASSWORD 'password';ALTER USER postgres_exporter SET SEARCH_PATH TO postgres_exporter,pg_catalog;-- If deploying as non-superuser (e.g., AWS RDS), uncomment and replace <MASTER_USER>-- GRANT postgres_exporter TO <MASTER_USER>;GRANT CONNECT ON DATABASE postgres TO postgres_exporter;GRANT pg_monitor TO postgres_exporter;
For older PostgreSQL versions without the pg_monitor role, you must create wrapper functions and views:
CREATE SCHEMA IF NOT EXISTS postgres_exporter;GRANT USAGE ON SCHEMA postgres_exporter TO postgres_exporter;-- Wrapper function for pg_stat_activityCREATE OR REPLACE FUNCTION get_pg_stat_activity() RETURNS SETOF pg_stat_activity AS$$ SELECT * FROM pg_catalog.pg_stat_activity; $$LANGUAGE sqlVOLATILESECURITY DEFINER;CREATE OR REPLACE VIEW postgres_exporter.pg_stat_activity AS SELECT * from get_pg_stat_activity();GRANT SELECT ON postgres_exporter.pg_stat_activity TO postgres_exporter;-- Wrapper function for pg_stat_replicationCREATE OR REPLACE FUNCTION get_pg_stat_replication() RETURNS SETOF pg_stat_replication AS$$ SELECT * FROM pg_catalog.pg_stat_replication; $$LANGUAGE sqlVOLATILESECURITY DEFINER;CREATE OR REPLACE VIEW postgres_exporter.pg_stat_replication AS SELECT * FROM get_pg_stat_replication();GRANT SELECT ON postgres_exporter.pg_stat_replication TO postgres_exporter;-- Wrapper for pg_stat_statements (if extension is installed)CREATE EXTENSION IF NOT EXISTS pg_stat_statements;CREATE OR REPLACE FUNCTION get_pg_stat_statements() RETURNS SETOF pg_stat_statements AS$$ SELECT * FROM public.pg_stat_statements; $$LANGUAGE sqlVOLATILESECURITY DEFINER;CREATE OR REPLACE VIEW postgres_exporter.pg_stat_statements AS SELECT * FROM get_pg_stat_statements();GRANT SELECT ON postgres_exporter.pg_stat_statements TO postgres_exporter;
Always use SSL when connecting over untrusted networks:
# Require SSLDATA_SOURCE_URI="postgres.example.com:5432/postgres?sslmode=require"# Verify CA certificateDATA_SOURCE_URI="postgres.example.com:5432/postgres?sslmode=verify-ca&sslrootcert=/path/to/ca.crt"# Full verification (hostname and CA)DATA_SOURCE_URI="postgres.example.com:5432/postgres?sslmode=verify-full&sslrootcert=/path/to/ca.crt"
-- Grant monitoring role to RDS master user firstGRANT postgres_exporter TO your_rds_master_user;-- Then grant pg_monitorGRANT pg_monitor TO postgres_exporter;