1 | 'use strict'
|
2 |
|
3 | const cli = require('heroku-cli-util')
|
4 |
|
5 | async function run(context, heroku) {
|
6 | const fetcher = require('../lib/fetcher')(heroku)
|
7 | const psql = require('../lib/psql')
|
8 |
|
9 | const { app, args, flags } = context
|
10 | const { database } = args
|
11 | const { verbose } = flags
|
12 |
|
13 | let db = await fetcher.database(app, database)
|
14 |
|
15 | const num = Math.random()
|
16 | const waitingMarker = `${num}${num}`
|
17 |
|
18 | let waitingQuery = `
|
19 | SELECT '${num}' || '${num}' WHERE EXISTS (
|
20 | SELECT 1 FROM information_schema.columns WHERE table_schema = 'pg_catalog'
|
21 | AND table_name = 'pg_stat_activity'
|
22 | AND column_name = 'waiting'
|
23 | )
|
24 | `
|
25 | let waitingOutput = await psql.exec(db, waitingQuery)
|
26 | let waiting = waitingOutput.includes(waitingMarker)
|
27 | ? 'waiting'
|
28 | : 'wait_event IS NOT NULL AS waiting'
|
29 | let query = `
|
30 | SELECT
|
31 | pid,
|
32 | state,
|
33 | application_name AS source,
|
34 | usename AS username,
|
35 | age(now(),xact_start) AS running_for,
|
36 | xact_start AS transaction_start,
|
37 | ${waiting},
|
38 | query
|
39 | FROM pg_stat_activity
|
40 | WHERE
|
41 | query <> '<insufficient privilege>'
|
42 | ${verbose ? '' : "AND state <> 'idle'"}
|
43 | AND pid <> pg_backend_pid()
|
44 | ORDER BY query_start DESC
|
45 | `
|
46 |
|
47 | const output = await psql.exec(db, query)
|
48 | process.stdout.write(output)
|
49 | }
|
50 |
|
51 | module.exports = {
|
52 | topic: 'pg',
|
53 | command: 'ps',
|
54 | description: 'view active queries with execution time',
|
55 | needsApp: true,
|
56 | needsAuth: true,
|
57 | flags: [{ name: 'verbose', char: 'v' }],
|
58 | args: [{ name: 'database', optional: true }],
|
59 | run: cli.command({ preauth: true }, run)
|
60 | }
|