########
 
 lftools is a collection of scripts written directly in python or externally via
-bash. It supports the following commands.
+bash.
+
+It supports the following commands:
 
 .. toctree::
     :maxdepth: 2
     openstack
     sign
     version
+
+Enable debugging via ``lftools --debug`` preceding any commands or via
+environment variable ``DEBUG=True``, this will print extra information if
+available.
 
 formatter = logging.Formatter('(%(levelname)s) %(name)s: %(message)s')
 console_handler = logging.StreamHandler()
 console_handler.setFormatter(formatter)
-logging.getLogger("").setLevel(logging.NOTSET)
+logging.getLogger("").setLevel(logging.INFO)
 logging.getLogger("").addHandler(console_handler)
 
 
 __author__ = 'Thanh Ha'
 
+import logging
+
 import click
 
 from lftools.cli.config import config_sys
 from lftools.cli.sign import sign
 from lftools.cli.version import version
 
+log = logging.getLogger(__name__)
+
 
 @click.group()
+@click.option('--debug', envvar='DEBUG', is_flag=True, default=False)
 @click.pass_context
 @click.version_option()
-def cli(ctx):
+def cli(ctx, debug):
     """CLI entry point for lftools."""
-    pass
+    if debug:
+        logging.getLogger("").setLevel(logging.DEBUG)
+
+    ctx.obj['DEBUG'] = debug
+    log.debug('DEBUG mode enabled.')
 
 
 cli.add_command(config_sys)
 
--- /dev/null
+---
+features:
+  - |
+    Add a new ``--debug`` flag to enable extra troubleshooting information.
+    This flag can also be set via environment variable ``DEBUG=True``.
 
     os.chdir(str(datafiles))
 
     # Check that license checker passes when file has license.
-    result = cli_runner.invoke(cli.cli, ['license', 'check', 'license.py'])
+    result = cli_runner.invoke(cli.cli, ['license', 'check', 'license.py'], obj={})
     # noqa: B101 .
     assert result.exit_code == 0
 
     # Check that license checker fails when file is missing license.
-    result = cli_runner.invoke(cli.cli, ['license', 'check', 'no_license1.py'])
+    result = cli_runner.invoke(cli.cli, ['license', 'check', 'no_license1.py'], obj={})
     # noqa: B101 .
     assert result.exit_code == 1
 
 
     # Check that check-dir fails due to directory containing files
     # with no license.
-    result = cli_runner.invoke(cli.cli, ['license', 'check-dir', '.'])
+    result = cli_runner.invoke(cli.cli, ['license', 'check-dir', '.'], obj={})
     # noqa: B101 .
     assert result.exit_code == 1
 
     # Check that check-dir passes when directory contains files with licenses
     os.remove('no_license1.py')
     os.remove('no_license2.py')
-    result = cli_runner.invoke(cli.cli, ['license', 'check-dir', '.'])
+    result = cli_runner.invoke(cli.cli, ['license', 'check-dir', '.'], obj={})
     # noqa: B101 .
     assert result.exit_code == 0
 
 def test_version_bump(cli_runner, datafiles):
     """Test version bump command."""
     os.chdir(str(datafiles))
-    cli_runner.invoke(cli.cli, ['version', 'bump', 'TestRelease'])
+    cli_runner.invoke(cli.cli, ['version', 'bump', 'TestRelease'], obj={})
 
     for _file in datafiles.listdir():
         pom = str(_file) + '/pom.xml'
 def test_version_release(cli_runner, datafiles):
     """Test version release command."""
     os.chdir(str(datafiles))
-    cli_runner.invoke(cli.cli, ['version', 'release', 'TestRelease'])
+    cli_runner.invoke(cli.cli, ['version', 'release', 'TestRelease'], obj={})
 
     for _file in datafiles.listdir():
         pom = str(_file) + '/pom.xml'