create table @extschema@.long_running_query_rules ( priority int4, application_name_ilike text, usename name, state text, alert_threshold interval not null, active_since timestamptz, active_until timestamptz, created_at timestamptz default now(), comment text ); insert into @extschema@.long_running_query_rules(priority, application_name_ilike, usename, state, alert_threshold) values (0, 'pg\_dump', null, null, interval'6 hours'), -- pg_dump 6 hours (0, 'pg2ch', null, null, interval'3 hours'), -- pg2ch 3 hours (100, null, null, 'idle in transaction', interval'5 minutes'), -- any idle transaction 5 minutes (100, null, null, 'idle in transaction (aborted)', interval'5 minutes'), -- same as above, except one of the statements in the transaction caused an error (1000, null, null, null, interval'1 hour'); -- anything else 1 hour create or replace view @extschema@.long_running_queries ( duration, pid, is_slave, application_name, username, database, backend_type, client_addr, state, wait_event, wait_event_type, query ) as select now() - p.query_start as duration, p.pid, pg_is_in_recovery() as is_slave, p.application_name, p.usename, p.datname as database, p.backend_type, p.client_addr, p.state, p.wait_event, p.wait_event_type, p.query from pg_catalog.pg_stat_activity p, lateral ( select alert_threshold, active_since, active_until from @extschema@.long_running_query_rules l where coalesce(p.application_name ilike l.application_name_ilike, true) and coalesce(p.usename = l.usename, true) and coalesce(p.state = l.state, true) order by priority asc limit 1 ) l where p.state != 'idle' and backend_type = 'client backend' and age(now(), query_start) > l.alert_threshold and coalesce(now() >= l.active_since, true) and coalesce(now() <= l.active_until, true) order by duration desc;