Skip to content

Instantly share code, notes, and snippets.

@LeMeteore
Forked from apollo13/chromelogger.py
Created December 23, 2016 10:44
Show Gist options
  • Save LeMeteore/5156d2adf8331a944fe37b818f0fe14f to your computer and use it in GitHub Desktop.
Save LeMeteore/5156d2adf8331a944fe37b818f0fe14f to your computer and use it in GitHub Desktop.

Revisions

  1. @apollo13 apollo13 revised this gist Dec 21, 2016. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions chromelogger.py
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,6 @@
    """
    License: MIT - https://opensource.org/licenses/MIT
    ChromeLogger is a protocol which allows sending logging messages to the Browser.
    This module implements simple support for Django. It consists of two components:
  2. @apollo13 apollo13 created this gist Dec 21, 2016.
    99 changes: 99 additions & 0 deletions chromelogger.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,99 @@
    """
    ChromeLogger is a protocol which allows sending logging messages to the Browser.
    This module implements simple support for Django. It consists of two components:
    * `LoggingMiddleware` which is responsible for sending all log messages
    associated with the request to the browser.
    * `ChromeLoggerHandler` a python logging handler which collects all messages.
    Configuration in settings.py is as follows::
    MIDDLEWARE = [
    'chromelogger.LoggingMiddleware',
    ... # other middlewares
    ]
    LOGGING = {
    ...
    'handlers': {
    'browser': {
    'class': 'chromelogger.ChromeLoggerHandler',
    },
    ...
    },
    'loggers': {
    'django': {
    'handlers': ['console', 'browser'],
    'level': 'DEBUG',
    },
    ...
    }
    }
    """
    import json
    import logging
    import threading

    HEADER_DATA = {
    'version': 1,
    'columns': ['log', 'backtrace', 'type'],
    }

    STORAGE = threading.local()


    def map_level(level):
    """Maps a logging level to a string understood by browser devtools."""
    if level >= logging.ERROR:
    return 'error'
    elif level >= logging.WARNING:
    return 'warn'
    elif level >= logging.INFO:
    return 'info'
    return ''


    def encode_data(data):
    """Return a base64 encoded json dump."""
    bytes = json.dumps(data).encode('utf-8').encode('base64').replace('\n', '')
    assert len(bytes) < 250 * 1024
    return bytes


    class ChromeLoggerHandler(logging.Handler):
    def emit(self, record):
    try:
    STORAGE.records.append(record)
    except AttributeError:
    pass


    def LoggingMiddleware(get_respone):
    def middleware(request):
    STORAGE.records = log_records = []

    try:
    response = get_respone(request)

    logging_data = HEADER_DATA.copy()
    rows = [
    [['{}:'.format(record.name), record.getMessage().strip()],
    '{} : {}'.format(record.pathname, record.lineno),
    map_level(record.levelno)]
    for record in log_records
    ]
    rows.insert(0, [
    ['{} request to {}'.format(request.method, request.get_full_path())],
    '', 'group'
    ])
    rows.append([[], '', 'groupEnd'])
    logging_data['rows'] = rows
    response['X-ChromeLogger-Data'] = encode_data(logging_data)
    return response

    finally:
    del STORAGE.records

    return middleware