You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by bo...@apache.org on 2017/03/28 23:42:17 UTC

incubator-airflow git commit: [AIRFLOW-1045] Make log level configurable via airflow.cfg

Repository: incubator-airflow
Updated Branches:
  refs/heads/master fe9ebe3cc -> e739a5f52


[AIRFLOW-1045] Make log level configurable via airflow.cfg

For now, changing log level needs to modify
settings.py directly.
It's inconvenient. This PR makes it configurable
via airflow.cfg.

Closes #2191 from sekikn/loglevel


Project: http://git-wip-us.apache.org/repos/asf/incubator-airflow/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-airflow/commit/e739a5f5
Tree: http://git-wip-us.apache.org/repos/asf/incubator-airflow/tree/e739a5f5
Diff: http://git-wip-us.apache.org/repos/asf/incubator-airflow/diff/e739a5f5

Branch: refs/heads/master
Commit: e739a5f52c215bae9d6588318ee9b2ce1757ed64
Parents: fe9ebe3
Author: Kengo Seki <se...@apache.org>
Authored: Tue Mar 28 16:42:10 2017 -0700
Committer: Bolke de Bruin <bo...@xs4all.nl>
Committed: Tue Mar 28 16:42:10 2017 -0700

----------------------------------------------------------------------
 airflow/config_templates/default_airflow.cfg |  3 ++
 airflow/config_templates/default_test.cfg    |  1 +
 airflow/settings.py                          | 21 ++++++++--
 tests/core.py                                | 50 +++++++++++++++++++++++
 4 files changed, 72 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-airflow/blob/e739a5f5/airflow/config_templates/default_airflow.cfg
----------------------------------------------------------------------
diff --git a/airflow/config_templates/default_airflow.cfg b/airflow/config_templates/default_airflow.cfg
index af240a7..77c65ca 100644
--- a/airflow/config_templates/default_airflow.cfg
+++ b/airflow/config_templates/default_airflow.cfg
@@ -46,6 +46,9 @@ encrypt_s3_logs = False
 # DEPRECATED option for remote log storage, use remote_base_log_folder instead!
 s3_log_folder =
 
+# Logging level
+logging_level = INFO
+
 # The executor class that airflow should use. Choices include
 # SequentialExecutor, LocalExecutor, CeleryExecutor, DaskExecutor
 executor = SequentialExecutor

http://git-wip-us.apache.org/repos/asf/incubator-airflow/blob/e739a5f5/airflow/config_templates/default_test.cfg
----------------------------------------------------------------------
diff --git a/airflow/config_templates/default_test.cfg b/airflow/config_templates/default_test.cfg
index ecf7f4e..2d31141 100644
--- a/airflow/config_templates/default_test.cfg
+++ b/airflow/config_templates/default_test.cfg
@@ -28,6 +28,7 @@ airflow_home = {AIRFLOW_HOME}
 dags_folder = {TEST_DAGS_FOLDER}
 plugins_folder = {TEST_PLUGINS_FOLDER}
 base_log_folder = {AIRFLOW_HOME}/logs
+logging_level = INFO
 executor = SequentialExecutor
 sql_alchemy_conn = sqlite:///{AIRFLOW_HOME}/unittests.db
 load_examples = True

http://git-wip-us.apache.org/repos/asf/incubator-airflow/blob/e739a5f5/airflow/settings.py
----------------------------------------------------------------------
diff --git a/airflow/settings.py b/airflow/settings.py
index 45f7fba..08db96a 100644
--- a/airflow/settings.py
+++ b/airflow/settings.py
@@ -118,9 +118,24 @@ def policy(task_instance):
 
 
 def configure_logging(log_format=LOG_FORMAT):
-    logging.root.handlers = []
-    logging.basicConfig(
-        format=log_format, stream=sys.stdout, level=LOGGING_LEVEL)
+
+    def _configure_logging(logging_level):
+        global LOGGING_LEVEL
+        logging.root.handlers = []
+        logging.basicConfig(
+            format=log_format, stream=sys.stdout, level=logging_level)
+        LOGGING_LEVEL = logging_level
+
+    if "logging_level" in conf.as_dict()["core"]:
+        logging_level = conf.get('core', 'LOGGING_LEVEL').upper()
+    else:
+        logging_level = LOGGING_LEVEL
+    try:
+        _configure_logging(logging_level)
+    except ValueError:
+        logging.warning("Logging level {} is not defined. "
+                        "Use default.".format(logging_level))
+        _configure_logging(logging.INFO)
 
 
 def configure_vars():

http://git-wip-us.apache.org/repos/asf/incubator-airflow/blob/e739a5f5/tests/core.py
----------------------------------------------------------------------
diff --git a/tests/core.py b/tests/core.py
index 18dcb4d..bd52d19 100644
--- a/tests/core.py
+++ b/tests/core.py
@@ -17,6 +17,7 @@ from __future__ import print_function
 import bleach
 import doctest
 import json
+import logging
 import os
 import re
 import unittest
@@ -2342,5 +2343,54 @@ class EmailSmtpTest(unittest.TestCase):
         self.assertFalse(mock_smtp.called)
         self.assertFalse(mock_smtp_ssl.called)
 
+class LogTest(unittest.TestCase):
+    def setUp(self):
+        configuration.load_test_config()
+
+    def _log(self):
+        settings.configure_logging()
+
+        sio = six.StringIO()
+        handler = logging.StreamHandler(sio)
+        logger = logging.getLogger()
+        logger.addHandler(handler)
+
+        logging.debug("debug")
+        logging.info("info")
+        logging.warn("warn")
+
+        sio.flush()
+        return sio.getvalue()
+
+    def test_default_log_level(self):
+        s = self._log()
+        self.assertFalse("debug" in s)
+        self.assertTrue("info" in s)
+        self.assertTrue("warn" in s)
+
+    def test_change_log_level_to_debug(self):
+        configuration.set("core", "LOGGING_LEVEL", "DEBUG")
+        s = self._log()
+        self.assertTrue("debug" in s)
+        self.assertTrue("info" in s)
+        self.assertTrue("warn" in s)
+
+    def test_change_log_level_to_info(self):
+        configuration.set("core", "LOGGING_LEVEL", "INFO")
+        s = self._log()
+        self.assertFalse("debug" in s)
+        self.assertTrue("info" in s)
+        self.assertTrue("warn" in s)
+
+    def test_change_log_level_to_warn(self):
+        configuration.set("core", "LOGGING_LEVEL", "WARNING")
+        s = self._log()
+        self.assertFalse("debug" in s)
+        self.assertFalse("info" in s)
+        self.assertTrue("warn" in s)
+
+    def tearDown(self):
+        configuration.set("core", "LOGGING_LEVEL", "INFO")
+
 if __name__ == '__main__':
     unittest.main()