This is an automated email from the ASF dual-hosted git repository.

maximebeauchemin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
     new fd84fd8  RFC: add logger that logs into browser console (#4702)
fd84fd8 is described below

commit fd84fd89ce12388d4aa4c98bc3d0d1257d355168
Author: Beto Dealmeida <robe...@dealmeida.net>
AuthorDate: Thu Apr 12 21:48:17 2018 -0700

    RFC: add logger that logs into browser console (#4702)
    
    * Option for logging into browser console
    
    * Move import
    
    * Add lint req
    
    * Add docs, use Flask logger
---
 CONTRIBUTING.md        | 13 +++++++++++++
 requirements-dev.txt   |  1 +
 setup.py               |  1 +
 superset/__init__.py   |  4 +++-
 superset/cli.py        | 49 +++++++++++++++++++++++++++++++++++++++++--------
 superset/views/core.py |  6 ++++--
 6 files changed, 63 insertions(+), 11 deletions(-)

diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index a47aefb..10d82d1 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -200,6 +200,19 @@ Check the [OS 
dependencies](https://superset.incubator.apache.org/installation.h
     superset runserver -d
 
 
+### Logging to the browser console
+
+When debugging your application, you can have the server logs sent directly to 
the browser console:
+
+    superset runserver -d --console-log
+
+You can log anything to the browser console, including objects:
+
+    from superset import app
+    app.logger.error('An exception occurred!')
+    app.logger.info(form_data)
+
+
 ## Setting up the node / npm javascript environment
 
 `superset/assets` contains all npm-managed, front end assets.
diff --git a/requirements-dev.txt b/requirements-dev.txt
index 3ca7ffb..7f96163 100644
--- a/requirements-dev.txt
+++ b/requirements-dev.txt
@@ -5,3 +5,4 @@ psycopg2==2.7.4
 redis==2.10.6
 statsd==3.2.2
 tox==2.9.1
+console_log==0.2.10
diff --git a/setup.py b/setup.py
index 43f0c4a..c24d6f2 100644
--- a/setup.py
+++ b/setup.py
@@ -93,6 +93,7 @@ setup(
     ],
     extras_require={
         'cors': ['flask-cors>=2.0.0'],
+        'console_log': ['console_log==0.2.10'],
     },
     author='Maxime Beauchemin',
     author_email='maximebeauche...@gmail.com',
diff --git a/superset/__init__.py b/superset/__init__.py
index 83154ca..929fcfe 100644
--- a/superset/__init__.py
+++ b/superset/__init__.py
@@ -78,7 +78,9 @@ for bp in conf.get('BLUEPRINTS'):
 if conf.get('SILENCE_FAB'):
     logging.getLogger('flask_appbuilder').setLevel(logging.ERROR)
 
-if not app.debug:
+if app.debug:
+    app.logger.setLevel(logging.DEBUG)
+else:
     # In production mode, add log handler to sys.stderr.
     app.logger.addHandler(logging.StreamHandler())
     app.logger.setLevel(logging.INFO)
diff --git a/superset/cli.py b/superset/cli.py
index dc11e2c..a40f062 100755
--- a/superset/cli.py
+++ b/superset/cli.py
@@ -14,6 +14,7 @@ from colorama import Fore, Style
 from flask_migrate import MigrateCommand
 from flask_script import Manager
 from pathlib2 import Path
+import werkzeug.serving
 import yaml
 
 from superset import app, data, db, dict_import_export_util, security_manager, 
utils
@@ -32,10 +33,44 @@ def init():
     security_manager.sync_role_definitions()
 
 
+def debug_run(app, port, use_reloader):
+    return app.run(
+        host='0.0.0.0',
+        port=int(port),
+        threaded=True,
+        debug=True,
+        use_reloader=use_reloader)
+
+
+def console_log_run(app, port, use_reloader):
+    from console_log import ConsoleLog
+    from gevent import pywsgi
+    from geventwebsocket.handler import WebSocketHandler
+
+    app.wsgi_app = ConsoleLog(app.wsgi_app, app.logger)
+
+    def run():
+        server = pywsgi.WSGIServer(
+            ('0.0.0.0', int(port)),
+            app,
+            handler_class=WebSocketHandler)
+        server.serve_forever()
+
+    if use_reloader:
+        from gevent import monkey
+        monkey.patch_all()
+        run = werkzeug.serving.run_with_reloader(run)
+
+    run()
+
+
 @manager.option(
     '-d', '--debug', action='store_true',
     help='Start the web server in debug mode')
 @manager.option(
+    '--console-log', action='store_true',
+    help='Create logger that logs to the browser console (implies -d)')
+@manager.option(
     '-n', '--no-reload', action='store_false', dest='use_reloader',
     default=config.get('FLASK_USE_RELOAD'),
     help="Don't use the reloader in debug mode")
@@ -57,9 +92,9 @@ def init():
     help='Path to a UNIX socket as an alternative to address:port, e.g. '
          '/var/run/superset.sock. '
          'Will override the address and port values. [DEPRECATED]')
-def runserver(debug, use_reloader, address, port, timeout, workers, socket):
+def runserver(debug, console_log, use_reloader, address, port, timeout, 
workers, socket):
     """Starts a Superset web server."""
-    debug = debug or config.get('DEBUG')
+    debug = debug or config.get('DEBUG') or console_log
     if debug:
         print(Fore.BLUE + '-=' * 20)
         print(
@@ -68,12 +103,10 @@ def runserver(debug, use_reloader, address, port, timeout, 
workers, socket):
             Fore.YELLOW + ' mode')
         print(Fore.BLUE + '-=' * 20)
         print(Style.RESET_ALL)
-        app.run(
-            host='0.0.0.0',
-            port=int(port),
-            threaded=True,
-            debug=True,
-            use_reloader=use_reloader)
+        if console_log:
+            console_log_run(app, port, use_reloader)
+        else:
+            debug_run(app, port, use_reloader)
     else:
         logging.info(
             "The Gunicorn 'superset runserver' command is deprecated. Please "
diff --git a/superset/views/core.py b/superset/views/core.py
index 6629dbd..19885dc 100755
--- a/superset/views/core.py
+++ b/superset/views/core.py
@@ -746,8 +746,10 @@ class R(BaseSupersetView):
         obj = models.Url(url=url)
         db.session.add(obj)
         db.session.commit()
-        return('http://{request.headers[Host]}/{directory}?r={obj.id}'.format(
-            request=request, directory=directory, obj=obj))
+        return Response(
+            'http://{request.headers[Host]}/{directory}?r={obj.id}'.format(
+                request=request, directory=directory, obj=obj),
+            mimetype='text/plain')
 
     @expose('/msg/')
     def msg(self):

-- 
To stop receiving notification emails like this one, please contact
maximebeauche...@apache.org.

Reply via email to