diff --git a/example.conf b/example.conf
index 2b8a5e2f2..18bdf6f4e 100644
--- a/example.conf
+++ b/example.conf
@@ -24,10 +24,6 @@
 # Its value may be silently ignored in the future.
 #authenticate = <None>
 
-# Debug mode enabled/disabled. (boolean value)
-# Deprecated group/name - [discoverd]/debug
-#debug = false
-
 # Timeout after which introspection is considered failed, set to 0 to
 # disable. (integer value)
 # Deprecated group/name - [discoverd]/timeout
@@ -63,6 +59,96 @@
 # affected by introspection_delay setting. (string value)
 #introspection_delay_drivers = ^.*_ssh$
 
+#
+# From oslo.log
+#
+
+# Print debugging output (set logging level to DEBUG instead of
+# default INFO level). (boolean value)
+#debug = false
+
+# If set to false, will disable INFO logging level, making WARNING the
+# default. (boolean value)
+# This option is deprecated for removal.
+# Its value may be silently ignored in the future.
+#verbose = true
+
+# The name of a logging configuration file. This file is appended to
+# any existing logging configuration files. For details about logging
+# configuration files, see the Python logging module documentation.
+# (string value)
+# Deprecated group/name - [DEFAULT]/log_config
+#log_config_append = <None>
+
+# DEPRECATED. A logging.Formatter log message format string which may
+# use any of the available logging.LogRecord attributes. This option
+# is deprecated.  Please use logging_context_format_string and
+# logging_default_format_string instead. (string value)
+#log_format = <None>
+
+# Format string for %%(asctime)s in log records. Default: %(default)s
+# . (string value)
+#log_date_format = %Y-%m-%d %H:%M:%S
+
+# (Optional) Name of log file to output to. If no default is set,
+# logging will go to stdout. (string value)
+# Deprecated group/name - [DEFAULT]/logfile
+#log_file = <None>
+
+# (Optional) The base directory used for relative --log-file paths.
+# (string value)
+# Deprecated group/name - [DEFAULT]/logdir
+#log_dir = <None>
+
+# Use syslog for logging. Existing syslog format is DEPRECATED and
+# will be changed later to honor RFC5424. (boolean value)
+#use_syslog = false
+
+# (Optional) Enables or disables syslog rfc5424 format for logging. If
+# enabled, prefixes the MSG part of the syslog message with APP-NAME
+# (RFC5424). The format without the APP-NAME is deprecated in K, and
+# will be removed in M, along with this option. (boolean value)
+# This option is deprecated for removal.
+# Its value may be silently ignored in the future.
+#use_syslog_rfc_format = true
+
+# Syslog facility to receive log lines. (string value)
+#syslog_log_facility = LOG_USER
+
+# Log output to standard error. (boolean value)
+#use_stderr = true
+
+# Format string to use for log messages with context. (string value)
+#logging_context_format_string = %(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [%(request_id)s %(user_identity)s] %(instance)s%(message)s
+
+# Format string to use for log messages without context. (string
+# value)
+#logging_default_format_string = %(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [-] %(instance)s%(message)s
+
+# Data to append to log format when level is DEBUG. (string value)
+#logging_debug_format_suffix = %(funcName)s %(pathname)s:%(lineno)d
+
+# Prefix each line of exception output with this format. (string
+# value)
+#logging_exception_prefix = %(asctime)s.%(msecs)03d %(process)d ERROR %(name)s %(instance)s
+
+# List of logger=LEVEL pairs. (list value)
+#default_log_levels = amqp=WARN,amqplib=WARN,boto=WARN,qpid=WARN,sqlalchemy=WARN,suds=INFO,oslo.messaging=INFO,iso8601=WARN,requests.packages.urllib3.connectionpool=WARN,urllib3.connectionpool=WARN,websocket=WARN,requests.packages.urllib3.util.retry=WARN,urllib3.util.retry=WARN,keystonemiddleware=WARN,routes.middleware=WARN,stevedore=WARN,taskflow=WARN
+
+# Enables or disables publication of error events. (boolean value)
+#publish_errors = false
+
+# The format for an instance that is passed with the log message.
+# (string value)
+#instance_format = "[instance: %(uuid)s] "
+
+# The format for an instance UUID that is passed with the log message.
+# (string value)
+#instance_uuid_format = "[instance: %(uuid)s] "
+
+# Enables or disables fatal status of deprecations. (boolean value)
+#fatal_deprecations = false
+
 
 [database]
 
