1 | 'use strict'
|
2 |
|
3 | const cli = require('heroku-cli-util')
|
4 | const co = require('co')
|
5 | const capitalize = require('lodash.capitalize')
|
6 | const PGDIAGNOSE_HOST = process.env.PGDIAGNOSE_URL || 'https://pgdiagnose.herokai.com'
|
7 |
|
8 | function * run (context, heroku) {
|
9 | const fetcher = require('../lib/fetcher')(heroku)
|
10 | const host = require('../lib/host')
|
11 | const util = require('../lib/util')
|
12 | const {app, args} = context
|
13 |
|
14 | let generateReport = co.wrap(function * (database) {
|
15 | let db = yield fetcher.addon(app, database)
|
16 | db = yield heroku.get(`/addons/${db.name}`)
|
17 | let config = yield heroku.get(`/apps/${app}/config-vars`)
|
18 | let params = {
|
19 | url: config[util.getUrl(db.config_vars)],
|
20 | plan: db.plan.name.split(':')[1],
|
21 | app: db.app.name,
|
22 | database: util.getUrl(db.config_vars)
|
23 | }
|
24 | if (!util.starterPlan(db)) {
|
25 | params.metrics = yield heroku.get(`/client/v11/databases/${db.id}/metrics`, {host: host(db)})
|
26 | }
|
27 | return yield heroku.post('/reports', {
|
28 | host: PGDIAGNOSE_HOST,
|
29 | body: params
|
30 | })
|
31 | })
|
32 |
|
33 | let displayReport = report => {
|
34 | cli.log(`Report ${report.id} for ${report.app}::${report.database}
|
35 | available for one month after creation on ${report.created_at}
|
36 | `)
|
37 | let display = checks => {
|
38 | checks.forEach((check) => {
|
39 | let color = cli.color[check.status] || ((txt) => txt)
|
40 | cli.log(color(`${check.status.toUpperCase()}: ${check.name}`))
|
41 |
|
42 | if (check.status === 'green') return
|
43 | if (!check.results) return
|
44 |
|
45 | if (Array.isArray(check.results)) {
|
46 | if (!check.results.length) return
|
47 |
|
48 | let keys = Object.keys(check.results[0])
|
49 | cli.table(check.results, {
|
50 | columns: keys.map(key => ({label: capitalize(key), key: key}))
|
51 | })
|
52 | } else {
|
53 | if (!Object.keys(check.results).length) return
|
54 |
|
55 | let key = Object.keys(check.results)[0]
|
56 | cli.log(`${key.split('_').map((s) => capitalize(s)).join(' ')} ${check.results[key]}`)
|
57 | }
|
58 | })
|
59 | }
|
60 | display(report.checks.filter(c => c.status === 'red'))
|
61 | display(report.checks.filter(c => c.status === 'yellow'))
|
62 | display(report.checks.filter(c => c.status === 'green'))
|
63 | display(report.checks.filter(c => !['red', 'yellow', 'green'].find(d => d === c.status)))
|
64 | }
|
65 |
|
66 | let report
|
67 | let id = args['DATABASE|REPORT_ID']
|
68 | if (id && id.match(/^[a-z0-9-]{36}$/)) {
|
69 | report = yield heroku.get(`/reports/${encodeURIComponent(id)}`, {host: PGDIAGNOSE_HOST})
|
70 | } else {
|
71 | report = yield generateReport(id)
|
72 | }
|
73 |
|
74 | displayReport(report)
|
75 | }
|
76 |
|
77 | module.exports = {
|
78 | topic: 'pg',
|
79 | command: 'diagnose',
|
80 | description: 'run or view diagnostics report',
|
81 | help: `
|
82 | defaults to DATABASE_URL database if no DATABASE is specified
|
83 | if REPORT_ID is specified instead, a previous report is displayed
|
84 | `,
|
85 | needsApp: true,
|
86 | needsAuth: true,
|
87 | args: [{name: 'DATABASE|REPORT_ID', optional: true}],
|
88 | run: cli.command({preauth: true}, co.wrap(run))
|
89 | }
|