1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-11-02 06:13:16 +03:00
Files
mariadb-columnstore-engine/cmapi/cmapi_server/controllers/dispatcher.py
Alexander Presnyakov 151903cd18 Tracing fixes:
Don't log trace_params in tracing logger, because it already has all this data
Don't print span attrs, it can contain lots of headers
Save small part of the response into the span, if the response was a JSON string
Added JSON logging of trace details into a separate file (to not spam the main log with machine readable stuff)
Record part of the response into the span
Set duration attribute in server spans
Log 404 errors
Colorize the traces (each span slightly changes the color of the parent span)
Improve trace visualization with duration formatting and notes for request/response pairs
2025-09-10 17:06:12 +00:00

300 lines
9.5 KiB
Python

import json
import logging
import cherrypy
from cmapi_server.controllers.endpoints import (
StatusController, ConfigController, BeginController, CommitController,
RollbackController, StartController, ShutdownController,
ExtentMapController, ClusterController, ApiKeyController,
LoggingConfigController, AppController, NodeProcessController
)
from cmapi_server.controllers.s3dataload import S3DataLoadController
_version = '0.4.0'
dispatcher = cherrypy.dispatch.RoutesDispatcher()
logger = logging.getLogger(__name__)
# /_version/status (GET)
dispatcher.connect(name = 'status',
route = f'/cmapi/{_version}/node/status',
action = 'get_status',
controller = StatusController(),
conditions = {'method': ['GET']})
# /_version/master (GET)
dispatcher.connect(name = 'get_primary',
route = f'/cmapi/{_version}/node/primary',
action = 'get_primary',
controller = StatusController(),
conditions = {'method': ['GET']})
# /_version/new_primary (GET)
dispatcher.connect(name = 'get_new_primary',
route = f'/cmapi/{_version}/node/new_primary',
action = 'get_new_primary',
controller = StatusController(),
conditions = {'method': ['GET']})
# /_version/config/ (GET)
dispatcher.connect(name = 'get_config', # what does this name is used for?
route = f'/cmapi/{_version}/node/config',
action = 'get_config',
controller = ConfigController(),
conditions = {'method': ['GET']})
# /_version/config/ (PUT)
dispatcher.connect(name = 'put_config',
route = f'/cmapi/{_version}/node/config',
action = 'put_config',
controller = ConfigController(),
conditions = {'method': ['PUT']})
# /_version/begin/ (PUT)
dispatcher.connect(name = 'put_begin',
route = f'/cmapi/{_version}/node/begin',
action = 'put_begin',
controller = BeginController(),
conditions = {'method': ['PUT']})
# /_version/rollback/ (PUT)
dispatcher.connect(name = 'put_rollback',
route = f'/cmapi/{_version}/node/rollback',
action = 'put_rollback',
controller = RollbackController(),
conditions = {'method': ['PUT']})
# /_version/commit/ (PUT)
dispatcher.connect(name = 'put_commit',
route = f'/cmapi/{_version}/node/commit',
action = 'put_commit',
controller = CommitController(),
conditions = {'method': ['PUT']})
# /_version/start/ (PUT)
dispatcher.connect(name = 'start',
route = f'/cmapi/{_version}/node/start',
action = 'put_start',
controller = StartController(),
conditions = {'method': ['PUT']})
# /_version/shutdown/ (PUT)
dispatcher.connect(name = 'shutdown',
route = f'/cmapi/{_version}/node/shutdown',
action = 'put_shutdown',
controller = ShutdownController(),
conditions = {'method': ['PUT']})
# /_version/meta/em/ (GET)
dispatcher.connect(name = 'get_em',
route = f'/cmapi/{_version}/node/meta/em',
action = 'get_em',
controller = ExtentMapController(),
conditions = {'method': ['GET']})
# /_version/meta/journal/ (GET)
dispatcher.connect(name = 'get_journal',
route = f'/cmapi/{_version}/node/meta/journal',
action = 'get_journal',
controller = ExtentMapController(),
conditions = {'method': ['GET']})
# /_version/meta/vss/ (GET)
dispatcher.connect(name = 'get_vss',
route = f'/cmapi/{_version}/node/meta/vss',
action = 'get_vss',
controller = ExtentMapController(),
conditions = {'method': ['GET']})
# /_version/meta/vbbm/ (GET)
dispatcher.connect(name = 'get_vbbm',
route = f'/cmapi/{_version}/node/meta/vbbm',
action = 'get_vbbm',
controller = ExtentMapController(),
conditions = {'method': ['GET']})
# /_version/meta/footprint/ (GET)
dispatcher.connect(name = 'get_footprint',
route = f'/cmapi/{_version}/node/meta/footprint',
action = 'get_footprint',
controller = ExtentMapController(),
conditions = {'method': ['GET']})
# /_version/cluster/start/ (PUT)
dispatcher.connect(name = 'cluster_start',
route = f'/cmapi/{_version}/cluster/start',
action = 'put_start',
controller = ClusterController(),
conditions = {'method': ['PUT']})
# /_version/cluster/shutdown/ (PUT)
dispatcher.connect(name = 'cluster_shutdown',
route = f'/cmapi/{_version}/cluster/shutdown',
action = 'put_shutdown',
controller = ClusterController(),
conditions = {'method': ['PUT']})
# /_version/cluster/mode-set/ (PUT)
dispatcher.connect(name = 'cluster_mode_set',
route = f'/cmapi/{_version}/cluster/mode-set',
action = 'put_mode_set',
controller = ClusterController(),
conditions = {'method': ['PUT']})
# /_version/cluster/node/ (POST, PUT)
dispatcher.connect(name = 'cluster_add_node',
route = f'/cmapi/{_version}/cluster/node',
action = 'put_add_node',
controller = ClusterController(),
conditions = {'method': ['POST', 'PUT']})
# /_version/cluster/node/ (DELETE)
dispatcher.connect(name = 'cluster_remove_node',
route = f'/cmapi/{_version}/cluster/node',
action = 'delete_remove_node',
controller = ClusterController(),
conditions = {'method': ['DELETE']})
# /_version/cluster/status/ (GET)
dispatcher.connect(name = 'cluster_status',
route = f'/cmapi/{_version}/cluster/status',
action = 'get_status',
controller = ClusterController(),
conditions = {'method': ['GET']})
# /_version/node/apikey-set/ (PUT)
dispatcher.connect(
name = 'node_set_api_key',
route = f'/cmapi/{_version}/node/apikey-set',
action = 'set_api_key',
controller = ApiKeyController(),
conditions = {'method': ['PUT']}
)
# /_version/cluster/apikey-set/ (PUT)
dispatcher.connect(
name = 'cluster_set_api_key',
route = f'/cmapi/{_version}/cluster/apikey-set',
action = 'set_api_key',
controller = ClusterController(),
conditions = {'method': ['PUT']}
)
# /_version/cluster/node/ (POST, PUT)
dispatcher.connect(name = 'cluster_load_s3data',
route = f'/cmapi/{_version}/cluster/load_s3data',
action = 'load_s3data',
controller = S3DataLoadController(),
conditions = {'method': ['POST', 'PUT']})
# /_version/node/log-config/ (PUT)
dispatcher.connect(
name = 'node_set_log_level',
route = f'/cmapi/{_version}/node/log-level',
action = 'set_log_level',
controller = LoggingConfigController(),
conditions = {'method': ['PUT']}
)
# /_version/cluster/log-config'/ (PUT)
dispatcher.connect(
name = 'cluster_set_log_level',
route = f'/cmapi/{_version}/cluster/log-level',
action = 'set_log_level',
controller = ClusterController(),
conditions = {'method': ['PUT']}
)
# /ready (GET)
dispatcher.connect(
name = 'app_ready',
route = '/cmapi/ready',
action = 'ready',
controller = AppController(),
conditions = {'method': ['GET']}
)
# /_version/node/stop_dmlproc/ (PUT)
dispatcher.connect(
name = 'stop_dmlproc',
route = f'/cmapi/{_version}/node/stop_dmlproc',
action = 'put_stop_dmlproc',
controller = NodeProcessController(),
conditions = {'method': ['PUT']}
)
# /_version/node/is_process_running/ (PUT)
dispatcher.connect(
name = 'is_process_running',
route = f'/cmapi/{_version}/node/is_process_running',
action = 'get_process_running',
controller = NodeProcessController(),
conditions = {'method': ['GET']}
)
def jsonify_error(status, message, traceback, version): \
# pylint: disable=unused-argument
"""JSONify all CherryPy error responses (created by raising the
cherrypy.HTTPError exception)
"""
cherrypy.response.headers['Content-Type'] = 'application/json'
response_body = json.dumps(
{
'error': {
'http_status': status,
'message': message,
}
}
)
cherrypy.response.status = status
return response_body
def jsonify_404(status, message, traceback, version):
# pylint: disable=unused-argument
"""Specialized renderer for 404 Not Found that logs context, then renders JSON.
"""
try:
req = cherrypy.request
method = getattr(req, 'method', '')
path = getattr(req, 'path_info', '') or '/'
remote_ip = getattr(getattr(req, 'remote', None), 'ip', '') or '?'
logger.error("404 Not Found: %s %s from %s", method, path, remote_ip)
except Exception:
pass
return jsonify_error(status, message, traceback, version)