From b9e7f292c38610a23b75b57cf2ba04d1722fa94f Mon Sep 17 00:00:00 2001 From: Maxime Beauchemin Date: Fri, 17 Feb 2017 09:50:39 -0800 Subject: [PATCH] Cleaning up CLI stdout on startup on startup, FAB spits out a bunch of logging messages that aren't useful in most cases. This shuts them down by default. They can be turned back on with `config.SILENCE_FAB = True` Also shushing a flask-cache warning around setting up a null (default) cache --- superset/__init__.py | 9 +++--- .../javascripts/explorev2/stores/fields.jsx | 2 +- superset/cache_util.py | 19 ++++++++----- superset/config.py | 28 ++++++++++++------- superset/utils.py | 7 +++++ superset/viz.py | 25 +++++++++-------- 6 files changed, 56 insertions(+), 34 deletions(-) diff --git a/superset/__init__.py b/superset/__init__.py index 1838c49b232b6..f3d8795c02d45 100644 --- a/superset/__init__.py +++ b/superset/__init__.py @@ -12,7 +12,6 @@ from flask import Flask, redirect from flask_appbuilder import SQLA, AppBuilder, IndexView from flask_appbuilder.baseviews import expose -from flask_cache import Cache from flask_migrate import Migrate from superset.source_registry import SourceRegistry from werkzeug.contrib.fixers import ProxyFix @@ -30,6 +29,9 @@ app.config.from_object(CONFIG_MODULE) conf = app.config +if conf.get('SILENCE_FAB'): + logging.getLogger('flask_appbuilder').setLevel(logging.ERROR) + if not app.debug: # In production mode, add log handler to sys.stderr. app.logger.addHandler(logging.StreamHandler()) @@ -41,9 +43,8 @@ utils.pessimistic_connection_handling(db.engine.pool) -cache = Cache(app, config=app.config.get('CACHE_CONFIG')) -tables_cache = Cache(app, config=app.config.get('TABLE_NAMES_CACHE_CONFIG')) - +cache = utils.setup_cache(app, conf.get('CACHE_CONFIG')) +tables_cache = utils.setup_cache(app, conf.get('TABLE_NAMES_CACHE_CONFIG')) migrate = Migrate(app, db, directory=APP_DIR + "/migrations") diff --git a/superset/assets/javascripts/explorev2/stores/fields.jsx b/superset/assets/javascripts/explorev2/stores/fields.jsx index 9d0e1609ad4bc..34a8590a6acef 100644 --- a/superset/assets/javascripts/explorev2/stores/fields.jsx +++ b/superset/assets/javascripts/explorev2/stores/fields.jsx @@ -65,7 +65,7 @@ export const fields = { multi: true, label: 'Metrics', validators: [v.nonEmpty], - default: field => field.choices && field.choices.length > 0 ? [field.choices[0][0]] : null, + default: field => field.choices && field.choices.length > 0 ? [field.choices[0][0]] : null, mapStateToProps: (state) => ({ choices: (state.datasource) ? state.datasource.metrics_combo : [], }), diff --git a/superset/cache_util.py b/superset/cache_util.py index ef8835c55cce5..7bef8794af563 100644 --- a/superset/cache_util.py +++ b/superset/cache_util.py @@ -15,13 +15,18 @@ def memoized_func(timeout=5 * 60, key=view_cache_key): returns the caching key. """ def wrap(f): - def wrapped_f(cls, *args, **kwargs): - cache_key = key(*args, **kwargs) - o = tables_cache.get(cache_key) - if o is not None: + if tables_cache: + def wrapped_f(cls, *args, **kwargs): + cache_key = key(*args, **kwargs) + o = tables_cache.get(cache_key) + if o is not None: + return o + o = f(cls, *args, **kwargs) + tables_cache.set(cache_key, o, timeout=timeout) return o - o = f(cls, *args, **kwargs) - tables_cache.set(cache_key, o, timeout=timeout) - return o + else: + # noop + def wrapped_f(cls, *args, **kwargs): + return f(cls, *args, **kwargs) return wrapped_f return wrap diff --git a/superset/config.py b/superset/config.py index a3da859abba84..3a602bfeec70e 100644 --- a/superset/config.py +++ b/superset/config.py @@ -267,16 +267,6 @@ class CeleryConfig(object): CONFIG_PATH_ENV_VAR = 'SUPERSET_CONFIG_PATH' -try: - if CONFIG_PATH_ENV_VAR in os.environ: - # Explicitly import config module that is not in pythonpath; useful - # for case where app is being executed via pex. - imp.load_source('superset_config', os.environ[CONFIG_PATH_ENV_VAR]) - - from superset_config import * # noqa - print('Loaded your LOCAL configuration') -except ImportError: - pass # smtp server configuration EMAIL_NOTIFICATIONS = False # all the emails are sent using dryrun @@ -290,3 +280,21 @@ class CeleryConfig(object): if not CACHE_DEFAULT_TIMEOUT: CACHE_DEFAULT_TIMEOUT = CACHE_CONFIG.get('CACHE_DEFAULT_TIMEOUT') + +# Whether to bump the logging level to ERRROR on the flask_appbiulder package +# Set to False if/when debugging FAB related issues like +# permission management +SILENCE_FAB = True + +try: + if CONFIG_PATH_ENV_VAR in os.environ: + # Explicitly import config module that is not in pythonpath; useful + # for case where app is being executed via pex. + imp.load_source('superset_config', os.environ[CONFIG_PATH_ENV_VAR]) + + from superset_config import * # noqa + import superset_config + print('Loaded your LOCAL configuration at [{}]'.format( + superset_config.__file__)) +except ImportError: + pass diff --git a/superset/utils.py b/superset/utils.py index 5dea8a4ef064e..4eea55d8b09dd 100644 --- a/superset/utils.py +++ b/superset/utils.py @@ -30,6 +30,7 @@ FLAMSG_ERR_SEC_ACCESS_DENIED, PERMISSION_PREFIX ) +from flask_cache import Cache from flask_appbuilder._compat import as_unicode from flask_babel import gettext as __ import markdown as md @@ -565,3 +566,9 @@ def wraps(self, *args, **kwargs): def choicify(values): """Takes an iterable and makes an iterable of tuples with it""" return [(v, v) for v in values] + + +def setup_cache(app, cache_config): + """Setup the flask-cache on a flask app""" + if cache_config and cache_config.get('CACHE_TYPE') != 'null': + return Cache(app, config=cache_config) diff --git a/superset/viz.py b/superset/viz.py index 1e46f7c2106d0..bb9391ab5cbf8 100755 --- a/superset/viz.py +++ b/superset/viz.py @@ -231,7 +231,7 @@ def get_payload(self, force=False): cache_key = self.cache_key payload = None force = force if force else self.form_data.get('force') == 'true' - if not force: + if not force and cache: payload = cache.get(cache_key) if payload: @@ -280,17 +280,18 @@ def get_payload(self, force=False): data = self.json_dumps(payload) if PY3: data = bytes(data, 'utf-8') - try: - cache.set( - cache_key, - zlib.compress(data), - timeout=cache_timeout) - except Exception as e: - # cache.set call can fail if the backend is down or if - # the key is too large or whatever other reasons - logging.warning("Could not cache key {}".format(cache_key)) - logging.exception(e) - cache.delete(cache_key) + if cache: + try: + cache.set( + cache_key, + zlib.compress(data), + timeout=cache_timeout) + except Exception as e: + # cache.set call can fail if the backend is down or if + # the key is too large or whatever other reasons + logging.warning("Could not cache key {}".format(cache_key)) + logging.exception(e) + cache.delete(cache_key) payload['is_cached'] = is_cached return payload