Repository: sscpac/statick (language: python)

Issue:
Turn off output by default
Currently Statick prints out a lot of information to the terminal. In order to make Statick more Unix-y we should turn off all output by default. The current output should be enabled with a `--verbose` flag (or similar). That would make it easier to run while piping the Statick output to separate applications.


Discussion / hints:

Fix patch:
diff --git a/README.md b/README.md
index 2c26dc92..6ee577ba 100644
--- a/README.md
+++ b/README.md
@@ -85,7 +85,12 @@ apt install clang-tidy
 statick <path of package> --output-directory <output path>
 ```
 
-This will run the default level and print the results to the console.
+This will run the default _level_ and print the results to the console.
+
+To see more detailed output use the `--log` argument.
+Valid levels are: `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`.
+Specifying the log level is case-insensitive (both upper-case and lower-case are allowed).
+See the [logging][logging] module documentation for more details.
 
 ## Concepts
 
@@ -150,22 +155,22 @@ Statick has _levels_ of configuration to support testing each _package_ in the d
 _Levels_ are defined in the `config.yaml` file.
 Some projects only care about static analysis at a minimal level and do not care about linting for style at all.
 Other projects want all the bells and whistles that static analysis and linting have to offer.
-That's okay with Statick -- just make a level to match your project needs.
+That's okay with Statick -- just make a _level_ to match your project needs.
 
 Each _level_ specifies which plugins to run, and which flags to use for each plugin.
-If your project only has Python files then your level only needs to run the Python _discovery_ plugin.
-If you only want to run _tool_ plugins for _pylint_ and _pyflakes_, a level is how you configure Statick to look for
+If your project only has Python files then your _level_ only needs to run the Python _discovery_ plugin.
+If you only want to run _tool_ plugins for _pylint_ and _pyflakes_, a _level_ is how you configure Statick to look for
 issues using only those tools.
 If you are not using Jenkins then you can specify that you only want the _reporting_ plugin to run that prints issues
 to a console.
 
-Each _level_ can be stand-alone or it can _inherit_ from a separate level.
+Each _level_ can be stand-alone or it can _inherit_ from a separate _level_.
 This allows users to gradually build up _levels_ to apply to various packages.
-All _packages_ can start by being required to pass a _threshold_ level.
-An _objective_ level can build on the _threshold_ level with more tools or more strict flags for each tool.
+All _packages_ can start by being required to pass a _threshold_ _level_.
+An _objective_ _level_ can build on the _threshold_ _level_ with more tools or more strict flags for each tool.
 A gradual transition of packages from _threshold_ to _objective_ can be undertaken.
-Flags from the inherited level can be overridden by listing the same tool under the level's `tools` key with a new set
-of flags.
+Flags from the inherited _level_ can be overridden by listing the same tool under the _level's_ `tools` key with a new
+set of flags.
 
 In the following `config.yaml` example the `objective` _level_ inherits from and modifies the `threshold` _level_.
 The `pylint` flags from `threshold` are completely modified by the `objective` _level_, and the `clang-tidy` _tool_ is
@@ -235,7 +240,7 @@ packages:
   my_really_good_package: ultimate
 ```
 
-The `default` key lists the _level_ to run if no specific level listed for a package.
+The `default` key lists the _level_ to run if no specific _level_ listed for a package.
 
 The `packages` key lists _packages_ and override levels to run for those packages.
 
@@ -659,6 +664,7 @@ His commits were scrubbed from git history upon the initial public release.
 [docformatter]: https://github.com/myint/docformatter
 [flawfinder]: https://dwheeler.com/flawfinder/
 [lizard]: https://github.com/terryyin/lizard
+[logging]: https://docs.python.org/3/howto/logging.html
 [make]: https://gcc.gnu.org/onlinedocs/libstdc++/index.html
 [mypy]: https://github.com/python/mypy
 [perlcritic]: http://perlcritic.com/
diff --git a/examples/navigation/navigation_config/plugins/my_custom_tool_plugin.py b/examples/navigation/navigation_config/plugins/my_custom_tool_plugin.py
index df16ba48..3a8c4de5 100644
--- a/examples/navigation/navigation_config/plugins/my_custom_tool_plugin.py
+++ b/examples/navigation/navigation_config/plugins/my_custom_tool_plugin.py
@@ -1,5 +1,6 @@
 """Run grep."""
 
+import logging
 import re
 import shlex
 import subprocess
@@ -32,15 +33,14 @@ def scan(self, package, level):
             output = subprocess.check_output(subproc_args,
                                              stderr=subprocess.STDOUT)
         except subprocess.CalledProcessError as ex:
-            print("Problem {}".format(ex.returncode))
-            print("{}".format(ex.output))
+            logging.warning("Problem %d", ex.returncode)
+            logging.warning("%s exception: %s", self.get_name(), ex.output)
             return None
 
-        if self.plugin_context.args.show_tool_output:
-            print("{}".format(output))
+        logging.debug("%s", output)
 
-        with open(self.get_name() + ".log", "w") as fname:
-            fname.write(output)
+        with open(self.get_name() + ".log", "w") as fid:
+            fid.write(output)
 
         issues = self.parse_output(output)
         return issues
diff --git a/statick b/statick
index f3d3590b..d4a0f0bb 100755
--- a/statick
+++ b/statick
@@ -1,8 +1,6 @@
 #!/usr/bin/env python3
 """Executable script for running statick against a single package."""
 
-from __future__ import print_function
-
 import argparse
 import sys
 
@@ -15,9 +13,7 @@ def run(statick: Statick, parsed_args: argparse.Namespace) -> bool:
     path = parsed_args.path
     issues, success = statick.run(path, parsed_args)
     if issues is None:
-        print(
-            "Something went wrong, no information about issues. Statick exiting with errors."
-        )
+        statick.print_no_issues()
         return False
     for tool in issues:
         if issues[tool]:
@@ -33,6 +29,7 @@ def main() -> None:
     statick = Statick(args.get_user_paths())
     statick.gather_args(args.parser)
     parsed_args = args.get_args()
+    statick.set_logging_level(parsed_args)
     statick.get_config(parsed_args)
     statick.get_exceptions(parsed_args)
 
@@ -42,10 +39,10 @@ def main() -> None:
         success = run(statick, parsed_args)
 
     if parsed_args.check and not success:
-        print("Statick exiting with errors.")
+        statick.print_exit_status(False)
         sys.exit(1)
     else:
-        print("Statick exiting with success.")
+        statick.print_exit_status(True)
         sys.exit(0)
 
 
diff --git a/statick_tool/args.py b/statick_tool/args.py
index cf2ca8da..a6c52dca 100644
--- a/statick_tool/args.py
+++ b/statick_tool/args.py
@@ -3,6 +3,7 @@
 Enable usage of user-paths argument before parsing other arguments.
 """
 import argparse
+import logging
 import os
 from typing import Any, List, Optional
 
@@ -37,7 +38,7 @@ def get_user_paths(self, args: Any = None) -> List[str]:
                 if os.path.exists(path) and os.path.isdir(path):
                     user_paths.append(path)
                 else:
-                    print("Could not find user path {}!".format(path))
+                    logging.error("Could not find user path %s!", path)
         return user_paths
 
     def get_args(self, args: Optional[List[str]] = None) -> argparse.Namespace:
diff --git a/statick_tool/discovery_plugin.py b/statick_tool/discovery_plugin.py
index 0e3e0d52..b4bb8742 100644
--- a/statick_tool/discovery_plugin.py
+++ b/statick_tool/discovery_plugin.py
@@ -1,4 +1,5 @@
 """Discovery plugin."""
+import logging
 import os
 import subprocess
 import sys
@@ -42,12 +43,12 @@ def find_files(self, package: Package) -> None:
             return
 
         for root, _, files in os.walk(package.path):
-            for f in files:
-                full_path = os.path.join(root, f)
+            for fname in files:
+                full_path = os.path.join(root, fname)
                 abs_path = os.path.abspath(full_path)
                 file_output = self.get_file_cmd_output(full_path)
                 file_dict = {
-                    "name": f.lower(),
+                    "name": fname.lower(),
                     "path": abs_path,
                     "file_cmd_out": file_output,
                 }
@@ -78,8 +79,10 @@ def get_file_cmd_output(self, full_path: str) -> str:
             )  # type: str
             return output.lower()
         except subprocess.CalledProcessError as ex:
-            print("Failed to run 'file' command. Returncode = {}".format(ex.returncode))
-            print("Exception output: {}".format(ex.output))
+            logging.warning(
+                "Failed to run 'file' command. Returncode = %d", ex.returncode
+            )
+            logging.warning("Exception output: %s", ex.output)
             return ""
 
     def set_plugin_context(self, plugin_context: Union[None, PluginContext]) -> None:
diff --git a/statick_tool/exceptions.py b/statick_tool/exceptions.py
index 405b3bb5..a63bd378 100644
--- a/statick_tool/exceptions.py
+++ b/statick_tool/exceptions.py
@@ -11,6 +11,7 @@
 generates the issues.
 """
 import fnmatch
+import logging
 import os
 import re
 from typing import Any, Dict, List, Match, Optional, Pattern
