psqlstatsshow
Version:
Web Monitoring PostgreSQL- Tracking execution statistics of all SQL statements executed by a server.
254 lines (218 loc) • 5.42 kB
JavaScript
#!/usr/bin/env node
const path = require('path').posix
const reload = require('reload')
const helpers = require('handlebars-helpers')()
const argv = require('minimist')(process.argv)
const bodyParser = require('body-parser')
const cookieSession = require('cookie-session')
const exphbs = require('express-handlebars')
const express = require('express')
const Database = require('./base/database')
let database
const password = argv.password || ''
const port = argv.port || process.env.PORT || process.env.port || 3000
const isDevMode = argv.dev
const isEnableClose = !(argv['disable-close'] || false)
const checkPassword = (req, res) => {
if (password == '') {
return true
}
const passwordInput = req.session.password
if (passwordInput != password) {
res.redirect('/login')
return false
}
return true
}
const app = express()
const handlebarsContext = {
isDevMode,
isEnableClose,
database: ''
}
const hbs = exphbs.create({
defaultLayout: 'main',
partialsDir: path.join(__dirname, 'views/partials'),
layoutsDir: path.join(__dirname, 'views/layouts'),
helpers: {
...helpers,
console: text => console.log(text)
}
})
app.engine('handlebars', hbs.engine)
app.set('port', port)
app.set('views', path.join(__dirname, 'views'))
app.set('view engine', 'handlebars')
app.set('trust proxy', 1)
app.use(
cookieSession({
name: 'session',
keys: ['PSQL-StatsShow', 'psqlstatsshow']
})
)
if (!isDevMode) {
app.enable('view cache')
}
app.use((req, res, next) => {
// Console.log(`[:]Path: ${req.path}`)
if (
req.path !== '/login' &&
!(req.path.startsWith('/css') || req.path.startsWith('/uikit') || req.path.startsWith('/reload')) &&
!checkPassword(req, res)
) {
console.log('[!] Open page of login')
return false
}
if (!database) {
database = new Database({
database: req.session.database
})
}
handlebarsContext.database = req.session.database
return next()
})
app.use('/uikit', express.static(path.join(path.dirname(require.resolve('uikit')), '..')))
app.use('/css', express.static(path.join(__dirname, 'css')))
app.use(bodyParser.urlencoded({
extended: false
}))
app.get(['/', '/dashboard'], async (req, res) => {
console.log('[!] Dashboard')
const result = [{
title: 'Most Used',
qtTitle: 'Calls',
list: await database.mostUsed()
}, {
title: 'Most Rows',
qtTitle: 'Rows',
list: await database.mostRows()
}, {
title: 'Max Time',
qtTitle: 'Time',
list: await database.maxTime()
}, {
title: 'Min Time',
qtTitle: 'Time',
list: await database.minTime()
}, {
title: 'Mean Time',
qtTitle: 'Time',
list: await database.meanTime()
}, {
title: 'Local Read',
qtTitle: 'Block',
list: await database.maxTime()
}, {
title: 'Local Write',
qtTitle: 'Block',
list: await database.maxTime()
}]
const configFile = await database.get('SHOW config_file;', [])
const blockSize = await database.get('SHOW block_size;', [])
const maxConnections = await database.get('SHOW max_connections;', [])
const timeZone = await database.get('SHOW timezone;', [])
return res.render('dashboard', {
...handlebarsContext,
result: result.map(elemt => {
return {
configFile: configFile[0].config_file,
blockSize: blockSize[0].block_size,
maxConnections: maxConnections[0].max_connections,
timeZone: timeZone[0].TimeZone,
...elemt,
...handlebarsContext
}
}),
path: '/dashboard'
})
})
const search = async (req, res) => {
const {
query
} = req.body
let result
if (query) {
const select = await database.get(query, []).catch(error => {
res.render('alert', {
...handlebarsContext,
path: req.path,
text: error
})
return undefined
})
if (!select) {
return undefined
}
if (select.error) {
return res.render('alert', {
...handlebarsContext,
path: req.path,
text: select.error
})
}
result = {}
result.keys = Object.keys(select[0])
result.data = select.map(elemt => Object.values(elemt))
}
return res.render('search', {
...handlebarsContext,
result,
path: '/dashboard'
})
}
app.post('/search', search)
app.get('/search', search)
app.get('/close', async (req, res) => {
if (!isEnableClose) {
return res.render('alert', {
...handlebarsContext,
path: req.path,
text: 'Disable!'
})
}
console.log('[!] Shutdown Server...')
res.render('alert', {
...handlebarsContext,
path: req.path,
text: 'Shutdown Server...'
})
await new Promise(resolve => setTimeout(
resolve,
(5000) // 5s
))
return process.exit()
})
app.get('/singout', (req, res) => {
console.log('[!] Sing out user')
req.session.password = ''
return res.redirect('/login')
})
app.get('/login', (req, res) => {
console.log('[!] Login user')
return res.render('login', {
...handlebarsContext,
path: req.path
})
})
app.post('/login', async (req, res) => {
req.session.password = req.body.password
if (checkPassword(req, res)) {
req.session.database = req.body.database
database = new Database({
database: req.session.database
})
await database.get('SELECT $1', ['Hello world!']).catch(() => {
req.session.password = ''
req.session.database = ''
return res.redirect('/login')
}).then(() => {
return res.redirect('/dashboard')
})
}
})
app.listen(app.get('port'), () => {
console.log(`[!] Open browser: http://localhost:${app.get('port')} or YOU_IP:${app.get('port')}`)
})
if (isDevMode) {
reload(app)
}