diff --git a/cms/wsgi.py b/cms/wsgi.py
index b46d824c4677792e9d5fa872b76c3f68381a3069..0a4d276460beb2a35a9b53b6beef8dce1261a090 100644
--- a/cms/wsgi.py
+++ b/cms/wsgi.py
@@ -1,3 +1,17 @@
+"""
+WSGI config for CMS.
+
+This module contains the WSGI application used by Django's development server
+and any production WSGI deployments.
+It exposes a module-level variable named ``application``. Django's
+``runserver`` and ``runfcgi`` commands discover this application via the
+``WSGI_APPLICATION`` setting.
+"""
+from __future__ import absolute_import
+
+from openedx.core.lib.logsettings import log_python_warnings
+log_python_warnings()
+
 # Patch the xml libs before anything else.
 from safe_lxml import defuse_xml_libs
 defuse_xml_libs()
diff --git a/lms/wsgi.py b/lms/wsgi.py
index d71a2c26ebcddb73d126376cfe4fa6ef3f9df473..4d7f6d10e0ae252df26e332447a74f737fe2e033 100644
--- a/lms/wsgi.py
+++ b/lms/wsgi.py
@@ -7,6 +7,10 @@ It exposes a module-level variable named ``application``. Django's
 ``runserver`` and ``runfcgi`` commands discover this application via the
 ``WSGI_APPLICATION`` setting.
 """
+from __future__ import absolute_import
+
+from openedx.core.lib.logsettings import log_python_warnings
+log_python_warnings()
 
 # Patch the xml libs
 from safe_lxml import defuse_xml_libs
diff --git a/lms/wsgi_apache_lms.py b/lms/wsgi_apache_lms.py
index 09c038ada818f2638e0ec35ddb61d85ad6e5dc2a..59f99ada77c439d7b552ad31666be38f92c46a33 100644
--- a/lms/wsgi_apache_lms.py
+++ b/lms/wsgi_apache_lms.py
@@ -4,6 +4,10 @@ Apache WSGI file for LMS
 This module contains the WSGI application used for Apache deployment.
 It exposes a module-level variable named ``application``.
 """
+from __future__ import absolute_import
+
+from openedx.core.lib.logsettings import log_python_warnings
+log_python_warnings()
 
 # Patch the xml libs before anything else.
 from safe_lxml import defuse_xml_libs
diff --git a/manage.py b/manage.py
index fd26eab45d0db28dc6b4c80a84b7bdbed2bfc12c..a3ca481ebdf6b24898469950c396f9d848284947 100755
--- a/manage.py
+++ b/manage.py
@@ -10,15 +10,21 @@ by passing the --settings flag, you can specify what environment specific settin
 
 Any arguments not understood by this manage.py will be passed to django-admin.py
 """
+# pylint: disable=wrong-import-order, wrong-import-position
+from __future__ import absolute_import, print_function
+
+from openedx.core.lib.logsettings import log_python_warnings
+log_python_warnings()
 
 # Patch the xml libs before anything else.
 from safe_lxml import defuse_xml_libs
 defuse_xml_libs()
 
+import importlib
 import os
 import sys
-import importlib
 from argparse import ArgumentParser
+
 import contracts
 
 
@@ -82,8 +88,8 @@ def parse_args():
     edx_args, django_args = parser.parse_known_args()
 
     if edx_args.help:
-        print "edX:"
-        print edx_args.help_string
+        print("edX:")
+        print(edx_args.help_string)
 
     return edx_args, django_args
 
@@ -104,7 +110,7 @@ if __name__ == "__main__":
         contracts.disable_all()
 
     if edx_args.help:
-        print "Django:"
+        print("Django:")
         # This will trigger django-admin.py to print out its help
         django_args.append('--help')
 
diff --git a/openedx/core/lib/logsettings.py b/openedx/core/lib/logsettings.py
index 9e8dcb08ec7c4a8dbbefc823db50bcd2a8f14bf7..a600449e5c5bd864995dd50f78229a562f55872e 100644
--- a/openedx/core/lib/logsettings.py
+++ b/openedx/core/lib/logsettings.py
@@ -1,8 +1,10 @@
 """Get log settings."""
 
+import logging
 import os
 import platform
 import sys
+import warnings
 from logging.handlers import SysLogHandler
 
 LOG_LEVELS = ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']
@@ -161,3 +163,15 @@ def get_logger_config(log_dir,
         })
 
     return logger_config
+
+
+def log_python_warnings():
+    """
+    Stop ignoring DeprecationWarning, ImportWarning, and PendingDeprecationWarning;
+    log all Python warnings to the main log file.
+
+    Not used in test runs, so pytest can collect the warnings triggered for
+    each test case.
+    """
+    warnings.simplefilter('default')
+    logging.captureWarnings(True)