@@ -154,8 +155,8 @@ def filter_regex_exceptions(
             try:
                 compiled_re = re.compile(exception_re)  # type: Pattern[str]
             except re.error:
-                print(
-                    "Invalid regular expression in exception: {}".format(exception_re)
+                logging.warning(
+                    "Invalid regular expression in exception: %s", exception_re
                 )
                 continue
             for tool, tool_issues in list(issues.items()):
@@ -225,7 +226,8 @@ def print_exception_warning(cls, tool: str) -> None:
 
         Warning will only be printed once per tool.
         """
-        print(
-            "[WARNING] File exceptions not available for {} tool "
-            "plugin due to lack of absolute paths for issues.".format(tool)
+        logging.warning(
+            "[WARNING] File exceptions not available for %s tool "
+            "plugin due to lack of absolute paths for issues.",
+            tool,
         )
diff --git a/statick_tool/plugins/discovery/c_discovery_plugin.py b/statick_tool/plugins/discovery/c_discovery_plugin.py
index 54d92543..067c4ef3 100644
--- a/statick_tool/plugins/discovery/c_discovery_plugin.py
+++ b/statick_tool/plugins/discovery/c_discovery_plugin.py
@@ -1,4 +1,5 @@
 """Discover C files to analyze."""
+import logging
 from collections import OrderedDict
 from typing import List, Optional
 
@@ -35,15 +36,13 @@ def scan(
 
         c_files = list(OrderedDict.fromkeys(c_files))
 
-        print("  {} C/C++ files found.".format(len(c_files)))
+        logging.info("  %d C/C++ files found.", len(c_files))
         if exceptions:
             original_file_count = len(c_files)
             c_files = exceptions.filter_file_exceptions_early(package, c_files)
             if original_file_count > len(c_files):
-                print(
-                    "  After filtering, {} C/C++ files will be scanned.".format(
-                        len(c_files)
-                    )
+                logging.info(
+                    "  After filtering, %d C/C++ files will be scanned.", len(c_files)
                 )
 
         package["c_src"] = c_files
diff --git a/statick_tool/plugins/discovery/catkin_discovery_plugin.py b/statick_tool/plugins/discovery/catkin_discovery_plugin.py
index 38c90ccc..d38a4fbf 100644
--- a/statick_tool/plugins/discovery/catkin_discovery_plugin.py
+++ b/statick_tool/plugins/discovery/catkin_discovery_plugin.py
@@ -1,4 +1,5 @@
 """Discovery plugin to find catkin packages."""
+import logging
 import os
 from typing import Optional
 
@@ -27,8 +28,8 @@ def scan(
         package_file = os.path.join(package.path, "package.xml")
 
         if os.path.isfile(cmake_file) and os.path.isfile(package_file):
-            print("  Package is catkin.")
+            logging.info("  Package is catkin.")
             package["catkin"] = True
         else:
-            print("  Package is not catkin.")
+            logging.info("  Package is not catkin.")
             package["catkin"] = False
diff --git a/statick_tool/plugins/discovery/cmake_discovery_plugin.py b/statick_tool/plugins/discovery/cmake_discovery_plugin.py
index ea258001..e2a32c67 100644
--- a/statick_tool/plugins/discovery/cmake_discovery_plugin.py
+++ b/statick_tool/plugins/discovery/cmake_discovery_plugin.py
@@ -1,5 +1,6 @@
 """Discovery plugin to find CMake-based projects."""
 import argparse
+import logging
 import os
 import re
 import shutil
@@ -43,11 +44,11 @@ def scan(
         package["headers"] = []
 
         if not os.path.isfile(cmake_file):
-            print("  Package is not cmake.")
+            logging.info("  Package is not cmake.")
             package["cmake"] = False
             return
 
-        print("  Found cmake package {}".format(cmake_file))
+        logging.info("  Found cmake package %s", cmake_file)
 
         cmake_template = self.plugin_context.resources.get_file("CMakeLists.txt.in")
         shutil.copyfile(cmake_template, "CMakeLists.txt")  # type: ignore
@@ -101,25 +102,25 @@ def scan(
             output = subprocess.check_output(
                 subproc_args, stderr=subprocess.STDOUT, universal_newlines=True
             )  # type: str
-            if self.plugin_context.args.show_tool_output:
-                print("{}".format(output))
         except subprocess.CalledProcessError as ex:
             output = ex.output
-            print("Problem running CMake! Returncode = {}".format(str(ex.returncode)))
-            print("From {}, running {}".format(os.getcwd(), subproc_args))
-            print("{}".format(ex.output))
+            logging.warning("Problem running CMake! Returncode = %d", ex.returncode)
+            logging.warning("From %s, running %s", os.getcwd(), subproc_args)
+            logging.warning("CMake output: %s", ex.output)
 
         except OSError:
-            print("Couldn't find cmake executable!")
+            logging.warning("Couldn't find cmake executable!")
             return
 
+        logging.debug("%s", output)
+
         if self.plugin_context and self.plugin_context.args.output_directory:
-            with open("cmake.log", "w") as fname:
-                fname.write(output)
+            with open("cmake.log", "w") as fid:
+                fid.write(output)
 
         self.process_output(output, package)
 
-        print("  {} make targets found.".format(len(package["make_targets"])))
+        logging.info("  %d make targets found.", len(package["make_targets"]))
 
     @classmethod
     def process_output(  # pylint: disable=too-many-locals
@@ -177,7 +178,7 @@ def process_output(  # pylint: disable=too-many-locals
                 roslint = os.path.normpath(match_lint.group(1))
                 cpplint = os.path.join(roslint, "cpplint")
                 if os.path.isfile(cpplint):
-                    print("  cpplint script from roslint found at {}".format(cpplint))
+                    logging.info("  cpplint script from roslint found at %s", cpplint)
                     package["cpplint"] = cpplint
                 else:
                     package["cpplint"] = "cpplint"
diff --git a/statick_tool/plugins/discovery/java_discovery_plugin.py b/statick_tool/plugins/discovery/java_discovery_plugin.py
index 46e8cfa6..6611b351 100644
--- a/statick_tool/plugins/discovery/java_discovery_plugin.py
+++ b/statick_tool/plugins/discovery/java_discovery_plugin.py
@@ -1,4 +1,5 @@
 """Discover Java files to analyze."""
+import logging
 from collections import OrderedDict
 from typing import List, Optional
 
@@ -32,30 +33,28 @@ def scan(
         java_src_files = list(OrderedDict.fromkeys(java_src_files))
         java_class_files = list(OrderedDict.fromkeys(java_class_files))
 
-        print("  {} java source files found.".format(len(java_src_files)))
+        logging.info("  %d java source files found.", len(java_src_files))
         if exceptions:
             original_src_file_count = len(java_src_files)
             java_src_files = exceptions.filter_file_exceptions_early(
                 package, java_src_files
             )
             if original_src_file_count > len(java_src_files):
-                print(
-                    "  After filtering, {} java source files will be scanned.".format(
-                        len(java_src_files)
-                    )
+                logging.info(
+                    "  After filtering, %d java source files will be scanned.",
+                    len(java_src_files),
                 )
 
-        print("  {} java class files found.".format(len(java_class_files)))
+        logging.info("  %d java class files found.", len(java_class_files))
         if exceptions:
             original_class_file_count = len(java_class_files)
             java_class_files = exceptions.filter_file_exceptions_early(
                 package, java_class_files
             )
             if original_class_file_count > len(java_class_files):
-                print(
-                    "  After filtering, {} java class files will be scanned.".format(
-                        len(java_class_files)
-                    )
+                logging.info(
+                    "  After filtering, %d java class files will be scanned.",
+                    len(java_class_files),
                 )
 
         package["java_src"] = java_src_files
diff --git a/statick_tool/plugins/discovery/maven_discovery_plugin.py b/statick_tool/plugins/discovery/maven_discovery_plugin.py
index cd4d476f..af72b549 100644
--- a/statick_tool/plugins/discovery/maven_discovery_plugin.py
+++ b/statick_tool/plugins/discovery/maven_discovery_plugin.py
@@ -1,5 +1,6 @@
 """Discover Maven POM files to analyze."""
 import fnmatch
+import logging
 import os
 from collections import OrderedDict
 from typing import List, Optional
@@ -44,8 +45,8 @@ def scan(
         top_poms = list(OrderedDict.fromkeys(top_poms))
         all_poms = list(OrderedDict.fromkeys(all_poms))
 
-        print("  {} Maven POM files found.".format(len(all_poms)))
-        print("  {} top-level Maven POM files found.".format(len(top_poms)))
+        logging.info("  %d Maven POM files found.", len(all_poms))
+        logging.info("  %d top-level Maven POM files found.", len(top_poms))
 
         package["all_poms"] = all_poms
         package["top_poms"] = top_poms
diff --git a/statick_tool/plugins/discovery/perl_discovery_plugin.py b/statick_tool/plugins/discovery/perl_discovery_plugin.py
index 3802013a..0ced1509 100644
--- a/statick_tool/plugins/discovery/perl_discovery_plugin.py
+++ b/statick_tool/plugins/discovery/perl_discovery_plugin.py
@@ -1,4 +1,5 @@
 """Discover Perl files to analyze."""
+import logging
 from collections import OrderedDict
 from typing import List, Optional
 
@@ -31,15 +32,13 @@ def scan(
 
         perl_files = list(OrderedDict.fromkeys(perl_files))
 
-        print("  {} Perl files found.".format(len(perl_files)))
+        logging.info("  %d Perl files found.", len(perl_files))
         if exceptions:
             original_file_count = len(perl_files)
             perl_files = exceptions.filter_file_exceptions_early(package, perl_files)
             if original_file_count > len(perl_files):
-                print(
-                    "  After filtering, {} perl files will be scanned.".format(
-                        len(perl_files)
-                    )
+                logging.info(
+                    "  After filtering, %d perl files will be scanned.", len(perl_files)
                 )
 
         package["perl_src"] = perl_files
diff --git a/statick_tool/plugins/discovery/python_discovery_plugin.py b/statick_tool/plugins/discovery/python_discovery_plugin.py
index 585794fb..b595d3cc 100644
--- a/statick_tool/plugins/discovery/python_discovery_plugin.py
+++ b/statick_tool/plugins/discovery/python_discovery_plugin.py
@@ -1,4 +1,5 @@
 """Discover python files to analyze."""
+import logging
 from collections import OrderedDict
 from typing import List, Optional
 
@@ -32,17 +33,16 @@ def scan(
 
         python_files = list(OrderedDict.fromkeys(python_files))
 
-        print("  {} python files found.".format(len(python_files)))
+        logging.info("  %d python files found.", len(python_files))
         if exceptions:
             original_file_count = len(python_files)
             python_files = exceptions.filter_file_exceptions_early(
                 package, python_files
             )
             if original_file_count > len(python_files):
-                print(
-                    "  After filtering, {} python files will be scanned.".format(
-                        len(python_files)
-                    )
+                logging.info(
+                    "  After filtering, %d python files will be scanned.",
+                    len(python_files),
                 )
 
         package["python_src"] = python_files
diff --git a/statick_tool/plugins/discovery/ros_discovery_plugin.py b/statick_tool/plugins/discovery/ros_discovery_plugin.py
index 9e32ba14..caf93f0b 100644
--- a/statick_tool/plugins/discovery/ros_discovery_plugin.py
+++ b/statick_tool/plugins/discovery/ros_discovery_plugin.py
@@ -1,4 +1,5 @@
 """Discovery plugin to find ROS packages."""
+import logging
 import os
 from functools import reduce
 from typing import Any, Dict, Optional, Union
@@ -48,7 +49,7 @@ def scan(
             and os.path.isfile(package_file)
             and ros_version is not None
         ):
-            print("  Package is ROS{}.".format(ros_version))
+            logging.info("  Package is ROS%s.", ros_version)
             package["ros"] = True
             if ros_version == "1":
                 package["catkin"] = True
@@ -71,10 +72,10 @@ def scan(
                 ) as exc:
                     # No valid XML found, so we are not going to find the build type.
                     package["ros"] = False
-                    print("  Invalid XML in {}: {}".format(package_file, exc))
+                    logging.warning("  Invalid XML in %s: %s", package_file, exc)
                     return
                 if self.deep_get(output, "package.export.build_type") == "ament_python":
-                    print("  Package is ROS{}.".format(ros_version))
+                    logging.info("  Package is ROS%s.", ros_version)
                     package["ros"] = True
         else:
             package["ros"] = False
diff --git a/statick_tool/plugins/discovery/shell_discovery_plugin.py b/statick_tool/plugins/discovery/shell_discovery_plugin.py
index 3b3644dc..c66ec939 100644
--- a/statick_tool/plugins/discovery/shell_discovery_plugin.py
+++ b/statick_tool/plugins/discovery/shell_discovery_plugin.py
@@ -1,4 +1,5 @@
 """Discover shell files to analyze."""
+import logging
 from collections import OrderedDict
 from typing import List, Optional
 
@@ -33,15 +34,14 @@ def scan(
 
         shell_files = list(OrderedDict.fromkeys(shell_files))
 
-        print("  {} shell files found.".format(len(shell_files)))
+        logging.info("  %d shell files found.", len(shell_files))
         if exceptions:
             original_file_count = len(shell_files)
             shell_files = exceptions.filter_file_exceptions_early(package, shell_files)
             if original_file_count > len(shell_files):
-                print(
-                    "  After filtering, {} shell files will be scanned.".format(
-                        len(shell_files)
-                    )
+                logging.info(
+                    "  After filtering, %d shell files will be scanned.",
+                    len(shell_files),
                 )
 
         package["shell_src"] = shell_files
diff --git a/statick_tool/plugins/discovery/xml_discovery_plugin.py b/statick_tool/plugins/discovery/xml_discovery_plugin.py
index 2c3d67b2..35bbe6ab 100644
--- a/statick_tool/plugins/discovery/xml_discovery_plugin.py
+++ b/statick_tool/plugins/discovery/xml_discovery_plugin.py
@@ -1,4 +1,5 @@
 """Discover XML files to analyze."""
+import logging
 from collections import OrderedDict
 from typing import List, Optional, Tuple
 
@@ -29,15 +30,13 @@ def scan(
 
         xml_files = list(OrderedDict.fromkeys(xml_files))
 
-        print("  {} XML files found.".format(len(xml_files)))
+        logging.info("  %d XML files found.", len(xml_files))
         if exceptions:
             original_file_count = len(xml_files)
             xml_files = exceptions.filter_file_exceptions_early(package, xml_files)
             if original_file_count > len(xml_files):
-                print(
-                    "  After filtering, {} XML files will be scanned.".format(
-                        len(xml_files)
-                    )
+                logging.info(
+                    "  After filtering, %d XML files will be scanned.", len(xml_files)
                 )
 
         package["xml"] = xml_files
diff --git a/statick_tool/plugins/discovery/yaml_discovery_plugin.py b/statick_tool/plugins/discovery/yaml_discovery_plugin.py
index f87e6540..92a515f2 100644
--- a/statick_tool/plugins/discovery/yaml_discovery_plugin.py
+++ b/statick_tool/plugins/discovery/yaml_discovery_plugin.py
@@ -1,4 +1,5 @@
 """Discover YAML files to analyze."""
+import logging
 from collections import OrderedDict
 from typing import List, Optional
 
@@ -29,15 +30,13 @@ def scan(
 
         yaml_files = list(OrderedDict.fromkeys(yaml_files))
 
-        print("  {} YAML files found.".format(len(yaml_files)))
+        logging.info("  %d YAML files found.", len(yaml_files))
         if exceptions:
             original_file_count = len(yaml_files)
             yaml_files = exceptions.filter_file_exceptions_early(package, yaml_files)
             if original_file_count > len(yaml_files):
-                print(
-                    "  After filtering, {} YAML files will be scanned.".format(
-                        len(yaml_files)
-                    )
+                logging.info(
+                    "  After filtering, %d YAML files will be scanned.", len(yaml_files)
                 )
 
         package["yaml"] = yaml_files
diff --git a/statick_tool/plugins/reporting/write_jenkins_warnings_ng_reporting_plugin.py b/statick_tool/plugins/reporting/write_jenkins_warnings_ng_reporting_plugin.py
index f19d5190..2ee9d8d5 100644
--- a/statick_tool/plugins/reporting/write_jenkins_warnings_ng_reporting_plugin.py
+++ b/statick_tool/plugins/reporting/write_jenkins_warnings_ng_reporting_plugin.py
@@ -1,5 +1,6 @@
 """Write Statick results to Jenkins Warnings-NG plugin json-log compatible output."""
 import json
+import logging
 import os
 from typing import Dict, List, Optional, Tuple
 
@@ -42,13 +43,13 @@ def report(
         if not os.path.exists(output_dir):
             os.mkdir(output_dir)
         if not os.path.isdir(output_dir):
-            print("Unable to create output directory at {}!".format(output_dir))
+            logging.error("Unable to create output directory at %s!", output_dir)
             return None, False
 
         output_file = os.path.join(
             output_dir, package.name + "-" + level + ".json.statick"
         )
-        print("Writing output to {}".format(output_file))
+        logging.info("Writing output to %s", output_file)
         with open(output_file, "w") as out:
             for _, value in issues.items():
                 for issue in value:
@@ -61,9 +62,11 @@ def report(
                         if int(issue.severity) > 4:
                             severity = "ERROR"
                     except ValueError as ex:
-                        print(
-                            "Invalid severity integer ({}), using default 'LOW' severity. "
-                            "Error = {}".format(issue.severity, ex)
+                        logging.warning(
+                            "Invalid severity integer (%s), using default 'LOW' "
+                            " severity. Error = %s",
+                            issue.severity,
+                            ex,
                         )
                     issue_dict = {
                         "fileName": issue.filename,
diff --git a/statick_tool/plugins/tool/bandit_tool_plugin.py b/statick_tool/plugins/tool/bandit_tool_plugin.py
index e5150b04..877392fc 100644
--- a/statick_tool/plugins/tool/bandit_tool_plugin.py
+++ b/statick_tool/plugins/tool/bandit_tool_plugin.py
@@ -1,6 +1,7 @@
 """Apply bandit tool and gather results."""
 import argparse
 import csv
+import logging
 import subprocess
 from typing import List, Optional
 
@@ -50,20 +51,19 @@ def scan(self, package: Package, level: str) -> Optional[List[Issue]]:
         except subprocess.CalledProcessError as ex:
             output = ex.output
             if ex.returncode != 1:
-                print("bandit failed! Returncode = {}".format(str(ex.returncode)))
-                print("{}".format(ex.output))
+                logging.warning("bandit failed! Returncode = %d", ex.returncode)
+                logging.warning("%s exception: %s", self.get_name(), ex.output)
                 return None
 
         except OSError as ex:
-            print("Couldn't find {}! ({})".format(bandit_bin, ex))
+            logging.warning("Couldn't find %s! (%s)", bandit_bin, ex)
             return None
 
-        if self.plugin_context and self.plugin_context.args.show_tool_output:
-            print("{}".format(output))
+        logging.debug("%s", output)
 
         if self.plugin_context and self.plugin_context.args.output_directory:
-            with open(self.get_name() + ".log", "w") as f:
-                f.write(output)
+            with open(self.get_name() + ".log", "w") as fid:
+                fid.write(output)
 
         issues = self.parse_output(output.splitlines())
         return issues
diff --git a/statick_tool/plugins/tool/black_tool_plugin.py b/statick_tool/plugins/tool/black_tool_plugin.py
index c525d828..25b436ed 100644
--- a/statick_tool/plugins/tool/black_tool_plugin.py
+++ b/statick_tool/plugins/tool/black_tool_plugin.py
@@ -1,4 +1,5 @@
 """Apply black tool and gather results."""
+import logging
 import re
 import subprocess
 from typing import List, Match, Optional, Pattern
@@ -34,30 +35,29 @@ def scan(self, package: Package, level: str) -> Optional[List[Issue]]:
             except subprocess.CalledProcessError as ex:
                 # Return code 123 means there was an internal error
                 if ex.returncode == 123:
-                    print("Black encountered internal error")
-                    print("{}".format(ex.output))
+                    logging.warning("Black encountered internal error")
+                    logging.warning("black exception: %s", ex.output)
 
                 # Return code 1 just means "found problems"
                 elif ex.returncode != 1:
-                    print("Problem {}".format(ex.returncode))
-                    print("{}".format(ex.output))
+                    logging.warning("Problem %d", ex.returncode)
+                    logging.warning("%s exception: %s", self.get_name(), ex.output)
                     return None
 
                 output = ex.output
 
             except OSError as ex:
-                print("Couldn't find {}! ({})".format(tool_bin, ex))
+                logging.info("Couldn't find %s! (%s)", tool_bin, ex)
                 return None
 
-            if self.plugin_context and self.plugin_context.args.show_tool_output:
-                print("{}".format(output))
+            logging.debug("%s", output)
 
             total_output.append(output)
 
         if self.plugin_context and self.plugin_context.args.output_directory:
-            with open(self.get_name() + ".log", "w") as fname:
+            with open(self.get_name() + ".log", "w") as fid:
                 for output in total_output:
-                    fname.write(output)
+                    fid.write(output)
 
         issues = self.parse_output(total_output)
         return issues
diff --git a/statick_tool/plugins/tool/catkin_lint_tool_plugin.py b/statick_tool/plugins/tool/catkin_lint_tool_plugin.py
index 189ce4d0..d59aa524 100644
--- a/statick_tool/plugins/tool/catkin_lint_tool_plugin.py
+++ b/statick_tool/plugins/tool/catkin_lint_tool_plugin.py
@@ -1,4 +1,5 @@
 """Apply catkin_lint tool and gather results."""
+import logging
 import os
 import re
 import subprocess
@@ -32,20 +33,19 @@ def scan(self, package: Package, level: str) -> Optional[List[Issue]]:
         except subprocess.CalledProcessError as ex:
             output = ex.output
             if ex.returncode != 1:
-                print("catkin_lint failed! Returncode = {}".format(ex.returncode))
-                print("{}".format(ex.output))
+                logging.warning("catkin_lint failed! Returncode = %d", ex.returncode)
+                logging.warning("%s exception: %s", self.get_name(), ex.output)
                 return None
 
         except OSError as ex:
-            print("Couldn't find catkin_lint executable! ({})".format(ex))
+            logging.warning("Couldn't find catkin_lint executable! (%s)", ex)
             return None
 
-        if self.plugin_context and self.plugin_context.args.show_tool_output:
-            print("{}".format(output))
+        logging.debug("%s", output)
 
         if self.plugin_context and self.plugin_context.args.output_directory:
-            with open(self.get_name() + ".log", "w") as fname:
-                fname.write(output)
+            with open(self.get_name() + ".log", "w") as fid:
+                fid.write(output)
 
         issues = self.parse_output(package, output)
         return issues
diff --git a/statick_tool/plugins/tool/cccc_tool_plugin.py b/statick_tool/plugins/tool/cccc_tool_plugin.py
index 5ca7f970..27986d94 100644
--- a/statick_tool/plugins/tool/cccc_tool_plugin.py
+++ b/statick_tool/plugins/tool/cccc_tool_plugin.py
@@ -10,6 +10,7 @@
 """
 import argparse
 import csv
+import logging
 import subprocess
 from typing import Any, Dict, List, Optional
 
@@ -69,16 +70,15 @@ def scan(  # pylint: disable=too-many-branches
                 if ex.returncode == 1:
                     log_output = ex.output
                 else:
-                    print("Problem {}".format(ex.returncode))
-                    print("{}".format(ex.output))
+                    logging.warning("Problem %d", ex.returncode)
+                    logging.warning("%s exception: %s", self.get_name(), ex.output)
                     return None
 
             except OSError as ex:
-                print("Couldn't find cccc executable! ({})".format(ex))
+                logging.warning("Couldn't find cccc executable! (%s)", ex)
                 return None
 
-            if self.plugin_context and self.plugin_context.args.show_tool_output:
-                print("{}".format(log_output))  # type: ignore
+            logging.debug("%s", log_output)
 
         if self.plugin_context and self.plugin_context.args.output_directory:
             with open(self.get_name() + ".log", "wb") as flog:
diff --git a/statick_tool/plugins/tool/clang_format_tool_plugin.py b/statick_tool/plugins/tool/clang_format_tool_plugin.py
index 21d3c1a2..feeade0b 100644
--- a/statick_tool/plugins/tool/clang_format_tool_plugin.py
+++ b/statick_tool/plugins/tool/clang_format_tool_plugin.py
@@ -1,6 +1,7 @@
 """Apply clang-format tool and gather results."""
 import argparse
 import difflib
+import logging
 import os
 import re
 import subprocess
@@ -96,8 +97,8 @@ def scan(
                     total_output.append(output)
 
         except (IOError, OSError) as ex:
-            print("clang-format binary failed: {}".format(clang_format_bin))
-            print("Error = {}".format(str(ex.strerror)))
+            logging.warning("clang-format binary failed: %s", clang_format_bin)
+            logging.warning("%s exception: %s", self.get_name(), ex.strerror)
             if (
                 self.plugin_context
                 and self.plugin_context.args.clang_format_raise_exception
@@ -106,9 +107,9 @@ def scan(
             return []
 
         except subprocess.CalledProcessError as ex:
-            print("clang-format binary failed: {}.".format(clang_format_bin))
-            print("Returncode: {}".format(str(ex.returncode)))
-            print("Error: {}".format(ex.output))
+            logging.warning("clang-format binary failed: %s.", clang_format_bin)
+            logging.warning("Returncode: %d", ex.returncode)
+            logging.warning("%s exception: %s", self.get_name(), ex.output)
             if (
                 self.plugin_context
                 and self.plugin_context.args.clang_format_raise_exception
@@ -116,14 +117,13 @@ def scan(
                 return None
             return []
 
-        if self.plugin_context and self.plugin_context.args.show_tool_output:
-            for output in total_output:
-                print("{}".format(output))
+        for output in total_output:
+            logging.debug("%s", output)
 
         if self.plugin_context and self.plugin_context.args.output_directory:
-            with open(self.get_name() + ".log", "w") as fname:
+            with open(self.get_name() + ".log", "w") as fid:
                 for output in total_output:
-                    fname.write(output)
+                    fid.write(output)
 
         issues = self.parse_output(total_output)  # type: List[Issue]
         return issues
@@ -170,14 +170,14 @@ def check_configuration(self, clang_format_bin: str) -> Optional[bool]:
                             raise exc
 
         except (IOError, OSError) as ex:
-            print("{}".format(exc_msg))
-            print("Error: {}".format(str(ex.strerror)))
+            logging.warning("%s", exc_msg)
+            logging.warning("%s exception: %s", self.get_name(), ex.strerror)
             if self.plugin_context.args.clang_format_raise_exception:
                 return None
             return False
 
         except subprocess.CalledProcessError as ex:
-            print("{} Returncode = {}".format(exc_msg, str(ex.returncode)))
+            logging.warning("%s Returncode = %d", exc_msg, ex.returncode)
             if self.plugin_context.args.clang_format_raise_exception:
                 return None
 
diff --git a/statick_tool/plugins/tool/clang_tidy_tool_plugin.py b/statick_tool/plugins/tool/clang_tidy_tool_plugin.py
index c478a5a1..0e2eb03f 100644
--- a/statick_tool/plugins/tool/clang_tidy_tool_plugin.py
+++ b/statick_tool/plugins/tool/clang_tidy_tool_plugin.py
@@ -1,5 +1,6 @@
 """Apply clang-tidy tool and gather results."""
 import argparse
+import logging
 import re
 import subprocess
 from typing import List, Match, Optional, Pattern
@@ -81,20 +82,19 @@ def scan(self, package: Package, level: str) -> Optional[List[Issue]]:
         except subprocess.CalledProcessError as ex:
             output = ex.output
             if ex.returncode != 1:
-                print("clang-tidy failed! Returncode = {}".format(str(ex.returncode)))
-                print("{}".format(ex.output))
+                logging.warning("clang-tidy failed! Returncode = %d", ex.returncode)
+                logging.warning("%s exception: %s", self.get_name(), ex.output)
                 return None
 
         except OSError as ex:
-            print("Couldn't find {}! ({})".format(clang_tidy_bin, ex))
+            logging.warning("Couldn't find %s! (%s)", clang_tidy_bin, ex)
             return None
 
-        if self.plugin_context and self.plugin_context.args.show_tool_output:
-            print("{}".format(output))
+        logging.debug("%s", output)
 
         if self.plugin_context and self.plugin_context.args.output_directory:
-            with open(self.get_name() + ".log", "w") as fname:
-                fname.write(output)
+            with open(self.get_name() + ".log", "w") as fid:
+                fid.write(output)
 
         issues = self.parse_output(output)  # type: List[Issue]
         return issues
diff --git a/statick_tool/plugins/tool/cmakelint_tool_plugin.py b/statick_tool/plugins/tool/cmakelint_tool_plugin.py
index e5befbb6..f466fd4b 100644
--- a/statick_tool/plugins/tool/cmakelint_tool_plugin.py
+++ b/statick_tool/plugins/tool/cmakelint_tool_plugin.py
@@ -1,4 +1,5 @@
 """Apply cmakelint tool and gather results."""
+import logging
 import os
 import re
 import subprocess
@@ -37,20 +38,19 @@ def scan(self, package: Package, level: str) -> Optional[List[Issue]]:
             if ex.returncode == 1:
                 output = ex.output
             else:
-                print("Problem {}".format(ex.returncode))
-                print("{}".format(ex.output))
+                logging.warning("Problem %d", ex.returncode)
+                logging.warning("%s exception: %s", self.get_name(), ex.output)
                 return None
 
         except OSError as ex:
-            print("Couldn't find cmakelint executable! ({})".format(ex))
+            logging.warning("Couldn't find cmakelint executable! (%s)", ex)
             return None
 
-        if self.plugin_context and self.plugin_context.args.show_tool_output:
-            print("{}".format(output))
+        logging.debug("%s", output)
 
         if self.plugin_context and self.plugin_context.args.output_directory:
-            with open(self.get_name() + ".log", "w") as f:
-                f.write(output)
+            with open(self.get_name() + ".log", "w") as fid:
+                fid.write(output)
 
         issues = self.parse_output(output)
         return issues
diff --git a/statick_tool/plugins/tool/cppcheck_tool_plugin.py b/statick_tool/plugins/tool/cppcheck_tool_plugin.py
index f9047a2b..a46dd2fb 100644
--- a/statick_tool/plugins/tool/cppcheck_tool_plugin.py
+++ b/statick_tool/plugins/tool/cppcheck_tool_plugin.py
@@ -1,5 +1,6 @@
 """Apply cppcheck tool and gather results."""
 import argparse
+import logging
 import os
 import re
 import subprocess
@@ -67,21 +68,23 @@ def scan(self, package: Package, level: str) -> Optional[List[Issue]]:
                 ver = float(match.group(2))
                 # If specific version is not specified just use the installed version.
                 if user_version is not None and ver != float(user_version):
-                    print(
-                        "You need version {} of cppcheck, but you have {}. "
+                    logging.warning(
+                        "You need version %s of cppcheck, but you have %s. "
                         "See README.md for instuctions on how to install the "
-                        "proper version".format(user_version, match.group(2))
+                        "proper version",
+                        user_version,
+                        match.group(2),
                     )
                     return None
 
         except OSError as ex:
-            print("Cppcheck not found! ({})".format(ex))
+            logging.warning("Cppcheck not found! (%s)", ex)
             return None
 
         except subprocess.CalledProcessError as ex:
             output = ex.output
-            print("Cppcheck failed! Returncode = {}".format(ex.returncode))
-            print("Exception output: {}".format(ex.output))
+            logging.warning("Cppcheck failed! Returncode = %d", ex.returncode)
+            logging.warning("%s exception: %s", self.get_name(), ex.output)
             return None
 
         files = []  # type: List[str]
@@ -113,16 +116,15 @@ def scan(self, package: Package, level: str) -> Optional[List[Issue]]:
             )
         except subprocess.CalledProcessError as ex:
             output = ex.output
-            print("cppcheck failed! Returncode = {}".format(ex.returncode))
-            print("{}".format(ex.output))
+            logging.warning("cppcheck failed! Returncode = %d", ex.returncode)
+            logging.warning("%s exception: %s", self.get_name(), ex.output)
             return None
 
-        if self.plugin_context and self.plugin_context.args.show_tool_output:
-            print("{}".format(output))
+        logging.debug("%s", output)
 
         if self.plugin_context and self.plugin_context.args.output_directory:
-            with open(self.get_name() + ".log", "w") as fname:
-                fname.write(output)
+            with open(self.get_name() + ".log", "w") as fid:
+                fid.write(output)
 
         issues = self.parse_output(output)
         return issues
diff --git a/statick_tool/plugins/tool/cpplint_tool_plugin.py b/statick_tool/plugins/tool/cpplint_tool_plugin.py
index a31c5d45..9c371236 100644
--- a/statick_tool/plugins/tool/cpplint_tool_plugin.py
+++ b/statick_tool/plugins/tool/cpplint_tool_plugin.py
@@ -1,4 +1,5 @@
 """Apply Cpplint tool and gather results."""
+import logging
 import os
 import re
 import subprocess
@@ -25,7 +26,7 @@ def scan(self, package: Package, level: str) -> Optional[List[Issue]]:
             return []
 
         if "cpplint" not in package:
-            print("  cpplint not found!")
+            logging.warning("  cpplint not found!")
             return None
 
         flags = []  # type: List[str]
@@ -46,20 +47,19 @@ def scan(self, package: Package, level: str) -> Optional[List[Issue]]:
         except subprocess.CalledProcessError as ex:
             output = ex.output
             if ex.returncode != 1:
-                print("cpplint failed! Returncode = {}".format(str(ex.returncode)))
-                print("{}".format(ex.output))
+                logging.warning("cpplint failed! Returncode = %d", ex.returncode)
+                logging.warning("%s exception: %s", self.get_name(), ex.output)
                 return None
 
         except OSError as ex:
-            print("Couldn't find cpplint executable! ({})".format(ex))
+            logging.warning("Couldn't find cpplint executable! (%s)", ex)
             return None
 
-        if self.plugin_context and self.plugin_context.args.show_tool_output:
-            print("{}".format(output))
+        logging.debug("%s", output)
 
         if self.plugin_context and self.plugin_context.args.output_directory:
-            with open(self.get_name() + ".log", "w") as f:
-                f.write(output)
+            with open(self.get_name() + ".log", "w") as fid:
+                fid.write(output)
 
         issues = self.parse_output(output)
         return issues
diff --git a/statick_tool/plugins/tool/docformatter_tool_plugin.py b/statick_tool/plugins/tool/docformatter_tool_plugin.py
index f0de4b54..ef33fde8 100644
--- a/statick_tool/plugins/tool/docformatter_tool_plugin.py
+++ b/statick_tool/plugins/tool/docformatter_tool_plugin.py
@@ -1,4 +1,5 @@
 """Apply docformatter tool and gather results."""
+import logging
 import os
 import re
 import subprocess
@@ -16,9 +17,8 @@ def get_name(self) -> str:
         """Get name of tool."""
         return "docformatter"
 
-    def scan(  # pylint: disable=too-many-locals, too-many-branches, too-many-return-statements
-        self, package: Package, level: str
-    ) -> Optional[List[Issue]]:
+    # pylint: disable=too-many-locals, too-many-branches, too-many-return-statements
+    def scan(self, package: Package, level: str) -> Optional[List[Issue]]:
         """Run tool and gather output."""
         if "python_src" not in package:
             return []
@@ -37,29 +37,30 @@ def scan(  # pylint: disable=too-many-locals, too-many-branches, too-many-return
                 )
 
             except (IOError, OSError) as ex:
-                print("docformatter binary failed: {}".format(tool_bin))
-                print("Error = {}".format(str(ex.strerror)))
+                logging.warning("docformatter binary failed: %s", tool_bin)
+                logging.warning("Error = %s", ex.strerror)
                 return []
 
             except subprocess.CalledProcessError as ex:
-                print("docformatter binary failed: {}.".format(tool_bin))
-                print("Returncode: {}".format(str(ex.returncode)))
-                print("Error: {}".format(ex.output))
+                logging.warning("docformatter binary failed: %s.", tool_bin)
+                logging.warning("Returncode: %d", ex.returncode)
+                logging.warning("%s exception: %s", self.get_name(), ex.output)
                 total_output.append(ex.output)
                 continue
 
-        if self.plugin_context and self.plugin_context.args.show_tool_output:
-            for output in total_output:
-                print("{}".format(output))
+        for output in total_output:
+            logging.debug("%s", output)
 
         if self.plugin_context and self.plugin_context.args.output_directory:
-            with open(self.get_name() + ".log", "w") as fname:
+            with open(self.get_name() + ".log", "w") as fid:
                 for output in total_output:
-                    fname.write(output)
+                    fid.write(output)
 
         issues = self.parse_output(total_output)  # type: List[Issue]
         return issues
 
+    # pylint: enable=too-many-locals, too-many-branches, too-many-return-statements
+
     def parse_output(self, total_output: List[str]) -> List[Issue]:
         """Parse tool output and report issues."""
         # Gives relative path to file.
diff --git a/statick_tool/plugins/tool/flawfinder_tool_plugin.py b/statick_tool/plugins/tool/flawfinder_tool_plugin.py
index b1ad3aba..e1d56b37 100644
--- a/statick_tool/plugins/tool/flawfinder_tool_plugin.py
+++ b/statick_tool/plugins/tool/flawfinder_tool_plugin.py
@@ -1,4 +1,5 @@
 """Apply flawfinder tool and gather results."""
+import logging
 import re
 import subprocess
 from typing import List, Match, Optional, Pattern
@@ -31,23 +32,22 @@ def scan(self, package: Package, level: str) -> Optional[List[Issue]]:
                     subproc_args, stderr=subprocess.STDOUT, universal_newlines=True
                 )
             except subprocess.CalledProcessError as ex:
-                print("Problem {}".format(ex.returncode))
-                print("{}".format(ex.output))
+                logging.warning("Problem %d", ex.returncode)
+                logging.warning("%s exception: %s", self.get_name(), ex.output)
                 return None
 
             except OSError as ex:
-                print("Couldn't find flawfinder executable! ({})".format(ex))
+                logging.warning("Couldn't find flawfinder executable! (%s)", ex)
                 return None
 
-            if self.plugin_context and self.plugin_context.args.show_tool_output:
-                print("{}".format(output))
+            logging.debug("%s", output)
 
             total_output.append(output)
 
         if self.plugin_context and self.plugin_context.args.output_directory:
-            with open(self.get_name() + ".log", "w") as f:
+            with open(self.get_name() + ".log", "w") as fid:
                 for output in total_output:
-                    f.write(output)
+                    fid.write(output)
 
         issues = self.parse_output(total_output)
         return issues
diff --git a/statick_tool/plugins/tool/lizard_tool_plugin.py b/statick_tool/plugins/tool/lizard_tool_plugin.py
index f2e1d557..3682e126 100644
--- a/statick_tool/plugins/tool/lizard_tool_plugin.py
+++ b/statick_tool/plugins/tool/lizard_tool_plugin.py
@@ -1,5 +1,6 @@
 """Apply lizard tool and gather results."""
 import io
+import logging
 import re
 from contextlib import redirect_stdout
 from typing import List, Match, Optional, Pattern
@@ -57,12 +58,10 @@ def scan(self, package: Package, level: str) -> Optional[List[Issue]]:
         output = lizard_output.getvalue()
         lizard.print_extension_results(options.extensions)
 
-        if self.plugin_context:
-            if self.plugin_context.args.show_tool_output:
-                print("{}".format(output))
-            if self.plugin_context.args.output_directory:
-                with open(self.get_name() + ".log", "w") as fid:
-                    fid.write(output)
+        logging.debug("%s", output)
+        if self.plugin_context and self.plugin_context.args.output_directory:
+            with open(self.get_name() + ".log", "w") as fid:
+                fid.write(output)
 
         issues = self.parse_output(output)
 
diff --git a/statick_tool/plugins/tool/make_tool_plugin.py b/statick_tool/plugins/tool/make_tool_plugin.py
index 376bc348..52d86549 100644
--- a/statick_tool/plugins/tool/make_tool_plugin.py
+++ b/statick_tool/plugins/tool/make_tool_plugin.py
@@ -1,4 +1,5 @@
 """Apply make tool and gather results."""
+import logging
 import re
 import subprocess
 from typing import Any, List, Match, Optional, Pattern
@@ -18,7 +19,7 @@ def get_name(self) -> str:
     def scan(self, package: Package, level: str) -> Optional[List[Issue]]:
         """Run tool and gather output."""
         if "make_targets" not in package or not package["make_targets"]:
-            print("  Skipping make. No targets.")
+            logging.info("  Skipping make. No targets.")
             return []
 
         output = None
@@ -29,22 +30,22 @@ def scan(self, package: Package, level: str) -> Optional[List[Issue]]:
             output = subprocess.check_output(
                 make_args, stderr=subprocess.STDOUT, universal_newlines=True
             )
-            if self.plugin_context and self.plugin_context.args.show_tool_output:
-                print("{}".format(output))
 
         except subprocess.CalledProcessError as ex:
             output = ex.output
-            print("Make failed! Returncode = {}".format(ex.returncode))
-            print("Exception output: {}".format(ex.output))
+            logging.warning("Make failed! Returncode = %d", ex.returncode)
+            logging.warning("%s exception: %s", self.get_name(), ex.output)
             return None
 
         except OSError as ex:
-            print("Couldn't find make executable! ({})".format(ex))
+            logging.warning("Couldn't find make executable! (%s)", ex)
             return None
 
+        logging.debug("%s", output)
+
         if self.plugin_context and self.plugin_context.args.output_directory:
-            with open(self.get_name() + ".log", "w") as fname:
-                fname.write(output)
+            with open(self.get_name() + ".log", "w") as fid:
+                fid.write(output)
 
         issues = self.parse_output(package, output)
         return issues
diff --git a/statick_tool/plugins/tool/mypy_tool_plugin.py b/statick_tool/plugins/tool/mypy_tool_plugin.py
index 0ee24a24..7c86caa4 100644
--- a/statick_tool/plugins/tool/mypy_tool_plugin.py
+++ b/statick_tool/plugins/tool/mypy_tool_plugin.py
@@ -1,4 +1,5 @@
 """Apply mypy tool and gather results."""
+import logging
 import re
 import subprocess
 import sys
@@ -16,9 +17,8 @@ def get_name(self) -> str:
         """Get name of tool."""
         return "mypy"
 
-    def scan(  # pylint: disable=too-many-locals, too-many-branches, too-many-return-statements
-        self, package: Package, level: str
-    ) -> Optional[List[Issue]]:
+    # pylint: disable=too-many-locals, too-many-branches, too-many-return-statements
+    def scan(self, package: Package, level: str) -> Optional[List[Issue]]:
         """Run tool and gather output."""
         if "python_src" not in package:
             return []
@@ -41,29 +41,30 @@ def scan(  # pylint: disable=too-many-locals, too-many-branches, too-many-return
                 )
 
             except (IOError, OSError) as ex:
-                print("mypy binary failed: {}".format(tool_bin))
-                print("Error = {}".format(str(ex.strerror)))
+                logging.warning("mypy binary failed: %s", tool_bin)
+                logging.warning("Error = %s", ex.strerror)
                 return []
 
             except subprocess.CalledProcessError as ex:
-                print("mypy binary failed: {}.".format(tool_bin))
-                print("Returncode: {}".format(str(ex.returncode)))
-                print("Error: {}".format(ex.output))
+                logging.warning("mypy binary failed: %s.", tool_bin)
+                logging.warning("Returncode: %d", ex.returncode)
+                logging.warning("%s exception: %s", self.get_name(), ex.output)
                 total_output.append(ex.output)
                 continue
 
-        if self.plugin_context and self.plugin_context.args.show_tool_output:
-            for output in total_output:
-                print("{}".format(output))
+        for output in total_output:
+            logging.debug("%s", output)
 
         if self.plugin_context and self.plugin_context.args.output_directory:
-            with open(self.get_name() + ".log", "w") as fname:
+            with open(self.get_name() + ".log", "w") as fid:
                 for output in total_output:
-                    fname.write(output)
+                    fid.write(output)
 
         issues = self.parse_output(total_output)  # type: List[Issue]
         return issues
 
+    # pylint: disable=too-many-locals, too-many-branches, too-many-return-statements
+
     def parse_output(self, total_output: List[str]) -> List[Issue]:
         """Parse tool output and report issues."""
         # file:line: severity: msg type
diff --git a/statick_tool/plugins/tool/perlcritic_tool_plugin.py b/statick_tool/plugins/tool/perlcritic_tool_plugin.py
index dffadbe9..dd02efc0 100644
--- a/statick_tool/plugins/tool/perlcritic_tool_plugin.py
+++ b/statick_tool/plugins/tool/perlcritic_tool_plugin.py
@@ -1,5 +1,6 @@
 """Apply Perl::Critic tool and gather results."""
 import argparse
+import logging
 import subprocess
 from typing import List, Optional
 
@@ -52,20 +53,19 @@ def scan(self, package: Package, level: str) -> Optional[List[Issue]]:
         except subprocess.CalledProcessError as ex:
             output = ex.output
             if ex.returncode != 2:
-                print("perlcritic failed! Returncode = {}".format(str(ex.returncode)))
-                print("{}".format(ex.output))
+                logging.warning("perlcritic failed! Returncode = %d", ex.returncode)
+                logging.warning("%s exception: %s", self.get_name(), ex.output)
                 return []
 
         except OSError as ex:
-            print("Couldn't find {}! ({})".format(perlcritic_bin, ex))
+            logging.warning("Couldn't find %s! (%s)", perlcritic_bin, ex)
             return []
 
-        if self.plugin_context and self.plugin_context.args.show_tool_output:
-            print("{}".format(output))
+        logging.debug("%s", output)
 
         if self.plugin_context and self.plugin_context.args.output_directory:
-            with open(self.get_name() + ".log", "wt") as f:
-                f.write(output)
+            with open(self.get_name() + ".log", "wt") as fid:
+                fid.write(output)
 
         issues = self.parse_output(output.splitlines())
 
diff --git a/statick_tool/plugins/tool/pycodestyle_tool_plugin.py b/statick_tool/plugins/tool/pycodestyle_tool_plugin.py
index f2345af5..eac9e57e 100644
--- a/statick_tool/plugins/tool/pycodestyle_tool_plugin.py
+++ b/statick_tool/plugins/tool/pycodestyle_tool_plugin.py
@@ -1,4 +1,5 @@
 """Apply pycodestyle tool and gather results."""
+import logging
 import re
 import subprocess
 from typing import List, Match, Optional, Pattern
@@ -34,25 +35,24 @@ def scan(self, package: Package, level: str) -> Optional[List[Issue]]:
             except subprocess.CalledProcessError as ex:
                 # Return code 1 just means "found problems"
                 if ex.returncode != 1:
-                    print("Problem {}".format(ex.returncode))
-                    print("{}".format(ex.output))
+                    logging.warning("Problem %d", ex.returncode)
+                    logging.warning("%s exception: %s", self.get_name(), ex.output)
                     return None
 
                 output = ex.output
 
             except OSError as ex:
-                print("Couldn't find {}! ({})".format(tool_bin, ex))
+                logging.warning("Couldn't find %s! (%s)", tool_bin, ex)
                 return None
 
-            if self.plugin_context and self.plugin_context.args.show_tool_output:
-                print("{}".format(output))
+            logging.debug("%s", output)
 
             total_output.append(output)
 
         if self.plugin_context and self.plugin_context.args.output_directory:
-            with open(self.get_name() + ".log", "w") as fname:
+            with open(self.get_name() + ".log", "w") as fid:
                 for output in total_output:
-                    fname.write(output)
+                    fid.write(output)
 
         issues = self.parse_output(total_output)
         return issues
diff --git a/statick_tool/plugins/tool/pydocstyle_tool_plugin.py b/statick_tool/plugins/tool/pydocstyle_tool_plugin.py
index 9e6f18c6..ae5f6263 100644
--- a/statick_tool/plugins/tool/pydocstyle_tool_plugin.py
+++ b/statick_tool/plugins/tool/pydocstyle_tool_plugin.py
@@ -1,4 +1,5 @@
 """Apply pydocstyle tool and gather results."""
+import logging
 import re
 import subprocess
 from typing import List, Match, Optional, Pattern
@@ -33,25 +34,24 @@ def scan(self, package: Package, level: str) -> Optional[List[Issue]]:
             except subprocess.CalledProcessError as ex:
                 # Return code 1 just means "found problems"
                 if ex.returncode != 1:
-                    print("Problem {}".format(ex.returncode))
-                    print("{}".format(ex.output))
+                    logging.warning("Problem %d", ex.returncode)
+                    logging.warning("%s exception: %s", self.get_name(), ex.output)
                     return None
 
                 output = ex.output
 
             except OSError as ex:
-                print("Couldn't find {}! ({})".format(tool_bin, ex))
+                logging.warning("Couldn't find %s! (%s)", tool_bin, ex)
                 return None
 
-            if self.plugin_context and self.plugin_context.args.show_tool_output:
-                print("{}".format(output))
+            logging.debug("%s: %s", src, output)
 
             total_output.append(output)
 
         if self.plugin_context and self.plugin_context.args.output_directory:
-            with open(self.get_name() + ".log", "w") as fname:
+            with open(self.get_name() + ".log", "w") as fid:
                 for output in total_output:
-                    fname.write(output)
+                    fid.write(output)
 
         issues = self.parse_output(total_output)
         return issues
diff --git a/statick_tool/plugins/tool/pyflakes_tool_plugin.py b/statick_tool/plugins/tool/pyflakes_tool_plugin.py
index 090c0e4c..68a3d7d4 100644
--- a/statick_tool/plugins/tool/pyflakes_tool_plugin.py
+++ b/statick_tool/plugins/tool/pyflakes_tool_plugin.py
@@ -1,4 +1,5 @@
 """Apply pyflakes tool and gather results."""
+import logging
 import re
 import subprocess
 from typing import List, Match, Optional, Pattern
@@ -32,25 +33,24 @@ def scan(self, package: Package, level: str) -> Optional[List[Issue]]:
             except subprocess.CalledProcessError as ex:
                 # Return code 1 just means "found problems"
                 if ex.returncode != 1:
-                    print("Problem {}".format(ex.returncode))
-                    print("{}".format(ex.output))
+                    logging.warning("Problem %d", ex.returncode)
+                    logging.warning("%s exception: %s", self.get_name(), ex.output)
                     return None
 
                 output = ex.output
 
             except OSError as ex:
-                print("Couldn't find pyflakes executable! ({})".format(ex))
+                logging.warning("Couldn't find pyflakes executable! (%s)", ex)
                 return None
 
-            if self.plugin_context and self.plugin_context.args.show_tool_output:
-                print("{}".format(output))
+            logging.debug("%s: %s", src, output)
 
             total_output.append(output)
 
         if self.plugin_context and self.plugin_context.args.output_directory:
-            with open(self.get_name() + ".log", "w") as fname:
+            with open(self.get_name() + ".log", "w") as fid:
                 for output in total_output:
-                    fname.write(output)
+                    fid.write(output)
 
         issues = self.parse_output(total_output)
         return issues
diff --git a/statick_tool/plugins/tool/pylint_tool_plugin.py b/statick_tool/plugins/tool/pylint_tool_plugin.py
index 1dc0b83c..7efd0fd9 100644
--- a/statick_tool/plugins/tool/pylint_tool_plugin.py
+++ b/statick_tool/plugins/tool/pylint_tool_plugin.py
@@ -1,4 +1,5 @@
 """Apply pylint tool and gather results."""
+import logging
 import re
 import subprocess
 from typing import List, Match, Optional, Pattern
@@ -36,23 +37,22 @@ def scan(self, package: Package, level: str) -> Optional[List[Issue]]:
                 if ex.returncode != 32:
                     output = ex.output
                 else:
-                    print("Problem {}".format(ex.returncode))
-                    print("{}".format(ex.output))
+                    logging.warning("Problem %d", ex.returncode)
+                    logging.warning("%s exception: %s", self.get_name(), ex.output)
                     return None
 
             except OSError as ex:
-                print("Couldn't find pylint executable! ({})".format(ex))
+                logging.warning("Couldn't find pylint executable! (%s)", ex)
                 return None
 
-            if self.plugin_context and self.plugin_context.args.show_tool_output:
-                print("{}".format(output))
+            logging.debug("%s: %s", src, output)
 
             total_output.append(output)
 
         if self.plugin_context and self.plugin_context.args.output_directory:
-            with open(self.get_name() + ".log", "w") as fname:
+            with open(self.get_name() + ".log", "w") as fid:
                 for output in total_output:
-                    fname.write(output)
+                    fid.write(output)
 
         issues = self.parse_output(total_output)
         return issues
diff --git a/statick_tool/plugins/tool/shellcheck_tool_plugin.py b/statick_tool/plugins/tool/shellcheck_tool_plugin.py
index 1c61a5df..24f5f934 100644
--- a/statick_tool/plugins/tool/shellcheck_tool_plugin.py
+++ b/statick_tool/plugins/tool/shellcheck_tool_plugin.py
@@ -4,6 +4,7 @@
 """
 import argparse
 import json
+import logging
 import subprocess
 from typing import Any, List, Optional
 
@@ -55,20 +56,19 @@ def scan(self, package: Package, level: str) -> Optional[List[Issue]]:
         except subprocess.CalledProcessError as ex:
             output = ex.output
             if ex.returncode != 1:
-                print("shellcheck failed! Returncode = {}".format(str(ex.returncode)))
-                print("{}".format(ex.output))
+                logging.warning("shellcheck failed! Returncode = %d", ex.returncode)
+                logging.warning("%s exception: %s", self.get_name(), ex.output)
                 return None
 
         except OSError as ex:
-            print("Couldn't find {}! ({})".format(shellcheck_bin, ex))
+            logging.warning("Couldn't find %s! (%s)", shellcheck_bin, ex)
             return None
 
-        if self.plugin_context and self.plugin_context.args.show_tool_output:
-            print("{}".format(output))
+        logging.debug("%s", output)
 
         if self.plugin_context and self.plugin_context.args.output_directory:
-            with open(self.get_name() + ".log", "w") as f:
-                f.write(output)
+            with open(self.get_name() + ".log", "w") as fid:
+                fid.write(output)
 
         issues = self.parse_output(json.loads(output))
         return issues
@@ -84,8 +84,7 @@ def parse_output(self, output: Any) -> List[Issue]:
                 or "code" not in item
                 or "message" not in item
             ):
-                if self.plugin_context and self.plugin_context.args.show_tool_output:
-                    print("  Found invalid shellcheck output: {}".format(item))
+                logging.debug("  Found invalid shellcheck output: %s", item)
                 continue
             if item["level"] == "style":
                 warning_level = "1"
diff --git a/statick_tool/plugins/tool/spotbugs_tool_plugin.py b/statick_tool/plugins/tool/spotbugs_tool_plugin.py
index 8fa21e61..d2cf9150 100644
--- a/statick_tool/plugins/tool/spotbugs_tool_plugin.py
+++ b/statick_tool/plugins/tool/spotbugs_tool_plugin.py
@@ -1,4 +1,5 @@
 """Apply spotbugs tool and gather results."""
+import logging
 import os
 import subprocess
 import xml.etree.ElementTree as etree
@@ -25,7 +26,9 @@ def scan(self, package: Package, level: str) -> Optional[List[Issue]]:
         """Run tool and gather output."""
         # Sanity check - make sure mvn exists
         if not self.command_exists("mvn"):
-            print("Couldn't find 'mvn' command, can't run Spotbugs Maven integration")
+            logging.warning(
+                "Couldn't find 'mvn' command, can't run Spotbugs Maven integration"
+            )
             return None
 
         if self.plugin_context is None:
@@ -72,16 +75,15 @@ def scan(self, package: Package, level: str) -> Optional[List[Issue]]:
                 )
             except subprocess.CalledProcessError as ex:
                 output = ex.output
-                print("spotbugs failed! Returncode = {}".format(str(ex.returncode)))
-                print("{}".format(ex.output))
+                logging.warning("spotbugs failed! Returncode = %d", ex.returncode)
+                logging.warning("%s exception: %s", self.get_name(), ex.output)
                 return None
 
             except OSError as ex:
-                print("Couldn't find maven! ({})".format(ex))
+                logging.warning("Couldn't find maven! (%s)", ex)
                 return None
 
-            if self.plugin_context and self.plugin_context.args.show_tool_output:
-                print("{}".format(output))
+            logging.debug("%s", output)
             total_output += output
 
         # The results will be output to (pom path)/target/spotbugs.xml for each pom
@@ -95,8 +97,8 @@ def scan(self, package: Package, level: str) -> Optional[List[Issue]]:
                     issues += self.parse_output(outfile.read())  # type: ignore
 
         if self.plugin_context and self.plugin_context.args.output_directory:
-            with open(self.get_name() + ".log", "w") as f:
-                f.write(total_output)
+            with open(self.get_name() + ".log", "w") as fid:
+                fid.write(total_output)
 
         return issues
 
@@ -108,10 +110,10 @@ def parse_output(self, output: str) -> Optional[List[Issue]]:
         try:
             output_xml = etree.fromstring(output)
         except etree.ParseError as ex:
-            print(
-                "Couldn't parse Spotbugs output ({})! Provided output was:\n{}".format(
-                    ex, output
-                )
+            logging.warning(
+                "Couldn't parse Spotbugs output (%s)! Provided output was:\n%s",
+                ex,
+                output,
             )
             return None
         for file_entry in output_xml.findall("file"):
@@ -128,10 +130,8 @@ def parse_output(self, output: str) -> Optional[List[Issue]]:
                         file_path = joined_path
                         break
             if not file_path:
-                print(
-                    "Couldn't find file for class {}".format(
-                        file_entry.attrib["classname"]
-                    )
+                logging.warning(
+                    "Couldn't find file for class %s", file_entry.attrib["classname"]
                 )
                 file_path = java_path_string
             for issue in file_entry.findall("BugInstance"):
diff --git a/statick_tool/plugins/tool/uncrustify_tool_plugin.py b/statick_tool/plugins/tool/uncrustify_tool_plugin.py
index 17096461..511ba5c9 100644
--- a/statick_tool/plugins/tool/uncrustify_tool_plugin.py
+++ b/statick_tool/plugins/tool/uncrustify_tool_plugin.py
@@ -1,6 +1,7 @@
 """Apply uncrustify tool and gather results."""
 import argparse
 import difflib
+import logging
 import subprocess
 from typing import List, Optional
 
@@ -88,22 +89,21 @@ def scan(  # pylint: disable=too-many-locals, too-many-branches
 
         except subprocess.CalledProcessError as ex:
             output = ex.output
-            print("uncrustify failed! Returncode = {}".format(str(ex.returncode)))
-            print("{}".format(ex.output))
+            logging.warning("uncrustify failed! Returncode = %d", ex.returncode)
+            logging.warning("%s exception: %s", self.get_name(), ex.output)
             return None
 
         except OSError as ex:
-            print("Couldn't find uncrustify executable! ({})".format(ex))
+            logging.warning("Couldn't find uncrustify executable! (%s)", ex)
             return None
 
-        if self.plugin_context and self.plugin_context.args.show_tool_output:
-            for output in total_output:
-                print("{}".format(output))
+        for output in total_output:
+            logging.debug("%s", output)
 
         if self.plugin_context and self.plugin_context.args.output_directory:
-            with open(self.get_name() + ".log", "w") as fname:
+            with open(self.get_name() + ".log", "w") as fid:
                 for output in total_output:
-                    fname.write(output)
+                    fid.write(output)
 
         issues = self.parse_output(total_output)
         return issues
diff --git a/statick_tool/plugins/tool/xmllint_tool_plugin.py b/statick_tool/plugins/tool/xmllint_tool_plugin.py
index 5b44c017..2a83f08f 100644
--- a/statick_tool/plugins/tool/xmllint_tool_plugin.py
+++ b/statick_tool/plugins/tool/xmllint_tool_plugin.py
@@ -1,4 +1,5 @@
 """Apply xmllint tool and gather results."""
+import logging
 import re
 import subprocess
 from typing import List, Match, Optional, Pattern
@@ -32,23 +33,22 @@ def scan(self, package: Package, level: str) -> Optional[List[Issue]]:
                 if ex.returncode == 1:
                     output = ex.output
                 else:
-                    print("Problem {}".format(ex.returncode))
-                    print("{}".format(ex.output))
+                    logging.warning("Problem %d", ex.returncode)
+                    logging.warning("%s exception: %s", self.get_name(), ex.output)
                     return None
 
             except OSError as ex:
-                print("Couldn't find xmllint executable! ({})".format(ex))
+                logging.warning("Couldn't find xmllint executable! (%s)", ex)
                 return None
 
-            if self.plugin_context and self.plugin_context.args.show_tool_output:
-                print("{}".format(output))
+            logging.debug("%s", output)
 
             total_output.append(output)
 
         if self.plugin_context and self.plugin_context.args.output_directory:
-            with open(self.get_name() + ".log", "w") as f:
+            with open(self.get_name() + ".log", "w") as fid:
                 for output in total_output:
-                    f.write(output)
+                    fid.write(output)
 
         issues = self.parse_output(total_output)
         return issues
diff --git a/statick_tool/plugins/tool/yamllint_tool_plugin.py b/statick_tool/plugins/tool/yamllint_tool_plugin.py
index d9b0f1c4..33fb0390 100644
--- a/statick_tool/plugins/tool/yamllint_tool_plugin.py
+++ b/statick_tool/plugins/tool/yamllint_tool_plugin.py
@@ -1,4 +1,5 @@
 """Apply yamllint tool and gather results."""
+import logging
 import re
 import subprocess
 from typing import List, Match, Optional, Pattern
@@ -33,23 +34,22 @@ def scan(self, package: Package, level: str) -> Optional[List[Issue]]:
                 if ex.returncode == 1:
                     output = ex.output
                 else:
-                    print("Problem {}".format(ex.returncode))
-                    print("{}".format(ex.output))
+                    logging.warning("Problem %d", ex.returncode)
+                    logging.warning("%s exception: %s", self.get_name(), ex.output)
                     return None
 
             except OSError as ex:
-                print("Couldn't find yamllint executable! ({})".format(ex))
+                logging.warning("Couldn't find yamllint executable! (%s)", ex)
                 return None
 
-            if self.plugin_context and self.plugin_context.args.show_tool_output:
-                print("{}".format(output))
+            logging.debug("%s: %s", yaml_file, output)
 
             total_output.append(output)
 
         if self.plugin_context and self.plugin_context.args.output_directory:
-            with open(self.get_name() + ".log", "w") as f:
+            with open(self.get_name() + ".log", "w") as fid:
                 for output in total_output:
-                    f.write(output)
+                    fid.write(output)
 
         issues = self.parse_output(total_output)
         return issues
diff --git a/statick_tool/resources.py b/statick_tool/resources.py
index 33e0c7c6..d97f58d6 100644
--- a/statick_tool/resources.py
+++ b/statick_tool/resources.py
@@ -2,6 +2,7 @@
 
 Handles chaining user directories and the default statick resource directory.
 """
+import logging
 import os
 from typing import List, Optional
 
@@ -19,10 +20,11 @@ def __init__(self, paths: List[str]) -> None:
         for path in paths:
             if os.path.exists(path) and os.path.isdir(path):
                 self.paths.append(os.path.abspath(path))
+                logging.debug("Adding %s to resources path", path)
             elif os.path.exists(path) and not os.path.isdir(path):
-                print("{} is not a directory".format(path))
+                logging.error("%s is not a directory and not used as a path", path)
             else:
-                print("Could not find path {}".format(path))
+                logging.error("Could not find path %s", path)
 
         default_path = os.path.dirname(__file__)
         self.paths.append(default_path)
diff --git a/statick_tool/statick.py b/statick_tool/statick.py
index 038f3005..4ad11ec4 100644
--- a/statick_tool/statick.py
+++ b/statick_tool/statick.py
@@ -22,8 +22,6 @@
 from statick_tool.resources import Resources
 from statick_tool.tool_plugin import ToolPlugin
 
-logging.basicConfig()
-
 
 class Statick:
     """Code analysis front-end."""
@@ -64,6 +62,30 @@ def __init__(self, user_paths: List[str]) -> None:
         self.config = None  # type: Optional[Config]
         self.exceptions = None  # type: Optional[Exceptions]
 
+    @staticmethod
+    def set_logging_level(args: argparse.Namespace) -> None:
+        """Set the logging level to use for output.
+
+        Valid levels are: DEBUG, INFO, WARNING, ERROR, CRITICAL. Specifying the level is
+        case-insensitive (both upper-case and lower-case are allowed).
+        """
+        valid_levels = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
+        log_level = args.log_level.upper()
+        if log_level not in valid_levels:
+            log_level = "WARNING"
+        if args.show_tool_output:
+            log_level = "DEBUG"
+        args.log_level = log_level
+        logging.basicConfig(level=log_level)
+        logging.root.setLevel(log_level)
+        logging.info("Log level set to %s", args.log_level.upper())
+
+        if args.show_tool_output:
+            logging.warning(
+                "The --show-tool-output argument has been deprecated since v0.5.0."
+                " Use log level of DEBUG instead. The argument will be removed in v0.6."
+            )
+
     def get_config(self, args: argparse.Namespace) -> None:
         """Get Statick configuration."""
         config_filename = "config.yaml"
@@ -72,9 +94,9 @@ def get_config(self, args: argparse.Namespace) -> None:
         try:
             self.config = Config(self.resources.get_file(config_filename))
         except OSError as ex:
-            print("Failed to access config file {}: {}".format(config_filename, ex))
+            logging.error("Failed to access config file %s: %s", config_filename, ex)
         except ValueError as ex:
-            print("Config file {} has errors: {}".format(config_filename, ex))
+            logging.error("Config file %s has errors: %s", config_filename, ex)
 
     def get_exceptions(self, args: argparse.Namespace) -> None:
         """Get Statick exceptions."""
@@ -84,13 +106,11 @@ def get_exceptions(self, args: argparse.Namespace) -> None:
         try:
             self.exceptions = Exceptions(self.resources.get_file(exceptions_filename))
         except OSError as ex:
-            print(
-                "Failed to access exceptions file {}: {}".format(
-                    exceptions_filename, ex
-                )
+            logging.error(
+                "Failed to access exceptions file %s: %s", exceptions_filename, ex
             )
         except ValueError as ex:
-            print("Exceptions file {} has errors: {}".format(exceptions_filename, ex))
+            logging.error("Exceptions file %s has errors: %s", exceptions_filename, ex)
 
     def get_ignore_packages(self) -> List[str]:
         """Get packages to ignore during scan process."""
@@ -106,6 +126,14 @@ def gather_args(self, args: argparse.ArgumentParser) -> None:
             type=str,
             help="Directory to write output files to",
         )
+        args.add_argument(
+            "--log",
+            dest="log_level",
+            type=str,
+            default="WARNING",
+            help="Verbosity level of output to show (DEBUG, INFO, WARNING, ERROR"
+            ", CRITICAL)",
+        )
         args.add_argument(
             "--show-tool-output",
             dest="show_tool_output",
@@ -161,7 +189,8 @@ def gather_args(self, args: argparse.ArgumentParser) -> None:
             dest="max_procs",
             type=int,
             default=int(multiprocessing.cpu_count() / 2),
-            help="Maximum number of CPU cores to use, only used when running on a workspace",
+            help="Maximum number of CPU cores to use, only used when running on a"
+            "workspace",
         )
         args.add_argument(
             "--packages-file",
@@ -194,17 +223,17 @@ def get_level(self, path: str, args: argparse.Namespace) -> Optional[str]:
             profile_filename = args.profile
         profile_resource = self.resources.get_file(profile_filename)
         if profile_resource is None:
-            print("Could not find profile file {}!".format(profile_filename))
+            logging.error("Could not find profile file %s!", profile_filename)
             return None
         try:
             profile = Profile(profile_resource)
         except OSError as ex:
             # This isn't quite redundant with the profile_resource check: it's possible
             # that something else triggers an OSError, like permissions.
-            print("Failed to access profile file {}: {}".format(profile_filename, ex))
+            logging.error("Failed to access profile file %s: %s", profile_filename, ex)
             return None
         except ValueError as ex:
-            print("Profile file {} has errors: {}".format(profile_filename, ex))
+            logging.error("Profile file %s has errors: %s", profile_filename, ex)
             return None
 
         package = Package(os.path.basename(path), path)
@@ -212,7 +241,9 @@ def get_level(self, path: str, args: argparse.Namespace) -> Optional[str]:
 
         return level
 
-    def run(  # pylint: disable=too-many-locals, too-many-return-statements, too-many-branches, too-many-statements
+    # pylint: disable=too-many-locals, too-many-return-statements, too-many-branches
+    # pylint: disable=too-many-statements
+    def run(
         self, path: str, args: argparse.Namespace
     ) -> Tuple[Optional[Dict[str, List[Issue]]], bool]:
         """Run scan tools against targets on path."""
@@ -220,24 +251,26 @@ def run(  # pylint: disable=too-many-locals, too-many-return-statements, too-man
 
         path = os.path.abspath(path)
         if not os.path.exists(path):
-            print("No package found at {}!".format(path))
+            logging.error("No package found at %s!", path)
             return None, False
 
         package = Package(os.path.basename(path), path)
         level = self.get_level(path, args)  # type: Optional[str]
-        print("level: {}".format(level))
+        logging.info("level: %s", level)
         if level is None:
-            print("Level is not valid.")
+            logging.error("Level is not valid.")
             return None, False
 
         if not self.config or not self.config.has_level(level):
-            print("Can't find specified level {} in config!".format(level))
+            logging.error("Can't find specified level %s in config!", level)
             return None, False
 
         orig_path = os.getcwd()
         if args.output_directory:
             if not os.path.isdir(args.output_directory):
-                print("Output directory not found at {}!".format(args.output_directory))
+                logging.error(
+                    "Output directory not found at %s!", args.output_directory
+                )
                 return None, False
 
             output_dir = os.path.join(args.output_directory, package.name + "-" + level)
@@ -246,39 +279,33 @@ def run(  # pylint: disable=too-many-locals, too-many-return-statements, too-man
                 try:
                     os.mkdir(output_dir)
                 except OSError as ex:
-                    print(
-                        "Unable to create output directory at {}: {}".format(
-                            output_dir, ex
-                        )
+                    logging.error(
+                        "Unable to create output directory at %s: %s", output_dir, ex
                     )
                     return None, False
-            print("Writing output to: {}".format(output_dir))
+            logging.info("Writing output to: %s", output_dir)
 
             os.chdir(output_dir)
 
-        print("------")
-        print(
-            "Scanning package {} ({}) at level {}".format(
-                package.name, package.path, level
-            )
+        logging.info("------")
+        logging.info(
+            "Scanning package %s (%s) at level %s", package.name, package.path, level
         )
 
         issues = {}  # type: Dict[str, List[Issue]]
 
         ignore_packages = self.get_ignore_packages()
         if package.name in ignore_packages:
-            print(
-                "Package {} is configured to be ignored by Statick.".format(
-                    package.name
-                )
+            logging.info(
+                "Package %s is configured to be ignored by Statick.", package.name
             )
             return issues, True
 
         plugin_context = PluginContext(args, self.resources, self.config)
 
-        print("---Discovery---")
+        logging.info("---Discovery---")
         if not DiscoveryPlugin.file_command_exists():
-            print(
+            logging.info(
                 "file command isn't available, discovery plugins will be less effective"
             )
 
@@ -288,7 +315,7 @@ def run(  # pylint: disable=too-many-locals, too-many-return-statements, too-man
         plugins_ran = []  # type: List[Any]
         for plugin_name in discovery_plugins:
             if plugin_name not in self.discovery_plugins:
-                print("Can't find specified discovery plugin {}!".format(plugin_name))
+                logging.error("Can't find specified discovery plugin %s!", plugin_name)
                 return None, False
 
             plugin = self.discovery_plugins[plugin_name]
@@ -298,24 +325,22 @@ def run(  # pylint: disable=too-many-locals, too-many-return-statements, too-man
                 if dependency_plugin.get_name() in plugins_ran:
                     continue
                 dependency_plugin.set_plugin_context(plugin_context)
-                print(
-                    "Running {} discovery plugin...".format(
-                        dependency_plugin.get_name()
-                    )
+                logging.info(
+                    "Running %s discovery plugin...", dependency_plugin.get_name()
                 )
                 dependency_plugin.scan(package, level, self.exceptions)
-                print("{} discovery plugin done.".format(dependency_plugin.get_name()))
+                logging.info("%s discovery plugin done.", dependency_plugin.get_name())
                 plugins_ran.append(dependency_plugin.get_name())
 
             if plugin.get_name() not in plugins_ran:
                 plugin.set_plugin_context(plugin_context)
-                print("Running {} discovery plugin...".format(plugin.get_name()))
+                logging.info("Running %s discovery plugin...", plugin.get_name())
                 plugin.scan(package, level, self.exceptions)
-                print("{} discovery plugin done.".format(plugin.get_name()))
+                logging.info("%s discovery plugin done.", plugin.get_name())
                 plugins_ran.append(plugin.get_name())
-        print("---Discovery---")
+        logging.info("---Discovery---")
 
-        print("---Tools---")
+        logging.info("---Tools---")
         enabled_plugins = self.config.get_enabled_tool_plugins(level)
         plugins_to_run = copy.copy(enabled_plugins)
         plugins_ran = []
@@ -324,7 +349,7 @@ def run(  # pylint: disable=too-many-locals, too-many-return-statements, too-man
             plugin_name = plugins_to_run[0]
 
             if plugin_name not in self.tool_plugins:
-                print("Can't find specified tool plugin {}!".format(plugin_name))
+                logging.error("Can't find specified tool plugin %s!", plugin_name)
                 return None, False
 
             if args.force_tool_list is not None:
@@ -333,7 +358,7 @@ def run(  # pylint: disable=too-many-locals, too-many-return-statements, too-man
                     plugin_name not in force_tool_list
                     and plugin_name not in plugin_dependencies
                 ):
-                    print("Skipping plugin not in force list {}!".format(plugin_name))
+                    logging.info("Skipping plugin not in force list %s!", plugin_name)
                     plugins_to_run.remove(plugin_name)
                     continue
 
@@ -345,9 +370,10 @@ def run(  # pylint: disable=too-many-locals, too-many-return-statements, too-man
             for dependency_name in dependencies:
                 if dependency_name not in plugins_ran:
                     if dependency_name not in enabled_plugins:
-                        print(
-                            "Plugin {} depends on plugin {} which isn't "
-                            "enabled!".format(plugin_name, dependency_name)
+                        logging.error(
+                            "Plugin %s depends on plugin %s which isn't enabled!",
+                            plugin_name,
+                            dependency_name,
                         )
                         return None, False
                     plugin_dependencies.append(dependency_name)
@@ -359,44 +385,45 @@ def run(  # pylint: disable=too-many-locals, too-many-return-statements, too-man
             if not dependencies_met:
                 continue
 
-            print("Running {} tool plugin...".format(plugin.get_name()))
+            logging.info("Running %s tool plugin...", plugin.get_name())
             tool_issues = plugin.scan(package, level)
             if tool_issues is not None:
                 issues[plugin_name] = tool_issues
-                print("{} tool plugin done.".format(plugin.get_name()))
+                logging.info("%s tool plugin done.", plugin.get_name())
             else:
-                print("{} tool plugin failed".format(plugin.get_name()))
+                logging.error("%s tool plugin failed", plugin.get_name())
                 success = False
 
             plugins_to_run.remove(plugin_name)
             plugins_ran.append(plugin_name)
-        print("---Tools---")
+        logging.info("---Tools---")
 
         if self.exceptions is not None:
             issues = self.exceptions.filter_issues(package, issues)
 
         os.chdir(orig_path)
 
-        print("---Reporting---")
+        logging.info("---Reporting---")
         reporting_plugins = self.config.get_enabled_reporting_plugins(level)
         if not reporting_plugins:
             reporting_plugins = self.reporting_plugins.keys()  # type: ignore
         for plugin_name in reporting_plugins:
             if plugin_name not in self.reporting_plugins.keys():
-                print("Can't find specified reporting plugin {}!".format(plugin_name))
+                logging.error("Can't find specified reporting plugin %s!", plugin_name)
                 return None, False
 
             plugin = self.reporting_plugins[plugin_name]
             plugin.set_plugin_context(plugin_context)
-            print("Running {} reporting plugin...".format(plugin.get_name()))
+            logging.info("Running %s reporting plugin...", plugin.get_name())
             plugin.report(package, issues, level)
-            print("{} reporting plugin done.".format(plugin.get_name()))
-        print("---Reporting---")
-        print("Done!")
+            logging.info("%s reporting plugin done.", plugin.get_name())
+        logging.info("---Reporting---")
+        logging.info("Done!")
 
         return issues, success
 
-    # , args: argparse.Namespace
+    # pylint: enable=too-many-locals, too-many-return-statements, too-many-branches
+    # pylint: enable=too-many-statements
 
     def run_workspace(
         self, parsed_args: argparse.Namespace
@@ -405,7 +432,8 @@ def run_workspace(
     ]:  # pylint: disable=too-many-locals, too-many-branches, too-many-statements
         """Run statick on a workspace.
 
-        --max-procs can be set to the desired number of CPUs to use for processing a workspace.
+        --max-procs can be set to the desired number of CPUs to use for processing a
+        workspace.
         This defaults to half the available CPUs.
         Setting this to -1 will cause statick.run_workspace to use all available CPUs.
         """
@@ -418,7 +446,7 @@ def run_workspace(
         if parsed_args.output_directory:
             out_dir = parsed_args.output_directory
             if not os.path.isdir(out_dir):
-                print("Output directory not found at " + out_dir + "!")
+                logging.error("Output directory not found at %s!", out_dir)
                 return None, False
 
         ignore_packages = self.get_ignore_packages()
@@ -450,7 +478,7 @@ def run_workspace(
                         if package.strip() and package[0] != "#"
                     ]
             except OSError:
-                print("Packages file not found")
+                logging.error("Packages file not found")
                 return None, False
             packages = [
                 package for package in packages if package.name in packages_file_list
@@ -458,10 +486,8 @@ def run_workspace(
 
         if parsed_args.list_packages:
             for package in packages:
-                print(
-                    "{:40}: {}".format(
-                        package.name, self.get_level(package.path, parsed_args)
-                    )
+                logging.info(
+                    "%s: %s", package.name, self.get_level(package.path, parsed_args)
                 )
             return None, True
 
@@ -470,7 +496,7 @@ def run_workspace(
         num_packages = len(packages)
         mp_args = []
         if multiprocessing.get_start_method() == "fork":
-            print("-- Scanning {} packages --".format(num_packages), flush=True)
+            logging.info("-- Scanning %d packages --", num_packages)
             for package in packages:
                 count += 1
                 mp_args.append((parsed_args, count, package, num_packages))
@@ -478,11 +504,11 @@ def run_workspace(
             with multiprocessing.Pool(parsed_args.max_procs) as pool:
                 total_issues = pool.starmap(self.scan_package, mp_args)
         else:
-            print(
-                "Statick's plugin manager does not currently support multiprocessing without"
-                " UNIX's fork function. Falling back to a single process."
+            logging.warning(
+                "Statick's plugin manager does not currently support multiprocessing"
+                " without UNIX's fork function. Falling back to a single process."
             )
-            print("-- Scanning {} packages --".format(num_packages), flush=True)
+            logging.info("-- Scanning %d packages --", num_packages)
             for package in packages:
                 count += 1
                 pkg_issues = self.scan_package(
@@ -490,8 +516,8 @@ def run_workspace(
                 )
                 total_issues.append(pkg_issues)
 
-        print("-- All packages run --")
-        print("-- overall report --")
+        logging.info("-- All packages run --")
+        logging.info("-- overall report --")
 
         success = True
         issues = {}  # type: Dict[str, List[Issue]]
@@ -519,7 +545,7 @@ def run_workspace(
         level = self.get_level(dummy_all_package.path, parsed_args)
         if level is not None and self.config is not None:
             if not self.config or not self.config.has_level(level):
-                print("Can't find specified level {} in config!".format(level))
+                logging.error("Can't find specified level %s in config!", level)
                 enabled_reporting_plugins = list(available_reporting_plugins)
             else:
                 enabled_reporting_plugins = self.config.get_enabled_reporting_plugins(
@@ -535,13 +561,13 @@ def run_workspace(
 
         for plugin_name in enabled_reporting_plugins:
             if plugin_name not in available_reporting_plugins:
-                print("Can't find specified reporting plugin {}!".format(plugin_name))
+                logging.error("Can't find specified reporting plugin %s!", plugin_name)
                 continue
             plugin = self.reporting_plugins[plugin_name]
             plugin.set_plugin_context(plugin_context)
-            print("Running {} reporting plugin...".format(plugin.get_name()))
+            logging.info("Running %s reporting plugin...", plugin.get_name())
             plugin.report(dummy_all_package, issues, level)
-            print("{} reporting plugin done.".format(plugin.get_name()))
+            logging.info("%s reporting plugin done.", plugin.get_name())
 
         return issues, success
 
@@ -558,32 +584,39 @@ def scan_package(
         old_stderr = sys.stderr
         sys.stdout = sio
         sys.stderr = sio
-        print(
-            "-- Scanning package "
-            + package.name
-            + " ("
-            + str(count)
-            + " of "
-            + str(num_packages)
-            + ") --"
+        logging.info(
+            "-- Scanning package %s (%d of %d) --", package.name, count, num_packages
         )
         issues, dummy = self.run(package.path, parsed_args)
         if issues is not None:
-            print(
-                "-- Done scanning package "
-                + package.name
-                + " ("
-                + str(count)
-                + " of "
-                + str(num_packages)
-                + ") --"
+            logging.info(
+                "-- Done scanning package %s (%d of %d) --",
+                package.name,
+                count,
+                num_packages,
             )
             sys.stdout = old_stdout
             sys.stderr = old_stderr
-            print(sio.getvalue(), flush=True)
+            logging.info(sio.getvalue())
         else:
-            print("Failed to run statick on package " + package.name + "!")
+            logging.error("Failed to run statick on package %s!", package.name)
             sys.stdout = old_stdout
             sys.stderr = old_stderr
-            print(sio.getvalue(), flush=True)
+            logging.info(sio.getvalue())
         return issues
+
+    @staticmethod
+    def print_no_issues() -> None:
+        """Print that no information about issues was found."""
+        logging.error(
+            "Something went wrong, no information about issues."
+            " Statick exiting with errors."
+        )
+
+    @staticmethod
+    def print_exit_status(status: bool) -> None:
+        """Print Statick exit status."""
+        if status:
+            logging.info("Statick exiting with success.")
+        else:
+            logging.error("Statick exiting with errors.")
diff --git a/statick_tool/tool_plugin.py b/statick_tool/tool_plugin.py
index 39f184fe..284c831f 100644
--- a/statick_tool/tool_plugin.py
+++ b/statick_tool/tool_plugin.py
@@ -1,5 +1,6 @@
 """Tool plugin."""
 import argparse
+import logging
 import os
 import shlex
 from typing import Any, Dict, List, Optional, Union
@@ -44,7 +45,8 @@ def load_mapping(self) -> Dict[str, str]:
             file_name
         )  # type: Union[Any, str, None]
         if self.plugin_context.args.mapping_file_suffix is not None:
-            # If the user specified a suffix, try to get the suffixed version of the file
+            # If the user specified a suffix, try to get the suffixed version of the
+            # file.
             suffixed_file_name = "plugin_mapping/{}-{}.txt".format(
                 self.get_name(), self.plugin_context.args.mapping_file_suffix
             )
@@ -63,7 +65,9 @@ def load_mapping(self) -> Dict[str, str]:
             for line in mapping_file.readlines():
                 split_line = line.strip().split(":")
                 if len(split_line) != 2:
-                    print("Warning: invalid line {} in file {}".format(line, file_name))
+                    logging.warning(
+                        "Invalid line %s in mapping file %s", line, file_name
+                    )
                     continue
                 warning_mapping[split_line[0]] = split_line[1]
         return warning_mapping


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 005165dd..90e6f31a 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -143,4 +143,4 @@ jobs:
         if: matrix.os == 'ubuntu-18.04' || matrix.os == 'ubuntu-20.04'
         run: |
           mkdir statick-output
-          ./statick . --output-directory statick-output --check --profile self_check.yaml
+          ./statick . --output-directory statick-output --check --profile self_check.yaml --log INFO
diff --git a/tests/plugins/discovery/cmake_discovery_plugin/test_cmake_discovery_plugin.py b/tests/plugins/discovery/cmake_discovery_plugin/test_cmake_discovery_plugin.py
index 9e3073a3..d036fffd 100644
--- a/tests/plugins/discovery/cmake_discovery_plugin/test_cmake_discovery_plugin.py
+++ b/tests/plugins/discovery/cmake_discovery_plugin/test_cmake_discovery_plugin.py
@@ -18,12 +18,6 @@
 def setup_cmake_discovery_plugin(add_plugin_context=True, cmake_flags=""):
     """Create an instance of the CMake discovery plugin."""
     arg_parser = argparse.ArgumentParser()
-    arg_parser.add_argument(
-        "--show-tool-output",
-        dest="show_tool_output",
-        action="store_false",
-        help="Show tool output",
-    )
 
     resources = Resources(
         [os.path.join(os.path.dirname(statick_tool.__file__), "plugins")]
diff --git a/tests/plugins/reporting/write_jenkins_warnings_ng_reporting_plugin/test_write_jenkins_warnings_ng_reporting_plugin.py b/tests/plugins/reporting/write_jenkins_warnings_ng_reporting_plugin/test_write_jenkins_warnings_ng_reporting_plugin.py
index 4b68407c..126f592a 100644
--- a/tests/plugins/reporting/write_jenkins_warnings_ng_reporting_plugin/test_write_jenkins_warnings_ng_reporting_plugin.py
+++ b/tests/plugins/reporting/write_jenkins_warnings_ng_reporting_plugin/test_write_jenkins_warnings_ng_reporting_plugin.py
@@ -33,12 +33,6 @@ def setup_write_jenkins_warnings_ng_reporting_plugin(
     """Create an instance of the file writer plugin."""
     arg_parser = argparse.ArgumentParser()
     arg_parser.add_argument("output_directory")
-    arg_parser.add_argument(
-        "--show-tool-output",
-        dest="show_tool_output",
-        action="store_false",
-        help="Show tool output",
-    )
 
     resources = Resources(
         [os.path.join(os.path.dirname(statick_tool.__file__), "plugins")]
diff --git a/tests/plugins/tool/bandit_tool_plugin/test_bandit_tool_plugin.py b/tests/plugins/tool/bandit_tool_plugin/test_bandit_tool_plugin.py
index d254cc68..ac3f5107 100644
--- a/tests/plugins/tool/bandit_tool_plugin/test_bandit_tool_plugin.py
+++ b/tests/plugins/tool/bandit_tool_plugin/test_bandit_tool_plugin.py
@@ -18,12 +18,6 @@
 def setup_bandit_tool_plugin(binary=None):
     """Create an instance of the bandit plugin."""
     arg_parser = argparse.ArgumentParser()
-    arg_parser.add_argument(
-        "--show-tool-output",
-        dest="show_tool_output",
-        action="store_false",
-        help="Show tool output",
-    )
     arg_parser.add_argument("--bandit-bin", dest="bandit_bin")
     arg_parser.add_argument(
         "--mapping-file-suffix", dest="mapping_file_suffix", type=str
diff --git a/tests/plugins/tool/black_tool_plugin/test_black_tool_plugin.py b/tests/plugins/tool/black_tool_plugin/test_black_tool_plugin.py
index d85c2377..436500aa 100644
--- a/tests/plugins/tool/black_tool_plugin/test_black_tool_plugin.py
+++ b/tests/plugins/tool/black_tool_plugin/test_black_tool_plugin.py
@@ -19,12 +19,6 @@
 def setup_black_tool_plugin():
     """Create and return an instance of the PyCodeStyle plugin."""
     arg_parser = argparse.ArgumentParser()
-    arg_parser.add_argument(
-        "--show-tool-output",
-        dest="show_tool_output",
-        action="store_false",
-        help="Show tool output",
-    )
 
     resources = Resources(
         [os.path.join(os.path.dirname(statick_tool.__file__), "plugins")]
diff --git a/tests/plugins/tool/catkin-lint_tool_plugin/test_catkin-lint_tool_plugin.py b/tests/plugins/tool/catkin-lint_tool_plugin/test_catkin-lint_tool_plugin.py
index 78d82182..bbd1d26c 100644
--- a/tests/plugins/tool/catkin-lint_tool_plugin/test_catkin-lint_tool_plugin.py
+++ b/tests/plugins/tool/catkin-lint_tool_plugin/test_catkin-lint_tool_plugin.py
@@ -19,12 +19,6 @@
 def setup_catkin_lint_tool_plugin():
     """Construct and return an instance of the CatkinLint plugin."""
     arg_parser = argparse.ArgumentParser()
-    arg_parser.add_argument(
-        "--show-tool-output",
-        dest="show_tool_output",
-        action="store_false",
-        help="Show tool output",
-    )
 
     resources = Resources(
         [os.path.join(os.path.dirname(statick_tool.__file__), "plugins")]
diff --git a/tests/plugins/tool/cccc_tool_plugin/test_cccc_tool_plugin.py b/tests/plugins/tool/cccc_tool_plugin/test_cccc_tool_plugin.py
index 99316dce..1b138387 100644
--- a/tests/plugins/tool/cccc_tool_plugin/test_cccc_tool_plugin.py
+++ b/tests/plugins/tool/cccc_tool_plugin/test_cccc_tool_plugin.py
@@ -24,12 +24,6 @@
 def setup_cccc_tool_plugin(use_plugin_context=True, binary=None, cccc_config=None):
     """Create an instance of the CCCC plugin."""
     arg_parser = argparse.ArgumentParser()
-    arg_parser.add_argument(
-        "--show-tool-output",
-        dest="show_tool_output",
-        action="store_false",
-        help="Show tool output",
-    )
     arg_parser.add_argument("--cccc-bin", dest="cccc_bin")
     arg_parser.add_argument("--cccc-config", dest="cccc_config")
 
diff --git a/tests/plugins/tool/clang-format_tool_plugin/test_clang-format_tool_plugin.py b/tests/plugins/tool/clang-format_tool_plugin/test_clang-format_tool_plugin.py
index 3840382a..09c0d501 100644
--- a/tests/plugins/tool/clang-format_tool_plugin/test_clang-format_tool_plugin.py
+++ b/tests/plugins/tool/clang-format_tool_plugin/test_clang-format_tool_plugin.py
@@ -22,12 +22,6 @@ def setup_clang_format_tool_plugin(
 ):
     """Initialize and return an instance of the clang-format plugin."""
     arg_parser = argparse.ArgumentParser()
-    arg_parser.add_argument(
-        "--show-tool-output",
-        dest="show_tool_output",
-        action="store_false",
-        help="Show tool output",
-    )
     arg_parser.add_argument("--clang-format-bin", dest="clang_format_bin")
     if do_raise:
         arg_parser.add_argument(
diff --git a/tests/plugins/tool/clang-tidy_tool_plugin/test_clang-tidy_tool_plugin.py b/tests/plugins/tool/clang-tidy_tool_plugin/test_clang-tidy_tool_plugin.py
index 339d8865..ff0e6cde 100644
--- a/tests/plugins/tool/clang-tidy_tool_plugin/test_clang-tidy_tool_plugin.py
+++ b/tests/plugins/tool/clang-tidy_tool_plugin/test_clang-tidy_tool_plugin.py
@@ -26,12 +26,6 @@
 def setup_clang_tidy_tool_plugin(use_plugin_context=True, binary=None):
     """Initialize and return an instance of the clang-tidy plugin."""
     arg_parser = argparse.ArgumentParser()
-    arg_parser.add_argument(
-        "--show-tool-output",
-        dest="show_tool_output",
-        action="store_false",
-        help="Show tool output",
-    )
     arg_parser.add_argument("--clang-tidy-bin", dest="clang_tidy_bin")
     arg_parser.add_argument(
         "--mapping-file-suffix", dest="mapping_file_suffix", type=str
diff --git a/tests/plugins/tool/cmakelint_tool_plugin/test_cmakelint_tool_plugin.py b/tests/plugins/tool/cmakelint_tool_plugin/test_cmakelint_tool_plugin.py
index 9cd1223b..f19f55a3 100644
--- a/tests/plugins/tool/cmakelint_tool_plugin/test_cmakelint_tool_plugin.py
+++ b/tests/plugins/tool/cmakelint_tool_plugin/test_cmakelint_tool_plugin.py
@@ -18,12 +18,6 @@
 def setup_cmakelint_tool_plugin():
     """Create an instance of the cmakelint plugin."""
     arg_parser = argparse.ArgumentParser()
-    arg_parser.add_argument(
-        "--show-tool-output",
-        dest="show_tool_output",
-        action="store_false",
-        help="Show tool output",
-    )
 
     resources = Resources(
         [os.path.join(os.path.dirname(statick_tool.__file__), "plugins")]
diff --git a/tests/plugins/tool/cppcheck_tool_plugin/test_cppcheck_tool_plugin.py b/tests/plugins/tool/cppcheck_tool_plugin/test_cppcheck_tool_plugin.py
index 4ac26979..8279a38e 100644
--- a/tests/plugins/tool/cppcheck_tool_plugin/test_cppcheck_tool_plugin.py
+++ b/tests/plugins/tool/cppcheck_tool_plugin/test_cppcheck_tool_plugin.py
@@ -19,12 +19,6 @@
 def setup_cppcheck_tool_plugin(use_plugin_context=True, binary=None):
     """Initialize and return an instance of the cppcheck plugin."""
     arg_parser = argparse.ArgumentParser()
-    arg_parser.add_argument(
-        "--show-tool-output",
-        dest="show_tool_output",
-        action="store_false",
-        help="Show tool output",
-    )
     arg_parser.add_argument("--cppcheck-bin", dest="cppcheck_bin")
     arg_parser.add_argument(
         "--mapping-file-suffix", dest="mapping_file_suffix", type=str
diff --git a/tests/plugins/tool/cpplint_tool_plugin/test_cpplint_tool_plugin.py b/tests/plugins/tool/cpplint_tool_plugin/test_cpplint_tool_plugin.py
index 373a4444..94486508 100644
--- a/tests/plugins/tool/cpplint_tool_plugin/test_cpplint_tool_plugin.py
+++ b/tests/plugins/tool/cpplint_tool_plugin/test_cpplint_tool_plugin.py
@@ -27,12 +27,6 @@
 def setup_cpplint_tool_plugin():
     """Initialize and return an instance of the cpplint plugin."""
     arg_parser = argparse.ArgumentParser()
-    arg_parser.add_argument(
-        "--show-tool-output",
-        dest="show_tool_output",
-        action="store_false",
-        help="Show tool output",
-    )
 
     resources = Resources(
         [os.path.join(os.path.dirname(statick_tool.__file__), "plugins")]
diff --git a/tests/plugins/tool/docformatter_tool_plugin/test_docformatter_tool_plugin.py b/tests/plugins/tool/docformatter_tool_plugin/test_docformatter_tool_plugin.py
index 6bc1d35a..738a8afb 100644
--- a/tests/plugins/tool/docformatter_tool_plugin/test_docformatter_tool_plugin.py
+++ b/tests/plugins/tool/docformatter_tool_plugin/test_docformatter_tool_plugin.py
@@ -19,12 +19,6 @@
 def setup_docformatter_tool_plugin():
     """Create and return an instance of the Docformatter plugin."""
     arg_parser = argparse.ArgumentParser()
-    arg_parser.add_argument(
-        "--show-tool-output",
-        dest="show_tool_output",
-        action="store_false",
-        help="Show tool output",
-    )
 
     resources = Resources(
         [os.path.join(os.path.dirname(statick_tool.__file__), "plugins")]
diff --git a/tests/plugins/tool/flawfinder_tool_plugin/test_flawfinder_tool_plugin.py b/tests/plugins/tool/flawfinder_tool_plugin/test_flawfinder_tool_plugin.py
index 8cbfb815..3ee71f62 100644
--- a/tests/plugins/tool/flawfinder_tool_plugin/test_flawfinder_tool_plugin.py
+++ b/tests/plugins/tool/flawfinder_tool_plugin/test_flawfinder_tool_plugin.py
@@ -20,12 +20,6 @@
 def setup_flawfinder_tool_plugin():
     """Initialize and return an instance of the flawfinder plugin."""
     arg_parser = argparse.ArgumentParser()
-    arg_parser.add_argument(
-        "--show-tool-output",
-        dest="show_tool_output",
-        action="store_false",
-        help="Show tool output",
-    )
     arg_parser.add_argument("--flawfinder-bin", dest="flawfinder_bin")
     arg_parser.add_argument(
         "--mapping-file-suffix", dest="mapping_file_suffix", type=str
diff --git a/tests/plugins/tool/lizard_tool_plugin/test_lizard_tool_plugin.py b/tests/plugins/tool/lizard_tool_plugin/test_lizard_tool_plugin.py
index 6c2f89cb..f0f32ac9 100644
--- a/tests/plugins/tool/lizard_tool_plugin/test_lizard_tool_plugin.py
+++ b/tests/plugins/tool/lizard_tool_plugin/test_lizard_tool_plugin.py
@@ -17,12 +17,6 @@
 def setup_lizard_tool_plugin(custom_rsc_path=None):
     """Initialize and return an instance of the lizard plugin."""
     arg_parser = argparse.ArgumentParser()
-    arg_parser.add_argument(
-        "--show-tool-output",
-        dest="show_tool_output",
-        action="store_false",
-        help="Show tool output",
-    )
 
     if custom_rsc_path is not None:
         resources = Resources([custom_rsc_path])
diff --git a/tests/plugins/tool/make_tool_plugin/test_make_tool_plugin.py b/tests/plugins/tool/make_tool_plugin/test_make_tool_plugin.py
index f5cfab58..98f2855c 100644
--- a/tests/plugins/tool/make_tool_plugin/test_make_tool_plugin.py
+++ b/tests/plugins/tool/make_tool_plugin/test_make_tool_plugin.py
@@ -19,12 +19,6 @@
 def setup_make_tool_plugin():
     """Construct and return an instance of the Make plugin."""
     arg_parser = argparse.ArgumentParser()
-    arg_parser.add_argument(
-        "--show-tool-output",
-        dest="show_tool_output",
-        action="store_false",
-        help="Show tool output",
-    )
     arg_parser.add_argument(
         "--mapping-file-suffix", dest="mapping_file_suffix", type=str
     )
diff --git a/tests/plugins/tool/mypy_tool_plugin/test_mypy_tool_plugin.py b/tests/plugins/tool/mypy_tool_plugin/test_mypy_tool_plugin.py
index fb5622bc..d311472d 100644
--- a/tests/plugins/tool/mypy_tool_plugin/test_mypy_tool_plugin.py
+++ b/tests/plugins/tool/mypy_tool_plugin/test_mypy_tool_plugin.py
@@ -19,12 +19,6 @@
 def setup_mypy_tool_plugin():
     """Create and return an instance of the Mypy plugin."""
     arg_parser = argparse.ArgumentParser()
-    arg_parser.add_argument(
-        "--show-tool-output",
-        dest="show_tool_output",
-        action="store_false",
-        help="Show tool output",
-    )
 
     resources = Resources(
         [os.path.join(os.path.dirname(statick_tool.__file__), "plugins")]
diff --git a/tests/plugins/tool/perlcritic_tool_plugin/test_perlcritic_tool_plugin.py b/tests/plugins/tool/perlcritic_tool_plugin/test_perlcritic_tool_plugin.py
index 9d44e6ad..2b6a8748 100644
--- a/tests/plugins/tool/perlcritic_tool_plugin/test_perlcritic_tool_plugin.py
+++ b/tests/plugins/tool/perlcritic_tool_plugin/test_perlcritic_tool_plugin.py
@@ -19,12 +19,6 @@
 def setup_perlcritic_tool_plugin(binary=None):
     """Initialize and return a perlcritic plugin."""
     arg_parser = argparse.ArgumentParser()
-    arg_parser.add_argument(
-        "--show-tool-output",
-        dest="show_tool_output",
-        action="store_false",
-        help="Show tool output",
-    )
     arg_parser.add_argument("--perlcritic-bin", dest="perlcritic_bin")
     arg_parser.add_argument(
         "--mapping-file-suffix", dest="mapping_file_suffix", type=str
diff --git a/tests/plugins/tool/pycodestyle_tool_plugin/test_pycodestyle_tool_plugin.py b/tests/plugins/tool/pycodestyle_tool_plugin/test_pycodestyle_tool_plugin.py
index 2b9acea4..37b7ed13 100644
--- a/tests/plugins/tool/pycodestyle_tool_plugin/test_pycodestyle_tool_plugin.py
+++ b/tests/plugins/tool/pycodestyle_tool_plugin/test_pycodestyle_tool_plugin.py
@@ -18,12 +18,6 @@
 def setup_pycodestyle_tool_plugin():
     """Create and return an instance of the PyCodeStyle plugin."""
     arg_parser = argparse.ArgumentParser()
-    arg_parser.add_argument(
-        "--show-tool-output",
-        dest="show_tool_output",
-        action="store_false",
-        help="Show tool output",
-    )
 
     resources = Resources(
         [os.path.join(os.path.dirname(statick_tool.__file__), "plugins")]
diff --git a/tests/plugins/tool/pydocstyle_tool_plugin/test_pydocstyle_tool_plugin.py b/tests/plugins/tool/pydocstyle_tool_plugin/test_pydocstyle_tool_plugin.py
index 6c8cc4eb..c597f5ea 100644
--- a/tests/plugins/tool/pydocstyle_tool_plugin/test_pydocstyle_tool_plugin.py
+++ b/tests/plugins/tool/pydocstyle_tool_plugin/test_pydocstyle_tool_plugin.py
@@ -18,12 +18,6 @@
 def setup_pydocstyle_tool_plugin():
     """Initialize and return a PyCodeStyle plugin."""
     arg_parser = argparse.ArgumentParser()
-    arg_parser.add_argument(
-        "--show-tool-output",
-        dest="show_tool_output",
-        action="store_false",
-        help="Show tool output",
-    )
 
     resources = Resources(
         [os.path.join(os.path.dirname(statick_tool.__file__), "plugins")]
diff --git a/tests/plugins/tool/pyflakes_tool_plugin/test_pyflakes_tool_plugin.py b/tests/plugins/tool/pyflakes_tool_plugin/test_pyflakes_tool_plugin.py
index 6a25ffcd..366b8369 100644
--- a/tests/plugins/tool/pyflakes_tool_plugin/test_pyflakes_tool_plugin.py
+++ b/tests/plugins/tool/pyflakes_tool_plugin/test_pyflakes_tool_plugin.py
@@ -18,12 +18,6 @@
 def setup_pyflakes_tool_plugin():
     """Initialize and return a Pyflakes plugin."""
     arg_parser = argparse.ArgumentParser()
-    arg_parser.add_argument(
-        "--show-tool-output",
-        dest="show_tool_output",
-        action="store_false",
-        help="Show tool output",
-    )
 
     resources = Resources(
         [os.path.join(os.path.dirname(statick_tool.__file__), "plugins")]
diff --git a/tests/plugins/tool/pylint_tool_plugin/test_pylint_tool_plugin.py b/tests/plugins/tool/pylint_tool_plugin/test_pylint_tool_plugin.py
index 75ef10e1..fe0eeebe 100644
--- a/tests/plugins/tool/pylint_tool_plugin/test_pylint_tool_plugin.py
+++ b/tests/plugins/tool/pylint_tool_plugin/test_pylint_tool_plugin.py
@@ -18,12 +18,6 @@
 def setup_pylint_tool_plugin():
     """Construct and return an instance of the Pylint plugin."""
     arg_parser = argparse.ArgumentParser()
-    arg_parser.add_argument(
-        "--show-tool-output",
-        dest="show_tool_output",
-        action="store_false",
-        help="Show tool output",
-    )
 
     resources = Resources(
         [os.path.join(os.path.dirname(statick_tool.__file__), "plugins")]
diff --git a/tests/plugins/tool/shellcheck_tool_plugin/test_shellcheck_tool_plugin.py b/tests/plugins/tool/shellcheck_tool_plugin/test_shellcheck_tool_plugin.py
index a54b35ee..02c288c5 100644
--- a/tests/plugins/tool/shellcheck_tool_plugin/test_shellcheck_tool_plugin.py
+++ b/tests/plugins/tool/shellcheck_tool_plugin/test_shellcheck_tool_plugin.py
@@ -20,12 +20,6 @@
 def setup_shellcheck_tool_plugin(binary=None):
     """Construct and return an instance of the Shellcheck plugin."""
     arg_parser = argparse.ArgumentParser()
-    arg_parser.add_argument(
-        "--show-tool-output",
-        dest="show_tool_output",
-        action="store_false",
-        help="Show tool output",
-    )
     arg_parser.add_argument("--shellcheck-bin", dest="shellcheck_bin")
 
     resources = Resources(
diff --git a/tests/plugins/tool/spotbugs_tool_plugin/test_spotbugs_tool_plugin.py b/tests/plugins/tool/spotbugs_tool_plugin/test_spotbugs_tool_plugin.py
index 98864e1d..288b8d70 100644
--- a/tests/plugins/tool/spotbugs_tool_plugin/test_spotbugs_tool_plugin.py
+++ b/tests/plugins/tool/spotbugs_tool_plugin/test_spotbugs_tool_plugin.py
@@ -20,12 +20,6 @@
 def setup_spotbugs_tool_plugin(use_plugin_context=True, custom_rsc_path=None):
     """Initialize and return a spotbugs plugin."""
     arg_parser = argparse.ArgumentParser()
-    arg_parser.add_argument(
-        "--show-tool-output",
-        dest="show_tool_output",
-        action="store_false",
-        help="Show tool output",
-    )
     arg_parser.add_argument(
         "--mapping-file-suffix", dest="mapping_file_suffix", type=str
     )
diff --git a/tests/plugins/tool/uncrustify_tool_plugin/test_uncrustify_tool_plugin.py b/tests/plugins/tool/uncrustify_tool_plugin/test_uncrustify_tool_plugin.py
index f8668e40..a4d8753c 100644
--- a/tests/plugins/tool/uncrustify_tool_plugin/test_uncrustify_tool_plugin.py
+++ b/tests/plugins/tool/uncrustify_tool_plugin/test_uncrustify_tool_plugin.py
@@ -27,12 +27,6 @@ def setup_uncrustify_tool_plugin(extra_path=None, use_plugin_context=True, binar
     """Initialize and return an instance of the uncrustify plugin."""
     arg_parser = argparse.ArgumentParser()
     arg_parser.add_argument("--uncrustify-bin", dest="uncrustify_bin")
-    arg_parser.add_argument(
-        "--show-tool-output",
-        dest="show_tool_output",
-        action="store_false",
-        help="Show tool output",
-    )
 
     paths = []
     if extra_path:
diff --git a/tests/plugins/tool/xmllint_tool_plugin/test_xmllint_tool_plugin.py b/tests/plugins/tool/xmllint_tool_plugin/test_xmllint_tool_plugin.py
index b18b2cb8..f9edd4fb 100644
--- a/tests/plugins/tool/xmllint_tool_plugin/test_xmllint_tool_plugin.py
+++ b/tests/plugins/tool/xmllint_tool_plugin/test_xmllint_tool_plugin.py
@@ -19,12 +19,6 @@
 def setup_xmllint_tool_plugin():
     """Create an instance of the xmllint plugin."""
     arg_parser = argparse.ArgumentParser()
-    arg_parser.add_argument(
-        "--show-tool-output",
-        dest="show_tool_output",
-        action="store_false",
-        help="Show tool output",
-    )
 
     resources = Resources(
         [os.path.join(os.path.dirname(statick_tool.__file__), "plugins")]
diff --git a/tests/plugins/tool/yamllint_tool_plugin/test_yamllint_tool_plugin.py b/tests/plugins/tool/yamllint_tool_plugin/test_yamllint_tool_plugin.py
index 92e00f84..4012e568 100644
--- a/tests/plugins/tool/yamllint_tool_plugin/test_yamllint_tool_plugin.py
+++ b/tests/plugins/tool/yamllint_tool_plugin/test_yamllint_tool_plugin.py
@@ -19,12 +19,6 @@
 def setup_yamllint_tool_plugin():
     """Construct and return an instance of the YAMLLint plugin."""
     arg_parser = argparse.ArgumentParser()
-    arg_parser.add_argument(
-        "--show-tool-output",
-        dest="show_tool_output",
-        action="store_false",
-        help="Show tool output",
-    )
 
     resources = Resources(
         [os.path.join(os.path.dirname(statick_tool.__file__), "plugins")]
diff --git a/tests/resources/test_resources.py b/tests/resources/test_resources.py
index 644ed659..89f263b5 100644
--- a/tests/resources/test_resources.py
+++ b/tests/resources/test_resources.py
@@ -1,5 +1,6 @@
 """Tests for the resources module."""
 
+import logging
 import os
 import tempfile
 
@@ -13,6 +14,8 @@
         TemporaryDirectory,
     )
 
+LOGGER = logging.getLogger(__name__)
+
 
 def test_resources_init():
     """
@@ -39,32 +42,34 @@ def test_resources_init_empty():
     assert resources.paths[0] == os.path.dirname(statick_tool.resources.__file__)
 
 
-def test_resources_init_invalid(capsys):
+def test_resources_init_invalid(caplog):
     """
     Test initialization of the resources module with an invalid dir.
 
     Expected results: resources.paths should have the directory which resources.py lives in
     and should print an error for the invalid directory
     """
+    LOGGER.info("Testing now.")
     resources = Resources(["invalid_directory"])
-    output = capsys.readouterr().out
     assert resources.paths
     assert resources.paths[0] == os.path.dirname(statick_tool.resources.__file__)
-    assert output.splitlines()[0] == "Could not find path invalid_directory"
+    assert "Could not find path invalid_directory" in caplog.text.splitlines()[0]
 
 
-def test_resources_init_file(capsys):
+def test_resources_init_file(caplog):
     """
     Test initialization of the resources module with an file as an arg.
 
     Expected results: resources.paths should have the directory which resources.py lives in
     and should print an error for the file
     """
-
+    LOGGER.info("Testing now.")
     with tempfile.NamedTemporaryFile() as tmpfile:
         resources = Resources([tmpfile.name])
-        output = capsys.readouterr().out
-        assert output.splitlines()[0] == "{} is not a directory".format(tmpfile.name)
+        assert (
+            "{} is not a directory".format(tmpfile.name) in caplog.text.splitlines()[0]
+        )
+
     assert resources.paths
     assert resources.paths[0] == os.path.dirname(statick_tool.resources.__file__)
 
diff --git a/tests/statick/test_statick.py b/tests/statick/test_statick.py
index f2e26d4e..8865b7bb 100644
--- a/tests/statick/test_statick.py
+++ b/tests/statick/test_statick.py
@@ -1,6 +1,7 @@
 """Unit tests of statick.py."""
 
 import contextlib
+import logging
 import os
 import shutil
 import subprocess
@@ -14,6 +15,8 @@
 from statick_tool.plugins.tool.clang_tidy_tool_plugin import ClangTidyToolPlugin
 from statick_tool.statick import Statick
 
+LOGGER = logging.getLogger(__name__)
+
 
 # From https://stackoverflow.com/questions/2059482/python-temporarily-modify-the-current-processs-environment
 @contextlib.contextmanager
@@ -1203,3 +1206,106 @@ def test_scan_package_with_issues(init_statick_ws):
         shutil.rmtree(os.path.join(os.path.dirname(__file__), "test_package-sei_cert"))
     except OSError as ex:
         print("Error: {}".format(ex))
+
+
+def test_print_no_issues(caplog):
+    """Test that expected error message is logged when no issues are found."""
+    args = Args("Statick tool")
+    args.parser.add_argument("--path", help="Path of package to scan")
+
+    statick = Statick(args.get_user_paths())
+    statick.print_no_issues()
+    output = caplog.text.splitlines()[0]
+    assert (
+        "Something went wrong, no information about issues. Statick exiting with errors."
+        in output
+    )
+
+
+def test_print_exit_status_errors(caplog):
+    """Test that expected error status message is logged."""
+    args = Args("Statick tool")
+    args.parser.add_argument("--path", help="Path of package to scan")
+    statick = Statick(args.get_user_paths())
+
+    statick.print_exit_status(False)
+    output = caplog.text.splitlines()[0]
+    assert "Statick exiting with errors." in output
+
+
+def test_print_exit_status_success(caplog):
+    """Test that expected success status message is logged."""
+    args = Args("Statick tool")
+    args.parser.add_argument("--path", help="Path of package to scan")
+    statick = Statick(args.get_user_paths())
+    logging.root.setLevel(logging.INFO)
+
+    statick.print_exit_status(True)
+    # This should contain logging output but is empty for INFO level.
+    output = caplog.text.splitlines()[0]
+    assert "Statick exiting with success." in output
+
+
+def test_print_logging_level():
+    """Test that log level is set as expected."""
+    args = Args("Statick tool")
+    args.parser.add_argument("--path", help="Path of package to scan")
+
+    statick = Statick(args.get_user_paths())
+    statick.gather_args(args.parser)
+    sys.argv = [
+        "--path",
+        os.path.dirname(__file__),
+        "--log",
+        "ERROR",
+    ]
+    args.output_directory = os.path.dirname(__file__)
+    parsed_args = args.get_args(sys.argv)
+    statick.set_logging_level(parsed_args)
+
+    logger = logging.getLogger()
+    assert logger.getEffectiveLevel() == logging.ERROR
+
+
+def test_print_logging_level_invalid():
+    """Test that log level is set to a valid level given garbage input."""
+    args = Args("Statick tool")
+    args.parser.add_argument("--path", help="Path of package to scan")
+
+    statick = Statick(args.get_user_paths())
+    statick.gather_args(args.parser)
+    sys.argv = [
+        "--path",
+        os.path.dirname(__file__),
+        "--log",
+        "NOT_A_VALID_LEVEL",
+    ]
+    args.output_directory = os.path.dirname(__file__)
+    parsed_args = args.get_args(sys.argv)
+    statick.set_logging_level(parsed_args)
+
+    logger = logging.getLogger()
+    assert logger.getEffectiveLevel() == logging.WARNING
+
+
+def test_show_tool_output_deprecated(caplog):
+    """Test that the deprecation warning is shown for --show-tool-output flag."""
+    args = Args("Statick tool")
+    args.parser.add_argument("--path", help="Path of package to scan")
+
+    statick = Statick(args.get_user_paths())
+    statick.gather_args(args.parser)
+    sys.argv = [
+        "--path",
+        os.path.dirname(__file__),
+        "--log",
+        "INFO",
+        "--show-tool-output",
+    ]
+    args.output_directory = os.path.dirname(__file__)
+    parsed_args = args.get_args(sys.argv)
+    statick.set_logging_level(parsed_args)
+
+    print("caplog: {}".format(caplog.text))
+    output = caplog.text.splitlines()[1]
+    assert "The --show-tool-output argument has been deprecated since v0.5.0." in output