2016-04-16 11:51:44 -05:00
|
|
|
##########################################################################
|
|
|
|
#
|
|
|
|
# pgAdmin 4 - PostgreSQL Tools
|
|
|
|
#
|
2019-01-02 04:24:12 -06:00
|
|
|
# Copyright (C) 2013 - 2019, The pgAdmin Development Team
|
2016-04-16 11:51:44 -05:00
|
|
|
# This software is released under the PostgreSQL Licence
|
|
|
|
#
|
|
|
|
##########################################################################
|
|
|
|
|
|
|
|
"""A blueprint module implementing the dashboard frame."""
|
2016-05-05 10:42:16 -05:00
|
|
|
from functools import wraps
|
2016-06-03 03:16:11 -05:00
|
|
|
from flask import render_template, url_for, Response, g
|
2018-04-04 04:47:01 -05:00
|
|
|
from flask_babelex import gettext
|
2016-07-22 10:25:23 -05:00
|
|
|
from flask_security import login_required
|
2016-04-16 11:51:44 -05:00
|
|
|
from pgadmin.utils import PgAdminModule
|
2016-12-09 05:59:13 -06:00
|
|
|
from pgadmin.utils.ajax import make_response as ajax_response,\
|
|
|
|
internal_server_error
|
2016-04-16 11:51:44 -05:00
|
|
|
from pgadmin.utils.ajax import precondition_required
|
|
|
|
from pgadmin.utils.driver import get_driver
|
|
|
|
from pgadmin.utils.menu import Panel
|
2016-05-05 10:42:16 -05:00
|
|
|
from pgadmin.utils.preferences import Preferences
|
|
|
|
|
2016-06-21 08:12:14 -05:00
|
|
|
from config import PG_DEFAULT_DRIVER
|
|
|
|
|
2017-10-10 03:50:47 -05:00
|
|
|
MODULE_NAME = 'dashboard'
|
|
|
|
|
2016-04-16 11:51:44 -05:00
|
|
|
|
|
|
|
class DashboardModule(PgAdminModule):
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
super(DashboardModule, self).__init__(*args, **kwargs)
|
|
|
|
|
|
|
|
def get_own_menuitems(self):
|
|
|
|
return {}
|
|
|
|
|
|
|
|
def get_own_javascripts(self):
|
|
|
|
return [{
|
|
|
|
'name': 'pgadmin.dashboard',
|
|
|
|
'path': url_for('dashboard.index') + 'dashboard',
|
|
|
|
'when': None
|
|
|
|
}]
|
|
|
|
|
2016-05-05 10:42:16 -05:00
|
|
|
def get_own_stylesheets(self):
|
|
|
|
"""
|
|
|
|
Returns:
|
|
|
|
list: the stylesheets used by this module.
|
|
|
|
"""
|
2018-09-04 05:24:51 -05:00
|
|
|
stylesheets = []
|
2016-05-05 10:42:16 -05:00
|
|
|
return stylesheets
|
|
|
|
|
2016-04-16 11:51:44 -05:00
|
|
|
def get_panels(self):
|
|
|
|
return [
|
|
|
|
Panel(
|
|
|
|
name='dashboard',
|
|
|
|
priority=1,
|
|
|
|
title=gettext('Dashboard'),
|
Improvement in the look and feel of the whole application
Changed the SCSS/CSS for the below third party libraries to adopt the
new look 'n' feel:
- wcDocker
- Alertify dialogs, and notifications
- AciTree
- Bootstrap Navbar
- Bootstrap Tabs
- Bootstrap Drop-Down menu
- Backgrid
- Select2
Adopated the new the look 'n' feel for the dialogs, wizard, properties,
tab panels, tabs, fieldset, subnode control, spinner control, HTML
table, and other form controls.
- Font is changed to Roboto
- Using SCSS variables to define the look 'n' feel
- Designer background images for the Login, and Forget password pages in
'web' mode
- Improved the look 'n' feel for the key selection in the preferences
dialog
- Table classes consistency changes across the application
- File Open and Save dialog list view changes
Author(s): Aditya Toshniwal & Khushboo Vashi
2018-12-21 05:44:55 -06:00
|
|
|
icon='',
|
2016-05-05 10:42:16 -05:00
|
|
|
content='',
|
2017-06-30 04:11:34 -05:00
|
|
|
isCloseable=True,
|
|
|
|
isPrivate=False,
|
|
|
|
limit=1,
|
|
|
|
isIframe=False,
|
2018-02-09 06:57:37 -06:00
|
|
|
canHide=True
|
|
|
|
).__dict__
|
2016-04-16 11:51:44 -05:00
|
|
|
]
|
|
|
|
|
2016-05-05 10:42:16 -05:00
|
|
|
def register_preferences(self):
|
|
|
|
"""
|
|
|
|
register_preferences
|
|
|
|
Register preferences for this module.
|
|
|
|
"""
|
|
|
|
# Register options for the PG and PPAS help paths
|
2018-02-09 06:57:37 -06:00
|
|
|
self.dashboard_preference = Preferences(
|
|
|
|
'dashboards', gettext('Dashboards')
|
|
|
|
)
|
2016-05-05 10:42:16 -05:00
|
|
|
|
|
|
|
self.session_stats_refresh = self.dashboard_preference.register(
|
|
|
|
'dashboards', 'session_stats_refresh',
|
|
|
|
gettext("Session statistics refresh rate"), 'integer',
|
|
|
|
1, min_val=1, max_val=999999,
|
|
|
|
category_label=gettext('Graphs'),
|
|
|
|
help_str=gettext('The number of seconds between graph samples.')
|
|
|
|
)
|
|
|
|
|
2018-09-05 11:25:11 -05:00
|
|
|
self.tps_stats_refresh = self.dashboard_preference.register(
|
2016-05-05 10:42:16 -05:00
|
|
|
'dashboards', 'tps_stats_refresh',
|
|
|
|
gettext("Transaction throughput refresh rate"), 'integer',
|
|
|
|
1, min_val=1, max_val=999999,
|
|
|
|
category_label=gettext('Graphs'),
|
|
|
|
help_str=gettext('The number of seconds between graph samples.')
|
|
|
|
)
|
|
|
|
|
2018-09-05 11:25:11 -05:00
|
|
|
self.ti_stats_refresh = self.dashboard_preference.register(
|
2016-05-05 10:42:16 -05:00
|
|
|
'dashboards', 'ti_stats_refresh',
|
|
|
|
gettext("Tuples in refresh rate"), 'integer',
|
|
|
|
1, min_val=1, max_val=999999,
|
|
|
|
category_label=gettext('Graphs'),
|
|
|
|
help_str=gettext('The number of seconds between graph samples.')
|
|
|
|
)
|
|
|
|
|
2018-09-05 11:25:11 -05:00
|
|
|
self.to_stats_refresh = self.dashboard_preference.register(
|
2016-05-05 10:42:16 -05:00
|
|
|
'dashboards', 'to_stats_refresh',
|
|
|
|
gettext("Tuples out refresh rate"), 'integer',
|
|
|
|
1, min_val=1, max_val=999999,
|
|
|
|
category_label=gettext('Graphs'),
|
|
|
|
help_str=gettext('The number of seconds between graph samples.')
|
|
|
|
)
|
|
|
|
|
2018-09-05 11:25:11 -05:00
|
|
|
self.bio_stats_refresh = self.dashboard_preference.register(
|
2016-05-05 10:42:16 -05:00
|
|
|
'dashboards', 'bio_stats_refresh',
|
|
|
|
gettext("Block I/O statistics refresh rate"), 'integer',
|
|
|
|
1, min_val=1, max_val=999999,
|
|
|
|
category_label=gettext('Graphs'),
|
|
|
|
help_str=gettext('The number of seconds between graph samples.')
|
|
|
|
)
|
|
|
|
|
2018-02-26 03:20:04 -06:00
|
|
|
self.display_graphs = self.dashboard_preference.register(
|
|
|
|
'display', 'show_graphs',
|
|
|
|
gettext("Show graphs?"), 'boolean', True,
|
|
|
|
category_label=gettext('Display'),
|
|
|
|
help_str=gettext('If set to True, graphs '
|
|
|
|
'will be displayed on dashboards.')
|
|
|
|
)
|
|
|
|
|
|
|
|
self.display_server_activity = self.dashboard_preference.register(
|
|
|
|
'display', 'show_activity',
|
|
|
|
gettext("Show activity?"), 'boolean', True,
|
|
|
|
category_label=gettext('Display'),
|
|
|
|
help_str=gettext('If set to True, activity tables '
|
|
|
|
'will be displayed on dashboards.')
|
|
|
|
)
|
|
|
|
|
2018-09-05 11:25:11 -05:00
|
|
|
self.graph_data_points = self.dashboard_preference.register(
|
|
|
|
'display', 'graph_data_points',
|
|
|
|
gettext("Show graph data points?"), 'boolean', False,
|
|
|
|
category_label=gettext('Display'),
|
|
|
|
help_str=gettext('If set to True, data points will be '
|
|
|
|
'visible on graph lines.')
|
|
|
|
)
|
|
|
|
|
|
|
|
self.graph_mouse_track = self.dashboard_preference.register(
|
|
|
|
'display', 'graph_mouse_track',
|
|
|
|
gettext("Show mouse hover tooltip?"), 'boolean', True,
|
|
|
|
category_label=gettext('Display'),
|
|
|
|
help_str=gettext('If set to True, tooltip will appear on mouse '
|
|
|
|
'hover on the graph lines giving the data point '
|
|
|
|
'details')
|
|
|
|
)
|
|
|
|
|
2017-07-18 09:13:16 -05:00
|
|
|
def get_exposed_url_endpoints(self):
|
|
|
|
"""
|
|
|
|
Returns:
|
|
|
|
list: a list of url endpoints exposed to the client.
|
|
|
|
"""
|
|
|
|
return [
|
|
|
|
'dashboard.index', 'dashboard.get_by_sever_id',
|
|
|
|
'dashboard.get_by_database_id',
|
|
|
|
'dashboard.session_stats',
|
|
|
|
'dashboard.get_session_stats_by_sever_id',
|
|
|
|
'dashboard.get_session_stats_by_database_id',
|
|
|
|
'dashboard.tps_stats',
|
|
|
|
'dashboard.tps_stats_by_server_id',
|
|
|
|
'dashboard.tps_stats_by_database_id',
|
|
|
|
'dashboard.ti_stats',
|
|
|
|
'dashboard.ti_stats_by_server_id',
|
|
|
|
'dashboard.ti_stats_by_database_id',
|
|
|
|
'dashboard.to_stats',
|
|
|
|
'dashboard.to_stats_by_server_id',
|
|
|
|
'dashboard.to_stats_by_database_id',
|
|
|
|
'dashboard.bio_stats',
|
|
|
|
'dashboard.bio_stats_by_server_id',
|
|
|
|
'dashboard.bio_stats_by_database_id',
|
|
|
|
'dashboard.activity',
|
|
|
|
'dashboard.get_activity_by_server_id',
|
|
|
|
'dashboard.get_activity_by_database_id',
|
|
|
|
'dashboard.locks',
|
|
|
|
'dashboard.get_locks_by_server_id',
|
|
|
|
'dashboard.get_locks_by_database_id',
|
|
|
|
'dashboard.prepared',
|
|
|
|
'dashboard.get_prepared_by_server_id',
|
|
|
|
'dashboard.get_prepared_by_database_id',
|
|
|
|
'dashboard.config',
|
|
|
|
'dashboard.get_config_by_server_id',
|
|
|
|
]
|
2016-04-16 11:51:44 -05:00
|
|
|
|
2018-02-09 06:57:37 -06:00
|
|
|
|
2016-04-16 11:51:44 -05:00
|
|
|
blueprint = DashboardModule(MODULE_NAME, __name__)
|
|
|
|
|
|
|
|
|
|
|
|
def check_precondition(f):
|
|
|
|
"""
|
|
|
|
This function will behave as a decorator which will check
|
|
|
|
database connection before running view, it also adds
|
|
|
|
manager, conn & template_path properties to self
|
|
|
|
"""
|
|
|
|
|
|
|
|
@wraps(f)
|
2016-05-05 10:42:16 -05:00
|
|
|
def wrap(*args, **kwargs):
|
2016-04-16 11:51:44 -05:00
|
|
|
# Here args[0] will hold self & kwargs will hold gid,sid,did
|
2016-05-05 10:42:16 -05:00
|
|
|
|
2016-06-03 03:16:11 -05:00
|
|
|
g.manager = get_driver(
|
2016-05-05 10:42:16 -05:00
|
|
|
PG_DEFAULT_DRIVER).connection_manager(
|
2016-04-16 11:51:44 -05:00
|
|
|
kwargs['sid']
|
|
|
|
)
|
2017-04-24 07:55:29 -05:00
|
|
|
|
2018-02-09 06:57:37 -06:00
|
|
|
stats_type = ('activity', 'prepared', 'locks', 'config')
|
|
|
|
|
2017-04-24 07:55:29 -05:00
|
|
|
# Below check handle the case where existing server is deleted
|
|
|
|
# by user and python server will raise exception if this check
|
|
|
|
# is not introduce.
|
|
|
|
if g.manager is None:
|
2018-02-09 06:57:37 -06:00
|
|
|
if f.__name__ in stats_type:
|
2017-04-24 07:55:29 -05:00
|
|
|
return precondition_required(
|
|
|
|
gettext("Please connect to the selected server"
|
|
|
|
" to view the table.")
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
return precondition_required(
|
|
|
|
gettext("Please connect to the selected server"
|
|
|
|
" to view the graph.")
|
|
|
|
)
|
|
|
|
|
2016-06-03 03:16:11 -05:00
|
|
|
g.conn = g.manager.connection()
|
2016-05-05 10:42:16 -05:00
|
|
|
|
2016-04-16 11:51:44 -05:00
|
|
|
# If DB not connected then return error to browser
|
2016-06-03 03:16:11 -05:00
|
|
|
if not g.conn.connected():
|
2018-02-09 06:57:37 -06:00
|
|
|
if f.__name__ in stats_type:
|
2016-12-09 05:59:13 -06:00
|
|
|
return precondition_required(
|
|
|
|
gettext("Please connect to the selected server"
|
|
|
|
" to view the table.")
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
return precondition_required(
|
|
|
|
gettext("Please connect to the selected server"
|
|
|
|
" to view the graph.")
|
|
|
|
)
|
|
|
|
|
|
|
|
if 'did' in kwargs:
|
|
|
|
db_conn = g.manager.connection(did=kwargs['did'])
|
|
|
|
# If the selected DB not connected then return error to browser
|
|
|
|
if not db_conn.connected():
|
2018-02-09 06:57:37 -06:00
|
|
|
if f.__name__ in stats_type:
|
2016-12-09 05:59:13 -06:00
|
|
|
return precondition_required(
|
|
|
|
gettext("Please connect to the selected database"
|
|
|
|
" to view the table.")
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
return precondition_required(
|
|
|
|
gettext("Please connect to the selected database to"
|
|
|
|
" view the graph.")
|
|
|
|
)
|
2016-04-16 11:51:44 -05:00
|
|
|
|
2016-05-05 10:42:16 -05:00
|
|
|
# Set template path for sql scripts
|
2016-06-03 03:16:11 -05:00
|
|
|
g.server_type = g.manager.server_type
|
|
|
|
g.version = g.manager.version
|
2016-10-14 19:18:17 -05:00
|
|
|
|
2017-08-25 07:23:03 -05:00
|
|
|
# Include server_type in template_path when server_type is gpdb
|
|
|
|
g.template_path = 'dashboard/sql/' + (
|
|
|
|
'#{0}#{1}#'.format(g.server_type, g.version)
|
2018-02-09 06:57:37 -06:00
|
|
|
if g.server_type == 'gpdb' else '#{0}#'.format(g.version)
|
2017-08-25 07:23:03 -05:00
|
|
|
)
|
2016-05-05 10:42:16 -05:00
|
|
|
|
|
|
|
return f(*args, **kwargs)
|
2016-04-16 11:51:44 -05:00
|
|
|
|
|
|
|
return wrap
|
|
|
|
|
|
|
|
|
|
|
|
@blueprint.route("/dashboard.js")
|
|
|
|
@login_required
|
|
|
|
def script():
|
|
|
|
"""render the required javascript"""
|
2018-02-09 06:57:37 -06:00
|
|
|
return Response(
|
|
|
|
response=render_template(
|
|
|
|
"dashboard/js/dashboard.js",
|
|
|
|
_=gettext
|
|
|
|
),
|
|
|
|
status=200,
|
|
|
|
mimetype="application/javascript"
|
|
|
|
)
|
2016-04-16 11:51:44 -05:00
|
|
|
|
|
|
|
|
2017-07-18 09:13:16 -05:00
|
|
|
@blueprint.route('/', endpoint='index')
|
|
|
|
@blueprint.route('/<int:sid>', endpoint='get_by_sever_id')
|
|
|
|
@blueprint.route('/<int:sid>/<int:did>', endpoint='get_by_database_id')
|
2016-04-16 11:51:44 -05:00
|
|
|
@login_required
|
|
|
|
def index(sid=None, did=None):
|
2016-05-05 10:42:16 -05:00
|
|
|
"""
|
|
|
|
Renders the welcome, server or database dashboard
|
|
|
|
Args:
|
|
|
|
sid: Server ID
|
|
|
|
did: Database ID
|
|
|
|
|
|
|
|
Returns: Welcome/Server/database dashboard
|
|
|
|
|
|
|
|
"""
|
|
|
|
rates = {}
|
2018-02-26 03:20:04 -06:00
|
|
|
settings = {}
|
2016-05-05 10:42:16 -05:00
|
|
|
|
2016-10-14 19:18:17 -05:00
|
|
|
# Get the server version
|
|
|
|
if sid is not None:
|
|
|
|
g.manager = get_driver(
|
|
|
|
PG_DEFAULT_DRIVER).connection_manager(sid)
|
|
|
|
g.conn = g.manager.connection()
|
|
|
|
|
|
|
|
g.version = g.manager.version
|
|
|
|
|
|
|
|
if not g.conn.connected():
|
|
|
|
g.version = 0
|
|
|
|
|
2016-04-16 11:51:44 -05:00
|
|
|
# Show the appropriate dashboard based on the identifiers passed to us
|
|
|
|
if sid is None and did is None:
|
|
|
|
return render_template('/dashboard/welcome_dashboard.html')
|
|
|
|
if did is None:
|
2018-02-09 06:57:37 -06:00
|
|
|
return render_template(
|
|
|
|
'/dashboard/server_dashboard.html',
|
|
|
|
sid=sid,
|
|
|
|
rates=rates,
|
2018-07-24 10:31:44 -05:00
|
|
|
version=g.version
|
2018-02-09 06:57:37 -06:00
|
|
|
)
|
2016-04-16 11:51:44 -05:00
|
|
|
else:
|
2018-02-09 06:57:37 -06:00
|
|
|
return render_template(
|
|
|
|
'/dashboard/database_dashboard.html',
|
|
|
|
sid=sid,
|
|
|
|
did=did,
|
|
|
|
rates=rates,
|
2018-07-24 10:31:44 -05:00
|
|
|
version=g.version
|
2018-02-09 06:57:37 -06:00
|
|
|
)
|
2016-05-05 10:42:16 -05:00
|
|
|
|
|
|
|
|
|
|
|
def get_data(sid, did, template):
|
|
|
|
"""
|
|
|
|
Generic function to get server stats based on an SQL template
|
|
|
|
Args:
|
|
|
|
sid: The server ID
|
|
|
|
did: The database ID
|
|
|
|
template: The SQL template name
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
|
|
"""
|
|
|
|
# Allow no server ID to be specified (so we can generate a route in JS)
|
|
|
|
# but throw an error if it's actually called.
|
|
|
|
if not sid:
|
|
|
|
return internal_server_error(errormsg='Server ID not specified.')
|
|
|
|
|
|
|
|
sql = render_template(
|
2016-06-03 03:16:11 -05:00
|
|
|
"/".join([g.template_path, template]), did=did
|
2016-05-05 10:42:16 -05:00
|
|
|
)
|
2016-06-03 03:16:11 -05:00
|
|
|
status, res = g.conn.execute_dict(sql)
|
2016-05-05 10:42:16 -05:00
|
|
|
|
|
|
|
if not status:
|
|
|
|
return internal_server_error(errormsg=res)
|
|
|
|
|
|
|
|
return ajax_response(
|
|
|
|
response=res['rows'],
|
|
|
|
status=200
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2017-07-18 09:13:16 -05:00
|
|
|
@blueprint.route('/session_stats/', endpoint='session_stats')
|
|
|
|
@blueprint.route(
|
2018-02-09 06:57:37 -06:00
|
|
|
'/session_stats/<int:sid>', endpoint='get_session_stats_by_sever_id'
|
|
|
|
)
|
2017-07-18 09:13:16 -05:00
|
|
|
@blueprint.route(
|
|
|
|
'/session_stats/<int:sid>/<int:did>',
|
|
|
|
endpoint='get_session_stats_by_database_id'
|
|
|
|
)
|
2016-05-05 10:42:16 -05:00
|
|
|
@login_required
|
|
|
|
@check_precondition
|
|
|
|
def session_stats(sid=None, did=None):
|
|
|
|
"""
|
|
|
|
This function returns server session statistics
|
|
|
|
:param sid: server id
|
|
|
|
:return:
|
|
|
|
"""
|
|
|
|
return get_data(sid, did, 'session_stats.sql')
|
|
|
|
|
|
|
|
|
2017-07-18 09:13:16 -05:00
|
|
|
@blueprint.route('/tps_stats/', endpoint='tps_stats')
|
|
|
|
@blueprint.route('/tps_stats/<int:sid>', endpoint='tps_stats_by_server_id')
|
|
|
|
@blueprint.route(
|
|
|
|
'/tps_stats/<int:sid>/<int:did>', endpoint='tps_stats_by_database_id'
|
|
|
|
)
|
2016-05-05 10:42:16 -05:00
|
|
|
@login_required
|
|
|
|
@check_precondition
|
|
|
|
def tps_stats(sid=None, did=None):
|
|
|
|
"""
|
|
|
|
This function returns server TPS throughput
|
|
|
|
:param sid: server id
|
|
|
|
:return:
|
|
|
|
"""
|
|
|
|
return get_data(sid, did, 'tps_stats.sql')
|
|
|
|
|
|
|
|
|
2017-07-18 09:13:16 -05:00
|
|
|
@blueprint.route('/ti_stats/', endpoint='ti_stats')
|
|
|
|
@blueprint.route('/ti_stats/<int:sid>', endpoint='ti_stats_by_server_id')
|
|
|
|
@blueprint.route(
|
2018-02-09 06:57:37 -06:00
|
|
|
'/ti_stats/<int:sid>/<int:did>', endpoint='ti_stats_by_database_id'
|
|
|
|
)
|
2016-05-05 10:42:16 -05:00
|
|
|
@login_required
|
|
|
|
@check_precondition
|
|
|
|
def ti_stats(sid=None, did=None):
|
|
|
|
"""
|
|
|
|
This function returns server tuple input statistics
|
|
|
|
:param sid: server id
|
|
|
|
:return:
|
|
|
|
"""
|
|
|
|
return get_data(sid, did, 'ti_stats.sql')
|
|
|
|
|
|
|
|
|
2017-07-18 09:13:16 -05:00
|
|
|
@blueprint.route('/to_stats/', endpoint='to_stats')
|
|
|
|
@blueprint.route('/to_stats/<int:sid>', endpoint='to_stats_by_server_id')
|
|
|
|
@blueprint.route(
|
2018-02-09 06:57:37 -06:00
|
|
|
'/to_stats/<int:sid>/<int:did>', endpoint='to_stats_by_database_id'
|
|
|
|
)
|
2016-05-05 10:42:16 -05:00
|
|
|
@login_required
|
|
|
|
@check_precondition
|
|
|
|
def to_stats(sid=None, did=None):
|
|
|
|
"""
|
|
|
|
This function returns server tuple output statistics
|
|
|
|
:param sid: server id
|
|
|
|
:return:
|
|
|
|
"""
|
|
|
|
return get_data(sid, did, 'to_stats.sql')
|
|
|
|
|
|
|
|
|
2017-07-18 09:13:16 -05:00
|
|
|
@blueprint.route('/bio_stats/', endpoint='bio_stats')
|
|
|
|
@blueprint.route('/bio_stats/<int:sid>', endpoint='bio_stats_by_server_id')
|
|
|
|
@blueprint.route(
|
2018-02-09 06:57:37 -06:00
|
|
|
'/bio_stats/<int:sid>/<int:did>', endpoint='bio_stats_by_database_id'
|
|
|
|
)
|
2016-05-05 10:42:16 -05:00
|
|
|
@login_required
|
|
|
|
@check_precondition
|
|
|
|
def bio_stats(sid=None, did=None):
|
|
|
|
"""
|
|
|
|
This function returns server block IO statistics
|
|
|
|
:param sid: server id
|
|
|
|
:return:
|
|
|
|
"""
|
|
|
|
return get_data(sid, did, 'bio_stats.sql')
|
|
|
|
|
|
|
|
|
2017-07-18 09:13:16 -05:00
|
|
|
@blueprint.route('/activity/', endpoint='activity')
|
|
|
|
@blueprint.route('/activity/<int:sid>', endpoint='get_activity_by_server_id')
|
|
|
|
@blueprint.route(
|
2018-02-09 06:57:37 -06:00
|
|
|
'/activity/<int:sid>/<int:did>', endpoint='get_activity_by_database_id'
|
|
|
|
)
|
2016-05-05 10:42:16 -05:00
|
|
|
@login_required
|
|
|
|
@check_precondition
|
|
|
|
def activity(sid=None, did=None):
|
|
|
|
"""
|
|
|
|
This function returns server activity information
|
|
|
|
:param sid: server id
|
|
|
|
:return:
|
|
|
|
"""
|
|
|
|
return get_data(sid, did, 'activity.sql')
|
|
|
|
|
|
|
|
|
2017-07-18 09:13:16 -05:00
|
|
|
@blueprint.route('/locks/', endpoint='locks')
|
|
|
|
@blueprint.route('/locks/<int:sid>', endpoint='get_locks_by_server_id')
|
|
|
|
@blueprint.route(
|
2018-02-09 06:57:37 -06:00
|
|
|
'/locks/<int:sid>/<int:did>', endpoint='get_locks_by_database_id'
|
|
|
|
)
|
2016-05-05 10:42:16 -05:00
|
|
|
@login_required
|
|
|
|
@check_precondition
|
|
|
|
def locks(sid=None, did=None):
|
|
|
|
"""
|
|
|
|
This function returns server lock information
|
|
|
|
:param sid: server id
|
|
|
|
:return:
|
|
|
|
"""
|
|
|
|
return get_data(sid, did, 'locks.sql')
|
|
|
|
|
|
|
|
|
2017-07-18 09:13:16 -05:00
|
|
|
@blueprint.route('/prepared/', endpoint='prepared')
|
|
|
|
@blueprint.route('/prepared/<int:sid>', endpoint='get_prepared_by_server_id')
|
|
|
|
@blueprint.route(
|
2018-02-09 06:57:37 -06:00
|
|
|
'/prepared/<int:sid>/<int:did>', endpoint='get_prepared_by_database_id'
|
|
|
|
)
|
2016-05-05 10:42:16 -05:00
|
|
|
@login_required
|
|
|
|
@check_precondition
|
|
|
|
def prepared(sid=None, did=None):
|
|
|
|
"""
|
|
|
|
This function returns prepared XACT information
|
|
|
|
:param sid: server id
|
|
|
|
:return:
|
|
|
|
"""
|
|
|
|
return get_data(sid, did, 'prepared.sql')
|
|
|
|
|
|
|
|
|
2017-07-18 09:13:16 -05:00
|
|
|
@blueprint.route('/config/', endpoint='config')
|
|
|
|
@blueprint.route('/config/<int:sid>', endpoint='get_config_by_server_id')
|
2016-05-05 10:42:16 -05:00
|
|
|
@login_required
|
|
|
|
@check_precondition
|
|
|
|
def config(sid=None):
|
|
|
|
"""
|
|
|
|
This function returns server config information
|
|
|
|
:param sid: server id
|
|
|
|
:return:
|
|
|
|
"""
|
|
|
|
return get_data(sid, None, 'config.sql')
|
2017-07-24 06:13:24 -05:00
|
|
|
|
|
|
|
|
|
|
|
@blueprint.route(
|
|
|
|
'/cancel_query/<int:sid>/<int:pid>', methods=['DELETE']
|
|
|
|
)
|
|
|
|
@blueprint.route(
|
|
|
|
'/cancel_query/<int:sid>/<int:did>/<int:pid>', methods=['DELETE']
|
|
|
|
)
|
|
|
|
@login_required
|
|
|
|
@check_precondition
|
|
|
|
def cancel_query(sid=None, did=None, pid=None):
|
|
|
|
"""
|
|
|
|
This function cancel the specific session
|
|
|
|
:param sid: server id
|
|
|
|
:param did: database id
|
|
|
|
:param pid: session/process id
|
|
|
|
:return: Response
|
|
|
|
"""
|
|
|
|
sql = "SELECT pg_cancel_backend({0});".format(pid)
|
|
|
|
status, res = g.conn.execute_scalar(sql)
|
|
|
|
if not status:
|
|
|
|
return internal_server_error(errormsg=res)
|
|
|
|
|
|
|
|
return ajax_response(
|
|
|
|
response=gettext("Success") if res else gettext("Failed"),
|
|
|
|
status=200
|
|
|
|
)
|
2017-09-29 09:40:31 -05:00
|
|
|
|
2018-02-09 06:57:37 -06:00
|
|
|
|
2017-09-29 09:40:31 -05:00
|
|
|
@blueprint.route(
|
|
|
|
'/terminate_session/<int:sid>/<int:pid>', methods=['DELETE']
|
|
|
|
)
|
|
|
|
@blueprint.route(
|
|
|
|
'/terminate_session/<int:sid>/<int:did>/<int:pid>', methods=['DELETE']
|
|
|
|
)
|
|
|
|
@login_required
|
|
|
|
@check_precondition
|
|
|
|
def terminate_session(sid=None, did=None, pid=None):
|
|
|
|
"""
|
|
|
|
This function terminate the specific session
|
|
|
|
:param sid: server id
|
|
|
|
:param did: database id
|
|
|
|
:param pid: session/process id
|
|
|
|
:return: Response
|
|
|
|
"""
|
|
|
|
sql = "SELECT pg_terminate_backend({0});".format(pid)
|
|
|
|
status, res = g.conn.execute_scalar(sql)
|
|
|
|
if not status:
|
|
|
|
return internal_server_error(errormsg=res)
|
|
|
|
|
|
|
|
return ajax_response(
|
|
|
|
response=gettext("Success") if res else gettext("Failed"),
|
|
|
|
status=200
|
|
|
|
)
|