diff --git a/ironic_inspector/common/swift.py b/ironic_inspector/common/swift.py
index 69dff11ca..7259a1dcf 100644
--- a/ironic_inspector/common/swift.py
+++ b/ironic_inspector/common/swift.py
@@ -13,9 +13,8 @@
 
 # Mostly copied from ironic/common/swift.py
 
-import logging
-
 from oslo_config import cfg
+from oslo_log import log
 from swiftclient import client as swift_client
 from swiftclient import exceptions as swift_exceptions
 
@@ -25,7 +24,7 @@ from ironic_inspector import utils
 CONF = cfg.CONF
 
 
-LOG = logging.getLogger('ironic_inspector.common.swift')
+LOG = log.getLogger('ironic_inspector.common.swift')
 
 
 SWIFT_OPTS = [
diff --git a/ironic_inspector/conf.py b/ironic_inspector/conf.py
index 746580381..8da964388 100644
--- a/ironic_inspector/conf.py
+++ b/ironic_inspector/conf.py
@@ -193,10 +193,6 @@ SERVICE_OPTS = [
                 help='DEPRECATED: use auth_strategy.',
                 deprecated_group='discoverd',
                 deprecated_for_removal=True),
-    cfg.BoolOpt('debug',
-                default=False,
-                help='Debug mode enabled/disabled.',
-                deprecated_group='discoverd'),
     cfg.IntOpt('timeout',
                default=3600,
                help='Timeout after which introspection is considered failed, '
diff --git a/ironic_inspector/firewall.py b/ironic_inspector/firewall.py
index 5aae28fa9..efd7f2215 100644
--- a/ironic_inspector/firewall.py
+++ b/ironic_inspector/firewall.py
@@ -11,11 +11,11 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import logging
 import subprocess
 
 from eventlet import semaphore
 from oslo_config import cfg
+from oslo_log import log
 
 from ironic_inspector.common.i18n import _LE
 from ironic_inspector import node_cache
@@ -23,7 +23,7 @@ from ironic_inspector import utils
 
 
 CONF = cfg.CONF
-LOG = logging.getLogger("ironic_inspector.firewall")
+LOG = log.getLogger("ironic_inspector.firewall")
 NEW_CHAIN = None
 CHAIN = None
 INTERFACE = None
diff --git a/ironic_inspector/introspect.py b/ironic_inspector/introspect.py
index d0529503c..54f287d3f 100644
--- a/ironic_inspector/introspect.py
+++ b/ironic_inspector/introspect.py
@@ -13,7 +13,6 @@
 
 """Handling introspection request."""
 
-import logging
 import re
 import string
 import time
@@ -21,6 +20,7 @@ import time
 from eventlet import semaphore
 from ironicclient import exceptions
 from oslo_config import cfg
+from oslo_log import log
 
 from ironic_inspector.common.i18n import _, _LI, _LW
 from ironic_inspector import firewall
@@ -30,7 +30,7 @@ from ironic_inspector import utils
 CONF = cfg.CONF
 
 
-LOG = logging.getLogger("ironic_inspector.introspect")
+LOG = log.getLogger("ironic_inspector.introspect")
 PASSWORD_ACCEPTED_CHARS = set(string.ascii_letters + string.digits)
 PASSWORD_MAX_LENGTH = 20  # IPMI v2.0
 
diff --git a/ironic_inspector/main.py b/ironic_inspector/main.py
index e0458dcfd..059a7726d 100644
--- a/ironic_inspector/main.py
+++ b/ironic_inspector/main.py
@@ -16,17 +16,16 @@ eventlet.monkey_patch()
 
 import functools
 import json
-import logging
 import ssl
 import sys
 
 import flask
 from oslo_config import cfg
+from oslo_log import log
 from oslo_utils import uuidutils
 
 from ironic_inspector import db
 from ironic_inspector.common.i18n import _, _LC, _LE, _LI, _LW
-# Import configuration options
 from ironic_inspector import conf  # noqa
 from ironic_inspector import firewall
 from ironic_inspector import introspect
@@ -39,7 +38,7 @@ CONF = cfg.CONF
 
 
 app = flask.Flask(__name__)
-LOG = logging.getLogger('ironic_inspector.main')
+LOG = log.getLogger('ironic_inspector.main')
 
 MINIMUM_API_VERSION = (1, 0)
 CURRENT_API_VERSION = (1, 0)
@@ -241,16 +240,17 @@ def create_ssl_context():
 
 
 def main(args=sys.argv[1:], in_functional_test=False):  # pragma: no cover
+    log.register_options(CONF)
     CONF(args, project='ironic-inspector')
     debug = CONF.debug
 
-    logging.basicConfig(level=logging.DEBUG if debug else logging.INFO)
-    for third_party in ('urllib3.connectionpool',
-                        'keystonemiddleware.auth_token',
-                        'requests.packages.urllib3.connectionpool'):
-        logging.getLogger(third_party).setLevel(logging.WARNING)
-    logging.getLogger('ironicclient.common.http').setLevel(
-        logging.INFO if debug else logging.ERROR)
+    log.set_defaults(default_log_levels=[
+        'urllib3.connectionpool=WARN',
+        'keystonemiddleware.auth_token=WARN',
+        'requests.packages.urllib3.connectionpool=WARN',
+        ('ironicclient.common.http=INFO' if debug else
+         'ironicclient.common.http=ERROR')])
+    log.setup(CONF, 'ironic_inspector')
 
     app_kwargs = {'debug': debug and not in_functional_test,
                   'host': CONF.listen_address,
diff --git a/ironic_inspector/node_cache.py b/ironic_inspector/node_cache.py
index 362bc7f25..5aa003049 100644
--- a/ironic_inspector/node_cache.py
+++ b/ironic_inspector/node_cache.py
@@ -14,12 +14,12 @@
 """Cache for nodes currently under introspection."""
 
 import json
-import logging
 import time
 
 from ironicclient import exceptions
 from oslo_config import cfg
 from oslo_db import exception as db_exc
+from oslo_log import log
 from sqlalchemy import text
 
 from ironic_inspector import db
@@ -29,7 +29,7 @@ from ironic_inspector import utils
 CONF = cfg.CONF
 
 
-LOG = logging.getLogger("ironic_inspector.node_cache")
+LOG = log.getLogger("ironic_inspector.node_cache")
 
 
 MACS_ATTRIBUTE = 'mac'
diff --git a/ironic_inspector/plugins/example.py b/ironic_inspector/plugins/example.py
index 5a90f03c2..bd655460d 100644
--- a/ironic_inspector/plugins/example.py
+++ b/ironic_inspector/plugins/example.py
@@ -13,12 +13,12 @@
 
 """Example plugin."""
 
-import logging
+from oslo_log import log
 
 from ironic_inspector.plugins import base
 
 
-LOG = logging.getLogger('ironic_inspector.plugins.example')
+LOG = log.getLogger('ironic_inspector.plugins.example')
 
 
 class ExampleProcessingHook(base.ProcessingHook):  # pragma: no cover
diff --git a/ironic_inspector/plugins/extra_hardware.py b/ironic_inspector/plugins/extra_hardware.py
index 96f377c3a..818d5ba28 100644
--- a/ironic_inspector/plugins/extra_hardware.py
+++ b/ironic_inspector/plugins/extra_hardware.py
@@ -19,9 +19,9 @@ is stored in the 'inspector' container.
 """
 
 import json
-import logging
 
 from oslo_config import cfg
+from oslo_log import log
 
 from ironic_inspector.common.i18n import _LW
 from ironic_inspector.common import swift
@@ -30,7 +30,7 @@ from ironic_inspector.plugins import base
 CONF = cfg.CONF
 
 
-LOG = logging.getLogger('ironic_inspector.plugins.extra_hardware')
+LOG = log.getLogger('ironic_inspector.plugins.extra_hardware')
 
 
 class ExtraHardwareHook(base.ProcessingHook):
diff --git a/ironic_inspector/plugins/root_device_hint.py b/ironic_inspector/plugins/root_device_hint.py
index 2a3c7be19..25e0db0b8 100644
--- a/ironic_inspector/plugins/root_device_hint.py
+++ b/ironic_inspector/plugins/root_device_hint.py
@@ -13,13 +13,13 @@
 
 """Gather root device hint from recognized block devices."""
 
-import logging
+from oslo_log import log
 
 from ironic_inspector.common.i18n import _LI, _LW
 from ironic_inspector.plugins import base
 
 
-LOG = logging.getLogger('ironic_inspector.plugins.root_device_hint')
+LOG = log.getLogger('ironic_inspector.plugins.root_device_hint')
 
 
 class RootDeviceHintHook(base.ProcessingHook):
diff --git a/ironic_inspector/plugins/standard.py b/ironic_inspector/plugins/standard.py
index 573ff5ca4..4b32fdd17 100644
--- a/ironic_inspector/plugins/standard.py
+++ b/ironic_inspector/plugins/standard.py
@@ -15,11 +15,11 @@
 
 import base64
 import datetime
-import logging
 import os
 import sys
 
 from oslo_config import cfg
+from oslo_log import log
 
 from ironic_inspector.common.i18n import _, _LC, _LI, _LW
 from ironic_inspector import conf
@@ -29,7 +29,7 @@ from ironic_inspector import utils
 CONF = cfg.CONF
 
 
-LOG = logging.getLogger('ironic_inspector.plugins.standard')
+LOG = log.getLogger('ironic_inspector.plugins.standard')
 
 
 class SchedulerHook(base.ProcessingHook):
diff --git a/ironic_inspector/process.py b/ironic_inspector/process.py
index ef1300a11..155747867 100644
--- a/ironic_inspector/process.py
+++ b/ironic_inspector/process.py
@@ -13,10 +13,9 @@
 
 """Handling introspection data from the ramdisk."""
 
-import logging
-
 import eventlet
 from ironicclient import exceptions
+from oslo_log import log
 
 from ironic_inspector.common.i18n import _, _LE, _LI
 from ironic_inspector import firewall
@@ -25,7 +24,7 @@ from ironic_inspector.plugins import base as plugins_base
 from ironic_inspector import utils
 
 
-LOG = logging.getLogger("ironic_inspector.process")
+LOG = log.getLogger("ironic_inspector.process")
 
 _CREDENTIALS_WAIT_RETRIES = 10
 _CREDENTIALS_WAIT_PERIOD = 3
diff --git a/ironic_inspector/test/base.py b/ironic_inspector/test/base.py
index 5dc139eb0..02d192d56 100644
--- a/ironic_inspector/test/base.py
+++ b/ironic_inspector/test/base.py
@@ -16,6 +16,7 @@ import unittest
 import mock
 from oslo_config import cfg
 from oslo_db import options as db_opts
+from oslo_log import log
 
 from ironic_inspector.common import i18n
 # Import configuration options
@@ -36,6 +37,12 @@ def init_test_conf():
         CONF.reset()
     for group in ('firewall', 'processing', 'ironic'):
         CONF.register_group(cfg.OptGroup(group))
+    try:
+        # Functional tests
+        log.register_options(CONF)
+    except Exception:
+        # Unit tests
+        pass
     db_opts.set_defaults(CONF)
     CONF.set_default('slave_connection', False, group='database')
     CONF.set_default('max_retries', 10, group='database')
diff --git a/ironic_inspector/utils.py b/ironic_inspector/utils.py
index 97d9a1843..7b5dc401a 100644
--- a/ironic_inspector/utils.py
+++ b/ironic_inspector/utils.py
@@ -11,7 +11,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import logging
 import re
 import socket
 
@@ -20,6 +19,7 @@ from ironicclient import client
 import keystoneclient.v2_0.client as keystone_client
 from keystonemiddleware import auth_token
 from oslo_config import cfg
+from oslo_log import log
 import six
 
 from ironic_inspector.common.i18n import _, _LE, _LI
@@ -30,7 +30,7 @@ CONF = cfg.CONF
 VALID_STATES = {'enroll', 'manageable', 'inspecting', 'inspectfail'}
 
 
-LOG = logging.getLogger('ironic_inspector.utils')
+LOG = log.getLogger('ironic_inspector.utils')
 
 GREEN_POOL = None
 
diff --git a/requirements.txt b/requirements.txt
index 215c1c86e..f6a48f01c 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -11,6 +11,7 @@ python-keystoneclient>=1.6.0
 oslo.config>=1.11.0 # Apache-2.0
 oslo.db>=1.12.0 # Apache-2.0
 oslo.i18n>=1.5.0 # Apache-2.0
+oslo.log>=1.8.0  # Apache-2.0
 oslo.utils>=1.9.0 # Apache-2.0
 six>=1.9.0
 stevedore>=1.5.0 # Apache-2.0
diff --git a/tox.ini b/tox.ini
index b544b4cb9..540caf82d 100644
--- a/tox.ini
+++ b/tox.ini
@@ -35,7 +35,8 @@ commands =
     --namespace ironic_inspector \
     --namespace keystonemiddleware.auth_token \
     --namespace ironic_inspector.common.swift \
-    --namespace oslo.db
+    --namespace oslo.db \
+    --namespace oslo.log
 
 [flake8]
 max-complexity=15