From b2a9a711896d0be6db61c90e1bcff012e1da7749 Mon Sep 17 00:00:00 2001 From: Andrey Sumin Date: Sun, 23 Feb 2014 15:04:17 +0400 Subject: [PATCH] HH-41451 syntax highlighting in debug [ipetropolsky] [gkostin] --- debian/install | 2 +- docs/config.md | 1 - frontik/debug/debug-css.xsl | 233 ++++++++++++ frontik/debug/debug-js.xsl | 65 ++++ frontik/{ => debug}/debug.xsl | 433 ++-------------------- frontik/debug/highlight-css.xsl | 14 + frontik/debug/highlight-js.xsl | 17 + frontik/handler_debug.py | 56 ++- frontik/options.py | 1 - frontik/xml_util.py | 17 - frontik_dev.cfg.ex | 1 - tests/projects/frontik.cfg | 3 - tests/projects/frontik_non_debug_mode.cfg | 3 - 13 files changed, 403 insertions(+), 443 deletions(-) create mode 100644 frontik/debug/debug-css.xsl create mode 100644 frontik/debug/debug-js.xsl rename frontik/{ => debug}/debug.xsl (55%) create mode 100644 frontik/debug/highlight-css.xsl create mode 100644 frontik/debug/highlight-js.xsl diff --git a/debian/install b/debian/install index bec2be9ea..50e8c3a61 100644 --- a/debian/install +++ b/debian/install @@ -1,2 +1,2 @@ production/frontik.cfg /etc/frontik -frontik/debug.xsl /usr/lib/frontik/ +frontik/debug/* /usr/lib/frontik/debug/ diff --git a/docs/config.md b/docs/config.md index 46b551251..857900fda 100644 --- a/docs/config.md +++ b/docs/config.md @@ -36,7 +36,6 @@ which run on one Frontik instance. | `debug` | `bool` | `False` | Enable debug mode by default (will show debug output on every error) | | `debug_login` | `str` | `None` | Debug mode login for basic authentication | | `debug_password` | `str` | `None` | Debug mode password for basic authentication | -| `debug_xsl` | `str` | see code | Debug page XSL template | | `suppressed_loggers` | `list` | `[]` | List of logger names to be excluded from debug output | | `syslog` | `bool` | `False` | Enables sending logs to syslog | | `syslog_address` | `str` | `'/dev/log'` | Syslog address | diff --git a/frontik/debug/debug-css.xsl b/frontik/debug/debug-css.xsl new file mode 100644 index 000000000..94883a851 --- /dev/null +++ b/frontik/debug/debug-css.xsl @@ -0,0 +1,233 @@ + + + + + + + + diff --git a/frontik/debug/debug-js.xsl b/frontik/debug/debug-js.xsl new file mode 100644 index 000000000..2430da702 --- /dev/null +++ b/frontik/debug/debug-js.xsl @@ -0,0 +1,65 @@ + + + + + + + + diff --git a/frontik/debug.xsl b/frontik/debug/debug.xsl similarity index 55% rename from frontik/debug.xsl rename to frontik/debug/debug.xsl index d2dce31be..25d264199 100644 --- a/frontik/debug.xsl +++ b/frontik/debug/debug.xsl @@ -1,9 +1,13 @@ - + + + + + + @@ -22,8 +26,10 @@ Status <xsl:value-of select="@code"/> - - + + + + @@ -58,7 +64,9 @@
- + + +
@@ -89,10 +97,6 @@ - - - -
@@ -231,21 +235,7 @@ - -
- - -
- -
-
-
- - +
-                
+                
+                    
+                
             
@@ -265,9 +257,9 @@
+ - @@ -293,18 +285,12 @@ - -
body
-
-            
-        
-
- - +
body
-
- -
+ + + +
@@ -316,11 +302,6 @@ - -
body
-
-
-
body
Empty response @@ -368,6 +349,19 @@
+ + + + + + +
+            
+                
+            
+        
+
+ @@ -442,359 +436,4 @@ - - - - - - - - - - -
- < - - - - - - - - - - =" - - - - - - - " - - - - - > - - </ - - - - > - - - /> - - -
-
- - - - - - - - - -
-
- -
- - - - <!----> - -
diff --git a/frontik/debug/highlight-css.xsl b/frontik/debug/highlight-css.xsl new file mode 100644 index 000000000..d48ef4d90 --- /dev/null +++ b/frontik/debug/highlight-css.xsl @@ -0,0 +1,14 @@ + + + + + + + diff --git a/frontik/debug/highlight-js.xsl b/frontik/debug/highlight-js.xsl new file mode 100644 index 000000000..fa34e4808 --- /dev/null +++ b/frontik/debug/highlight-js.xsl @@ -0,0 +1,17 @@ + + + + + + + + diff --git a/frontik/handler_debug.py b/frontik/handler_debug.py index b5d76b43e..3d19e118b 100644 --- a/frontik/handler_debug.py +++ b/frontik/handler_debug.py @@ -3,6 +3,7 @@ import Cookie import inspect import logging +import os import pprint import time import traceback @@ -18,7 +19,6 @@ import tornado.options import frontik.util -from frontik.util import decode_string_from_charset import frontik.xml_util debug_log = logging.getLogger('frontik.debug') @@ -27,6 +27,7 @@ def response_to_xml(response): time_info = etree.Element('time_info') content_type = response.headers.get('Content-Type', '') + mode = '' if 'charset' in content_type: charset = content_type.partition('=')[-1] @@ -37,16 +38,22 @@ def response_to_xml(response): try: if 'text/html' in content_type: - body = decode_string_from_charset(response.body, try_charsets) + body = frontik.util.decode_string_from_charset(response.body, try_charsets) body = body.replace('\n', '\\n').replace("'", "\\'").replace("<", "<") elif 'json' in content_type: - body = json.dumps(json.loads(response.body), sort_keys=True, indent=4) + mode = 'json' + body = _pretty_print_json(json.loads(response.body)) elif 'protobuf' in content_type: body = response.body.encode('hex') - elif 'text/plain' in content_type: - body = decode_string_from_charset(response.body, try_charsets) + elif response.body is None: + body = '' + elif 'xml' in content_type: + mode = 'xml' + body = _pretty_print_xml(etree.fromstring(response.body)) else: - body = etree.fromstring(response.body) + if 'javascript' in content_type: + mode = 'javascript' + body = frontik.util.decode_string_from_charset(response.body, try_charsets) except Exception: debug_log.exception('Cannot parse response body') body = repr(response.body) @@ -59,7 +66,7 @@ def response_to_xml(response): try: response = E.response( - E.body(body, content_type=content_type), + E.body(body, content_type=content_type, mode=mode), E.code(str(response.code)), E.effective_url(response.effective_url), E.error(str(response.error)), @@ -185,6 +192,14 @@ def _exception_to_xml(exc_info, log=debug_log): return exc_node +def _pretty_print_xml(node): + return etree.tostring(node, pretty_print=True) + + +def _pretty_print_json(node): + return json.dumps(node, sort_keys=True, indent=4) + + class DebugLogBulkHandler(object): FIELDS = ['created', 'filename', 'funcName', 'levelname', 'levelno', 'lineno', 'module', 'msecs', 'name', 'pathname', 'process', 'processName', 'relativeCreated', 'threadName'] @@ -235,15 +250,13 @@ def handle(self, record): entry.append(record._xslt_profile) if getattr(record, "_xml", None) is not None: - xml = etree.Element("xml") - entry.append(xml) - # make deepcopy - # if node was sent to debug, but later was appended in some other place - # etree will move node from this place to new one - xml.append(copy.deepcopy(record._xml)) + entry.append(E.text(_pretty_print_xml(record._xml))) if getattr(record, "_protobuf", None) is not None: - entry.append(E.protobuf(record._protobuf)) + entry.append(E.text(record._protobuf)) + + if getattr(record, "_text", None) is not None: + entry.append(E.text(record._text)) self.log_data.append(entry) if getattr(record, "_stages", None) is not None: @@ -252,6 +265,7 @@ def handle(self, record): class PageHandlerDebug(object): DEBUG_HEADER_NAME = 'X-Hh-Debug' + DEBUG_XSL = os.path.join(os.path.dirname(__file__), 'debug/debug.xsl') class DebugMode(object): def __init__(self, handler): @@ -307,11 +321,16 @@ def get_debug_page(self, status_code, response_headers, original_response=None): if hasattr(self.handler.config, 'debug_labels') and isinstance(self.handler.config.debug_labels, dict): debug_log_data.append(frontik.xml_util.dict_to_xml(self.handler.config.debug_labels, 'labels')) - debug_log_data.append(frontik.app.get_frontik_and_apps_versions()) + debug_log_data.append(E.versions( + _pretty_print_xml(frontik.app.get_frontik_and_apps_versions()) + )) + debug_log_data.append(E.request( _params_to_xml(self.handler.request.uri, self.handler.log), _headers_to_xml(self.handler.request.headers), - _cookies_to_xml(self.handler.request.headers))) + _cookies_to_xml(self.handler.request.headers) + )) + debug_log_data.append(E.response(_headers_to_xml(response_headers))) if getattr(self.handler, "_response_size", None) is not None: @@ -325,9 +344,8 @@ def get_debug_page(self, status_code, response_headers, original_response=None): # return raw xml if this is specified explicitly (noxsl=true) or when in inherited mode if frontik.util.get_cookie_or_url_param_value(self.handler, 'noxsl') is None and not self.debug_mode.inherited: try: - with open(tornado.options.options.debug_xsl) as xsl_file: - tranform = etree.XSLT(etree.XML(xsl_file.read())) - log_document = str(tranform(debug_log_data)) + transform = etree.XSLT(etree.parse(self.DEBUG_XSL)) + log_document = str(transform(debug_log_data)) self.handler.set_header('Content-Type', 'text/html; charset=UTF-8') except Exception: self.handler.log.exception('XSLT debug file error') diff --git a/frontik/options.py b/frontik/options.py index f8efa1fc5..6250bb828 100644 --- a/frontik/options.py +++ b/frontik/options.py @@ -17,7 +17,6 @@ tornado.options.define('debug', False, bool) tornado.options.define('debug_login', None, str) tornado.options.define('debug_password', None, str) -tornado.options.define('debug_xsl', '/usr/lib/frontik/debug.xsl', str) tornado.options.define('timeout_multiplier', 1.0, float) tornado.options.define('long_request_timeout', None, float) diff --git a/frontik/xml_util.py b/frontik/xml_util.py index 0f0f1383a..979fe8c76 100644 --- a/frontik/xml_util.py +++ b/frontik/xml_util.py @@ -16,9 +16,6 @@ class ApplicationXMLGlobals(object): def __init__(self, config): - for schema, path in getattr(config, 'XSL_SCHEMAS', {}).items(): - parser.resolvers.add(PrefixResolver(schema, path)) - self.xml_cache = frontik.file_cache.make_file_cache( 'XML', 'XML_root', getattr(config, 'XML_root', None), @@ -37,20 +34,6 @@ def __init__(self, config): ) -class PrefixResolver(etree.Resolver): - def __init__(self, scheme, path): - self.scheme = scheme - self.path = os.path.abspath(path) - - def resolve(self, system_url, public_id, context): - parsed_url = urlparse.urlsplit(system_url) - if parsed_url.scheme == self.scheme: - path = os.path.abspath(os.path.join(self.path, parsed_url.path)) - if not os.path.commonprefix([self.path, path]).startswith(self.path): - raise etree.XSLTParseError('Open files out of XSL root is not allowed: {0}'.format(path)) - return self.resolve_filename(path, context) - - def xml_from_file(filename, log=log_xml_util): """ filename -> (status, et.Element) diff --git a/frontik_dev.cfg.ex b/frontik_dev.cfg.ex index 4b8d0fad9..dbe7a4d62 100644 --- a/frontik_dev.cfg.ex +++ b/frontik_dev.cfg.ex @@ -20,7 +20,6 @@ urls = [ debug = True debug_login = "hh" debug_password = "12345" -debug_xsl = 'frontik/debug.xsl' # wait this number of seconds (int) in workers before stopping IOLoop in each worker, # should be a little less than supervisor_sigterm_timeout diff --git a/tests/projects/frontik.cfg b/tests/projects/frontik.cfg index 8d85d33ca..edf6aa085 100644 --- a/tests/projects/frontik.cfg +++ b/tests/projects/frontik.cfg @@ -8,9 +8,6 @@ suppressed_loggers = ["tornado.curl_httpclient"] host = "0.0.0.0" - -debug_xsl = "frontik/debug.xsl" - apps = { "test_app": "tests/projects/test_app", } diff --git a/tests/projects/frontik_non_debug_mode.cfg b/tests/projects/frontik_non_debug_mode.cfg index 07e1fbeae..2af623faa 100644 --- a/tests/projects/frontik_non_debug_mode.cfg +++ b/tests/projects/frontik_non_debug_mode.cfg @@ -8,10 +8,7 @@ debug_login = 'user' debug_password = 'god' suppressed_loggers = ['tornado.httpclient.curl'] -debug_xsl = 'frontik/debug.xsl' - apps = { "test_app": "tests/projects/test_app", "broken_app": "tests/projects/broken_app", } -