Use oslo.log

All OpenStack projects should use the oslo.log module for logging. This
patch converts the Blazar code base from its oslo-incubator logging
module to oslo.log.

Change-Id: I2434bb8e864a77a3c3b1ec278767e5526e0a8952
This commit is contained in:
Masahito Muroi 2016-12-14 17:28:02 +09:00
parent 0ff134d458
commit 3c7dbd3237
47 changed files with 167 additions and 885 deletions

View File

@ -17,16 +17,16 @@ import eventlet
import flask
from keystonemiddleware import auth_token
from oslo_config import cfg
from oslo_log import log as logging
from werkzeug import exceptions as werkzeug_exceptions
from climate.api.v1.oshosts import v1_0 as host_api_v1_0
from climate.api.v1 import utils as api_utils
from climate.api.v1 import v1_0 as api_v1_0
from climate.openstack.common import log
from climate.openstack.common.middleware import debug
LOG = log.getLogger(__name__)
LOG = logging.getLogger(__name__)
CONF = cfg.CONF

View File

@ -13,10 +13,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from oslo_log import log as logging
from climate import context
from climate import exceptions
from climate.manager import rpcapi as manager_rpcapi
from climate.openstack.common import log as logging
from climate import policy
from climate.utils import trusts

View File

@ -16,6 +16,7 @@
import traceback
import flask
from oslo_log import log as logging
import oslo_messaging as messaging
from oslo_serialization import jsonutils
from werkzeug import datastructures
@ -25,7 +26,6 @@ from climate.db import exceptions as db_exceptions
from climate import exceptions as ex
from climate.manager import exceptions as manager_exceptions
from climate.openstack.common.gettextutils import _
from climate.openstack.common import log as logging
LOG = logging.getLogger(__name__)

View File

@ -13,10 +13,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from oslo_log import log as logging
from climate.api.v1 import service
from climate.api.v1 import utils as api_utils
from climate.api.v1 import validation
from climate.openstack.common import log as logging
from climate import utils
LOG = logging.getLogger(__name__)

View File

@ -17,13 +17,13 @@
"""
from oslo_config import cfg
from oslo_log import log as logging
import pecan
from pecan import rest
from stevedore import enabled
from climate import exceptions
from climate.openstack.common.gettextutils import _
from climate.openstack.common import log as logging
LOG = logging.getLogger(__name__)

View File

@ -16,10 +16,10 @@
import abc
from oslo_config import cfg
from oslo_log import log as logging
from pecan import rest
import six
from climate.openstack.common import log as logging
LOG = logging.getLogger(__name__)
CONF = cfg.CONF

View File

@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from oslo_log import log as logging
import pecan
from wsme import types as wtypes
import wsmeext.pecan as wsme_pecan
@ -22,7 +23,6 @@ from climate.api.v2.controllers import extensions
from climate.api.v2.controllers import types
from climate import exceptions
from climate.openstack.common.gettextutils import _ # noqa
from climate.openstack.common import log as logging
from climate import policy
from climate.utils import trusts

View File

@ -14,13 +14,13 @@
# limitations under the License.
from oslo_config import cfg
from oslo_log import log as logging
from pecan import hooks
from climate.api import context
from climate.db import api as dbapi
from climate.manager.oshosts import rpcapi as hosts_rpcapi
from climate.manager import rpcapi
from climate.openstack.common import log as logging
LOG = logging.getLogger(__name__)

View File

@ -15,13 +15,13 @@
import json
from oslo_log import log as logging
import webob
from climate.db import exceptions as db_exceptions
from climate import exceptions
from climate.manager import exceptions as manager_exceptions
from climate.openstack.common.gettextutils import _ # noqa
from climate.openstack.common import log as logging
LOG = logging.getLogger(__name__)

View File

@ -20,12 +20,12 @@ import sys
import eventlet
from eventlet import wsgi
from oslo_config import cfg
from oslo_log import log as logging
gettext.install('climate', unicode=1)
from climate.api.v1 import app as v1_app
from climate.api.v2 import app as v2_app
from climate.openstack.common import log as logging
from climate.utils import service as service_utils
@ -93,7 +93,6 @@ def main():
"""Entry point to start Climate API wsgi server."""
cfg.CONF(sys.argv[1:], project='climate', prog='climate-api')
service_utils.prepare_service(sys.argv)
logging.setup("climate")
if not CONF.enable_v1_api:
app = v2_app.make_app()
else:

View File

@ -16,6 +16,7 @@
import socket
from oslo_config import cfg
from oslo_log import log as logging
cli_opts = [
cfg.StrOpt('host', default=socket.gethostname(),
@ -59,3 +60,4 @@ os_opts = [
CONF = cfg.CONF
CONF.register_cli_opts(cli_opts)
CONF.register_opts(os_opts)
logging.register_options(cfg.CONF)

View File

@ -31,9 +31,10 @@ interface.
"""
from oslo_log import log as logging
from climate.openstack.common.db import api as db_api
from climate.openstack.common.db import options as db_options
from climate.openstack.common import log as logging
_BACKEND_MAPPING = {

View File

@ -13,9 +13,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from oslo_log import log as logging
from climate import exceptions
from climate.openstack.common.gettextutils import _ # noqa
from climate.openstack.common import log as logging
LOG = logging.getLogger(__name__)

View File

@ -17,6 +17,7 @@
import sys
from oslo_log import log as logging
import sqlalchemy as sa
from sqlalchemy.sql.expression import asc
from sqlalchemy.sql.expression import desc
@ -28,7 +29,6 @@ from climate.openstack.common.db import exception as common_db_exc
from climate.openstack.common.db import options as db_options
from climate.openstack.common.db.sqlalchemy import session as db_session
from climate.openstack.common.gettextutils import _
from climate.openstack.common import log as logging
LOG = logging.getLogger(__name__)

View File

@ -15,14 +15,13 @@
import uuid
# FIXME: https://bugs.launchpad.net/climate/+bug/1300132
# from oslo_log import log as logging
import sqlalchemy as sa
from sqlalchemy.dialects.mysql import MEDIUMTEXT
from sqlalchemy.orm import relationship
from climate.db.sqlalchemy import model_base as mb
# FIXME: https://bugs.launchpad.net/climate/+bug/1300132
# from climate.openstack.common import log as logging
# FIXME: https://bugs.launchpad.net/climate/+bug/1300132
# LOG = logging.getLogger(__name__)

View File

@ -32,9 +32,10 @@ interface.
"""
from oslo_log import log as logging
from climate.openstack.common.db import api as db_api
from climate.openstack.common.db import options as db_options
from climate.openstack.common import log as logging
_BACKEND_MAPPING = {
'sqlalchemy': 'climate.db.sqlalchemy.utils',

View File

@ -14,8 +14,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from oslo_log import log as logging
from climate.openstack.common.gettextutils import _
from climate.openstack.common import log as logging
LOG = logging.getLogger(__name__)

View File

@ -17,6 +17,7 @@ import datetime
import eventlet
from oslo_config import cfg
from oslo_log import log as logging
import six
from stevedore import enabled
@ -27,7 +28,6 @@ from climate import manager
from climate.manager import exceptions
from climate.notification import api as notification_api
from climate.openstack.common.gettextutils import _
from climate.openstack.common import log as logging
from climate.utils import service as service_utils
from climate.utils import trusts

View File

@ -14,9 +14,9 @@
# under the License.
from oslo_config import cfg
from oslo_log import log as logging
import oslo_messaging as messaging
from climate.openstack.common import log
notification_opts = [
cfg.StrOpt('publisher_id',
@ -24,7 +24,7 @@ notification_opts = [
help='Publisher ID for notifications')
]
LOG = log.getLogger(__name__)
LOG = logging.getLogger(__name__)
SERVICE = 'lease'
CONF = cfg.CONF
CONF.register_opts(notification_opts, 'notifications')

View File

@ -21,10 +21,11 @@ API methods.
"""
import functools
import logging
import threading
import time
from oslo_log import log as logging
from climate.openstack.common.db import exception
from climate.openstack.common.gettextutils import _LE
from climate.openstack.common import importutils

View File

@ -279,10 +279,10 @@ Efficient use of soft deletes:
"""
import functools
import logging
import re
import time
from oslo_log import log as logging
import six
from sqlalchemy import exc as sqla_exc
from sqlalchemy.interfaces import PoolListener
@ -584,16 +584,6 @@ def create_engine(sql_connection, sqlite_fk=False, mysql_sql_mode=None,
'convert_unicode': True,
}
logger = logging.getLogger('sqlalchemy.engine')
# Map SQL debug level to Python log level
if connection_debug >= 100:
logger.setLevel(logging.DEBUG)
elif connection_debug >= 50:
logger.setLevel(logging.INFO)
else:
logger.setLevel(logging.WARNING)
if "sqlite" in connection_dict.drivername:
if sqlite_fk:
engine_args["listeners"] = [SqliteForeignKeysListener()]

View File

@ -15,11 +15,11 @@
# under the License.
import functools
import logging
import os
import subprocess
import lockfile
from oslo_log import log as logging
from six import moves
from six.moves.urllib import parse
import sqlalchemy

View File

@ -16,10 +16,10 @@
# License for the specific language governing permissions and limitations
# under the License.
import logging
import re
from migrate.changeset import UniqueConstraint
from oslo_log import log as logging
import sqlalchemy
from sqlalchemy import Boolean
from sqlalchemy import CheckConstraint

View File

@ -28,9 +28,9 @@ import eventlet
import eventlet.backdoor
import greenlet
from oslo_config import cfg
from oslo_log import log as logging
from climate.openstack.common.gettextutils import _LI
from climate.openstack.common import log as logging
help_for_backdoor_port = (
"Acceptable values are 0, <port>, and <start>:<end>, where 0 results "

View File

@ -17,11 +17,11 @@
Exception related utilities.
"""
import logging
import sys
import time
import traceback
from oslo_log import log as logging
import six
from climate.openstack.common.gettextutils import _LE

View File

@ -18,8 +18,9 @@ import errno
import os
import tempfile
from oslo_log import log as logging
from climate.openstack.common import excutils
from climate.openstack.common import log as logging
LOG = logging.getLogger(__name__)

View File

@ -1,712 +0,0 @@
# Copyright 2011 OpenStack Foundation.
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""OpenStack logging handler.
This module adds to logging functionality by adding the option to specify
a context object when calling the various log methods. If the context object
is not specified, default formatting is used. Additionally, an instance uuid
may be passed as part of the log message, which is intended to make it easier
for admins to find messages related to a specific instance.
It also allows setting of formatting information through conf.
"""
import inspect
import itertools
import logging
import logging.config
import logging.handlers
import os
import re
import sys
import traceback
from oslo_config import cfg
from oslo_serialization import jsonutils
import six
from six import moves
from climate.openstack.common.gettextutils import _
from climate.openstack.common import importutils
from climate.openstack.common import local
_DEFAULT_LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
_SANITIZE_KEYS = ['adminPass', 'admin_pass', 'password', 'admin_password']
# NOTE(ldbragst): Let's build a list of regex objects using the list of
# _SANITIZE_KEYS we already have. This way, we only have to add the new key
# to the list of _SANITIZE_KEYS and we can generate regular expressions
# for XML and JSON automatically.
_SANITIZE_PATTERNS = []
_FORMAT_PATTERNS = [r'(%(key)s\s*[=]\s*[\"\']).*?([\"\'])',
r'(<%(key)s>).*?(</%(key)s>)',
r'([\"\']%(key)s[\"\']\s*:\s*[\"\']).*?([\"\'])',
r'([\'"].*?%(key)s[\'"]\s*:\s*u?[\'"]).*?([\'"])']
for key in _SANITIZE_KEYS:
for pattern in _FORMAT_PATTERNS:
reg_ex = re.compile(pattern % {'key': key}, re.DOTALL)
_SANITIZE_PATTERNS.append(reg_ex)
common_cli_opts = [
cfg.BoolOpt('debug',
short='d',
default=False,
help='Print debugging output (set logging level to '
'DEBUG instead of default WARNING level).'),
cfg.BoolOpt('verbose',
short='v',
default=False,
help='Print more verbose output (set logging level to '
'INFO instead of default WARNING level).'),
]
logging_cli_opts = [
cfg.StrOpt('log-config-append',
metavar='PATH',
deprecated_name='log-config',
help='The name of logging configuration file. It does not '
'disable existing loggers, but just appends specified '
'logging configuration to any other existing logging '
'options. Please see the Python logging module '
'documentation for details on logging configuration '
'files.'),
cfg.StrOpt('log-format',
default=None,
metavar='FORMAT',
help='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.'),
cfg.StrOpt('log-date-format',
default=_DEFAULT_LOG_DATE_FORMAT,
metavar='DATE_FORMAT',
help='Format string for %%(asctime)s in log records. '
'Default: %(default)s'),
cfg.StrOpt('log-file',
metavar='PATH',
deprecated_name='logfile',
help='(Optional) Name of log file to output to. '
'If no default is set, logging will go to stdout.'),
cfg.StrOpt('log-dir',
deprecated_name='logdir',
help='(Optional) The base directory used for relative '
'--log-file paths'),
cfg.BoolOpt('use-syslog',
default=False,
help='Use syslog for logging. '
'Existing syslog format is DEPRECATED during I, '
'and then will be changed in J to honor RFC5424'),
cfg.BoolOpt('use-syslog-rfc-format',
# TODO(bogdando) remove or use True after existing
# syslog format deprecation in J
default=False,
help='(Optional) Use syslog rfc5424 format for logging. '
'If enabled, will add APP-NAME (RFC5424) before the '
'MSG part of the syslog message. The old format '
'without APP-NAME is deprecated in I, '
'and will be removed in J.'),
cfg.StrOpt('syslog-log-facility',
default='LOG_USER',
help='Syslog facility to receive log lines')
]
generic_log_opts = [
cfg.BoolOpt('use_stderr',
default=True,
help='Log output to standard error')
]
log_opts = [
cfg.StrOpt('logging_context_format_string',
default='%(asctime)s.%(msecs)03d %(process)d %(levelname)s '
'%(name)s [%(request_id)s %(user_identity)s] '
'%(instance)s%(message)s',
help='Format string to use for log messages with context'),
cfg.StrOpt('logging_default_format_string',
default='%(asctime)s.%(msecs)03d %(process)d %(levelname)s '
'%(name)s [-] %(instance)s%(message)s',
help='Format string to use for log messages without context'),
cfg.StrOpt('logging_debug_format_suffix',
default='%(funcName)s %(pathname)s:%(lineno)d',
help='Data to append to log format when level is DEBUG'),
cfg.StrOpt('logging_exception_prefix',
default='%(asctime)s.%(msecs)03d %(process)d TRACE %(name)s '
'%(instance)s',
help='Prefix each line of exception output with this format'),
cfg.ListOpt('default_log_levels',
default=[
'amqp=WARN',
'amqplib=WARN',
'boto=WARN',
'qpid=WARN',
'sqlalchemy=WARN',
'suds=INFO',
'iso8601=WARN',
'requests.packages.urllib3.connectionpool=WARN'
],
help='List of logger=LEVEL pairs'),
cfg.BoolOpt('publish_errors',
default=False,
help='Publish error events'),
cfg.BoolOpt('fatal_deprecations',
default=False,
help='Make deprecations fatal'),
# NOTE(mikal): there are two options here because sometimes we are handed
# a full instance (and could include more information), and other times we
# are just handed a UUID for the instance.
cfg.StrOpt('instance_format',
default='[instance: %(uuid)s] ',
help='If an instance is passed with the log message, format '
'it like this'),
cfg.StrOpt('instance_uuid_format',
default='[instance: %(uuid)s] ',
help='If an instance UUID is passed with the log message, '
'format it like this'),
]
CONF = cfg.CONF
CONF.register_cli_opts(common_cli_opts)
CONF.register_cli_opts(logging_cli_opts)
CONF.register_opts(generic_log_opts)
CONF.register_opts(log_opts)
# our new audit level
# NOTE(jkoelker) Since we synthesized an audit level, make the logging
# module aware of it so it acts like other levels.
logging.AUDIT = logging.INFO + 1
logging.addLevelName(logging.AUDIT, 'AUDIT')
try:
NullHandler = logging.NullHandler
except AttributeError: # NOTE(jkoelker) NullHandler added in Python 2.7
class NullHandler(logging.Handler):
def handle(self, record):
pass
def emit(self, record):
pass
def createLock(self):
self.lock = None
def _dictify_context(context):
if context is None:
return None
if not isinstance(context, dict) and getattr(context, 'to_dict', None):
context = context.to_dict()
return context
def _get_binary_name():
return os.path.basename(inspect.stack()[-1][1])
def _get_log_file_path(binary=None):
logfile = CONF.log_file
logdir = CONF.log_dir
if logfile and not logdir:
return logfile
if logfile and logdir:
return os.path.join(logdir, logfile)
if logdir:
binary = binary or _get_binary_name()
return '%s.log' % (os.path.join(logdir, binary),)
return None
def mask_password(message, secret="***"):
"""Replace password with 'secret' in message.
:param message: The string which includes security information.
:param secret: value with which to replace passwords.
:returns: The unicode value of message with the password fields masked.
For example:
>>> mask_password("'adminPass' : 'aaaaa'")
"'adminPass' : '***'"
>>> mask_password("'admin_pass' : 'aaaaa'")
"'admin_pass' : '***'"
>>> mask_password('"password" : "aaaaa"')
'"password" : "***"'
>>> mask_password("'original_password' : 'aaaaa'")
"'original_password' : '***'"
>>> mask_password("u'original_password' : u'aaaaa'")
"u'original_password' : u'***'"
"""
message = six.text_type(message)
# NOTE(ldbragst): Check to see if anything in message contains any key
# specified in _SANITIZE_KEYS, if not then just return the message since
# we don't have to mask any passwords.
if not any(key in message for key in _SANITIZE_KEYS):
return message
secret = r'\g<1>' + secret + r'\g<2>'
for pattern in _SANITIZE_PATTERNS:
message = re.sub(pattern, secret, message)
return message
class BaseLoggerAdapter(logging.LoggerAdapter):
def audit(self, msg, *args, **kwargs):
self.log(logging.AUDIT, msg, *args, **kwargs)
class LazyAdapter(BaseLoggerAdapter):
def __init__(self, name='unknown', version='unknown'):
self._logger = None
self.extra = {}
self.name = name
self.version = version
@property
def logger(self):
if not self._logger:
self._logger = getLogger(self.name, self.version)
return self._logger
class ContextAdapter(BaseLoggerAdapter):
warn = logging.LoggerAdapter.warning
def __init__(self, logger, project_name, version_string):
self.logger = logger
self.project = project_name
self.version = version_string
self._deprecated_messages_sent = dict()
@property
def handlers(self):
return self.logger.handlers
def deprecated(self, msg, *args, **kwargs):
"""Call this method when a deprecated feature is used.
If the system is configured for fatal deprecations then the message
is logged at the 'critical' level and :class:`DeprecatedConfig` will
be raised.
Otherwise, the message will be logged (once) at the 'warn' level.
:raises: :class:`DeprecatedConfig` if the system is configured for
fatal deprecations.
"""
stdmsg = _("Deprecated: %s") % msg
if CONF.fatal_deprecations:
self.critical(stdmsg, *args, **kwargs)
raise DeprecatedConfig(msg=stdmsg)
# Using a list because a tuple with dict can't be stored in a set.
sent_args = self._deprecated_messages_sent.setdefault(msg, list())
if args in sent_args:
# Already logged this message, so don't log it again.
return
sent_args.append(args)
self.warn(stdmsg, *args, **kwargs)
def process(self, msg, kwargs):
# NOTE(mrodden): catch any Message/other object and
# coerce to unicode before they can get
# to the python logging and possibly
# cause string encoding trouble
if not isinstance(msg, six.string_types):
msg = six.text_type(msg)
if 'extra' not in kwargs:
kwargs['extra'] = {}
extra = kwargs['extra']
context = kwargs.pop('context', None)
if not context:
context = getattr(local.store, 'context', None)
if context:
extra.update(_dictify_context(context))
instance = kwargs.pop('instance', None)
instance_uuid = (extra.get('instance_uuid') or
kwargs.pop('instance_uuid', None))
instance_extra = ''
if instance:
instance_extra = CONF.instance_format % instance
elif instance_uuid:
instance_extra = (CONF.instance_uuid_format
% {'uuid': instance_uuid})
extra['instance'] = instance_extra
extra.setdefault('user_identity', kwargs.pop('user_identity', None))
extra['project'] = self.project
extra['version'] = self.version
extra['extra'] = extra.copy()
return msg, kwargs
class JSONFormatter(logging.Formatter):
def __init__(self, fmt=None, datefmt=None):
# NOTE(jkoelker) we ignore the fmt argument, but its still there
# since logging.config.fileConfig passes it.
self.datefmt = datefmt
def formatException(self, ei, strip_newlines=True):
lines = traceback.format_exception(*ei)
if strip_newlines:
lines = [moves.filter(
lambda x: x,
line.rstrip().splitlines()) for line in lines]
lines = list(itertools.chain(*lines))
return lines
def format(self, record):
message = {'message': record.getMessage(),
'asctime': self.formatTime(record, self.datefmt),
'name': record.name,
'msg': record.msg,
'args': record.args,
'levelname': record.levelname,
'levelno': record.levelno,
'pathname': record.pathname,
'filename': record.filename,
'module': record.module,
'lineno': record.lineno,
'funcname': record.funcName,
'created': record.created,
'msecs': record.msecs,
'relative_created': record.relativeCreated,
'thread': record.thread,
'thread_name': record.threadName,
'process_name': record.processName,
'process': record.process,
'traceback': None}
if hasattr(record, 'extra'):
message['extra'] = record.extra
if record.exc_info:
message['traceback'] = self.formatException(record.exc_info)
return jsonutils.dumps(message)
def _create_logging_excepthook(product_name):
def logging_excepthook(exc_type, value, tb):
extra = {}
if CONF.verbose or CONF.debug:
extra['exc_info'] = (exc_type, value, tb)
getLogger(product_name).critical(
"".join(traceback.format_exception_only(exc_type, value)),
**extra)
return logging_excepthook
class LogConfigError(Exception):
message = _('Error loading logging config %(log_config)s: %(err_msg)s')
def __init__(self, log_config, err_msg):
self.log_config = log_config
self.err_msg = err_msg
def __str__(self):
return self.message % dict(log_config=self.log_config,
err_msg=self.err_msg)
def _load_log_config(log_config_append):
try:
logging.config.fileConfig(log_config_append,
disable_existing_loggers=False)
except moves.configparser.Error as exc:
raise LogConfigError(log_config_append, str(exc))
def setup(product_name, version='unknown'):
"""Setup logging."""
if CONF.log_config_append:
_load_log_config(CONF.log_config_append)
else:
_setup_logging_from_conf(product_name, version)
sys.excepthook = _create_logging_excepthook(product_name)
def set_defaults(logging_context_format_string):
cfg.set_defaults(log_opts,
logging_context_format_string=
logging_context_format_string)
def _find_facility_from_conf():
facility_names = logging.handlers.SysLogHandler.facility_names
facility = getattr(logging.handlers.SysLogHandler,
CONF.syslog_log_facility,
None)
if facility is None and CONF.syslog_log_facility in facility_names:
facility = facility_names.get(CONF.syslog_log_facility)
if facility is None:
valid_facilities = facility_names.keys()
consts = ['LOG_AUTH', 'LOG_AUTHPRIV', 'LOG_CRON', 'LOG_DAEMON',
'LOG_FTP', 'LOG_KERN', 'LOG_LPR', 'LOG_MAIL', 'LOG_NEWS',
'LOG_AUTH', 'LOG_SYSLOG', 'LOG_USER', 'LOG_UUCP',
'LOG_LOCAL0', 'LOG_LOCAL1', 'LOG_LOCAL2', 'LOG_LOCAL3',
'LOG_LOCAL4', 'LOG_LOCAL5', 'LOG_LOCAL6', 'LOG_LOCAL7']
valid_facilities.extend(consts)
raise TypeError(_('syslog facility must be one of: %s') %
', '.join("'%s'" % fac
for fac in valid_facilities))
return facility
class RFCSysLogHandler(logging.handlers.SysLogHandler):
def __init__(self, *args, **kwargs):
self.binary_name = _get_binary_name()
super(RFCSysLogHandler, self).__init__(*args, **kwargs)
def format(self, record):
msg = super(RFCSysLogHandler, self).format(record)
msg = self.binary_name + ' ' + msg
return msg
def _setup_logging_from_conf(project, version):
log_root = getLogger(None).logger
for handler in log_root.handlers:
log_root.removeHandler(handler)
if CONF.use_syslog:
facility = _find_facility_from_conf()
# TODO(bogdando) use the format provided by RFCSysLogHandler
# after existing syslog format deprecation in J
if CONF.use_syslog_rfc_format:
syslog = RFCSysLogHandler(address='/dev/log',
facility=facility)
else:
syslog = logging.handlers.SysLogHandler(address='/dev/log',
facility=facility)
log_root.addHandler(syslog)
logpath = _get_log_file_path()
if logpath:
filelog = logging.handlers.WatchedFileHandler(logpath)
log_root.addHandler(filelog)
if CONF.use_stderr:
streamlog = ColorHandler()
log_root.addHandler(streamlog)
elif not logpath:
# pass sys.stdout as a positional argument
# python2.6 calls the argument strm, in 2.7 it's stream
streamlog = logging.StreamHandler(sys.stdout)
log_root.addHandler(streamlog)
if CONF.publish_errors:
handler = importutils.import_object(
"climate.openstack.common.log_handler.PublishErrorsHandler",
logging.ERROR)
log_root.addHandler(handler)
datefmt = CONF.log_date_format
for handler in log_root.handlers:
# NOTE(alaski): CONF.log_format overrides everything currently. This
# should be deprecated in favor of context aware formatting.
if CONF.log_format:
handler.setFormatter(logging.Formatter(fmt=CONF.log_format,
datefmt=datefmt))
log_root.info('Deprecated: log_format is now deprecated and will '
'be removed in the next release')
else:
handler.setFormatter(ContextFormatter(project=project,
version=version,
datefmt=datefmt))
if CONF.debug:
log_root.setLevel(logging.DEBUG)
elif CONF.verbose:
log_root.setLevel(logging.INFO)
else:
log_root.setLevel(logging.WARNING)
for pair in CONF.default_log_levels:
mod, _sep, level_name = pair.partition('=')
level = logging.getLevelName(level_name)
logger = logging.getLogger(mod)
logger.setLevel(level)
_loggers = {}
def getLogger(name='unknown', version='unknown'):
if name not in _loggers:
_loggers[name] = ContextAdapter(logging.getLogger(name),
name,
version)
return _loggers[name]
def getLazyLogger(name='unknown', version='unknown'):
"""Returns lazy logger.
Creates a pass-through logger that does not create the real logger
until it is really needed and delegates all calls to the real logger
once it is created.
"""
return LazyAdapter(name, version)
class WritableLogger(object):
"""A thin wrapper that responds to `write` and logs."""
def __init__(self, logger, level=logging.INFO):
self.logger = logger
self.level = level
def write(self, msg):
self.logger.log(self.level, msg.rstrip())
class ContextFormatter(logging.Formatter):
"""A context.RequestContext aware formatter configured through flags.
The flags used to set format strings are: logging_context_format_string
and logging_default_format_string. You can also specify
logging_debug_format_suffix to append extra formatting if the log level is
debug.
For information about what variables are available for the formatter see:
http://docs.python.org/library/logging.html#formatter
If available, uses the context value stored in TLS - local.store.context
"""
def __init__(self, *args, **kwargs):
"""Initialize ContextFormatter instance
Takes additional keyword arguments which can be used in the message
format string.
:keyword project: project name
:type project: string
:keyword version: project version
:type version: string
"""
self.project = kwargs.pop('project', 'unknown')
self.version = kwargs.pop('version', 'unknown')
logging.Formatter.__init__(self, *args, **kwargs)
def format(self, record):
"""Uses contextstring if request_id is set, otherwise default."""
# store project info
record.project = self.project
record.version = self.version
# store request info
context = getattr(local.store, 'context', None)
if context:
d = _dictify_context(context)
for k, v in d.items():
setattr(record, k, v)
# NOTE(sdague): default the fancier formatting params
# to an empty string so we don't throw an exception if
# they get used
for key in ('instance', 'color'):
if key not in record.__dict__:
record.__dict__[key] = ''
if record.__dict__.get('request_id'):
self._fmt = CONF.logging_context_format_string
else:
self._fmt = CONF.logging_default_format_string
if (record.levelno == logging.DEBUG and
CONF.logging_debug_format_suffix):
self._fmt += " " + CONF.logging_debug_format_suffix
# Cache this on the record, Logger will respect our formatted copy
if record.exc_info:
record.exc_text = self.formatException(record.exc_info, record)
return logging.Formatter.format(self, record)
def formatException(self, exc_info, record=None):
"""Format exception output with CONF.logging_exception_prefix."""
if not record:
return logging.Formatter.formatException(self, exc_info)
stringbuffer = moves.StringIO()
traceback.print_exception(exc_info[0], exc_info[1], exc_info[2],
None, stringbuffer)
lines = stringbuffer.getvalue().split('\n')
stringbuffer.close()
if CONF.logging_exception_prefix.find('%(asctime)') != -1:
record.asctime = self.formatTime(record, self.datefmt)
formatted_lines = []
for line in lines:
pl = CONF.logging_exception_prefix % record.__dict__
fl = '%s%s' % (pl, line)
formatted_lines.append(fl)
return '\n'.join(formatted_lines)
class ColorHandler(logging.StreamHandler):
LEVEL_COLORS = {
logging.DEBUG: '\033[00;32m', # GREEN
logging.INFO: '\033[00;36m', # CYAN
logging.AUDIT: '\033[01;36m', # BOLD CYAN
logging.WARN: '\033[01;33m', # BOLD YELLOW
logging.ERROR: '\033[01;31m', # BOLD RED
logging.CRITICAL: '\033[01;31m', # BOLD RED
}
def format(self, record):
record.color = self.LEVEL_COLORS[record.levelno]
return logging.StreamHandler.format(self, record)
class DeprecatedConfig(Exception):
message = _("Fatal call to deprecated config: %(msg)s")
def __init__(self, msg):
super(Exception, self).__init__(self.message % dict(msg=msg))

View File

@ -19,9 +19,9 @@ import sys
from eventlet import event
from eventlet import greenthread
from oslo_log import log as logging
from climate.openstack.common.gettextutils import _LE, _LW
from climate.openstack.common import log as logging
from climate.openstack.common import timeutils
LOG = logging.getLogger(__name__)

View File

@ -17,12 +17,12 @@ import socket
import uuid
from oslo_config import cfg
from oslo_log import log as logging
from oslo_serialization import jsonutils
from climate.openstack.common import context
from climate.openstack.common.gettextutils import _, _LE
from climate.openstack.common import importutils
from climate.openstack.common import log as logging
from climate.openstack.common import timeutils

View File

@ -80,6 +80,7 @@ import ast
import re
from oslo_config import cfg
from oslo_log import log as logging
from oslo_serialization import jsonutils
import six
import six.moves.urllib.parse as urlparse
@ -87,7 +88,6 @@ import six.moves.urllib.request as urlrequest
from climate.openstack.common import fileutils
from climate.openstack.common.gettextutils import _, _LE
from climate.openstack.common import log as logging
policy_opts = [

View File

@ -18,7 +18,6 @@
"""Generic Node base class for all workers that run on hosts."""
import errno
import logging as std_logging
import os
import random
import signal
@ -36,11 +35,11 @@ except ImportError:
import eventlet
from eventlet import event
from oslo_config import cfg
from oslo_log import log as logging
from climate.openstack.common import eventlet_backdoor
from climate.openstack.common.gettextutils import _LE, _LI, _LW
from climate.openstack.common import importutils
from climate.openstack.common import log as logging
from climate.openstack.common import systemd
from climate.openstack.common import threadgroup
@ -165,7 +164,7 @@ class ServiceLauncher(Launcher):
signo = 0
LOG.debug('Full set of CONF:')
CONF.log_opt_values(LOG, std_logging.DEBUG)
CONF.log_opt_values(LOG, logging.DEBUG)
try:
if ready_callback:
@ -383,7 +382,7 @@ class ProcessLauncher(object):
"""Loop waiting on children to die and respawning as necessary."""
LOG.debug('Full set of CONF:')
CONF.log_opt_values(LOG, std_logging.DEBUG)
CONF.log_opt_values(LOG, logging.DEBUG)
try:
while True:

View File

@ -20,7 +20,7 @@ import os
import socket
import sys
from climate.openstack.common import log as logging
from oslo_log import log as logging
LOG = logging.getLogger(__name__)

View File

@ -26,11 +26,11 @@
"""Common utilities used in testing"""
import logging
import os
import tempfile
import fixtures
from oslo_log import log as logging
import testtools
_TRUE_VALUES = ('True', 'true', '1', 'yes')
@ -71,17 +71,8 @@ class BaseTestCase(testtools.TestCase):
level = logging.DEBUG
else:
level = logging.INFO
capture_logs = os.environ.get('OS_LOG_CAPTURE') in _TRUE_VALUES
if capture_logs:
self.useFixture(
fixtures.FakeLogger(
format=_LOG_FORMAT,
level=level,
nuke_handlers=capture_logs,
)
)
else:
logging.basicConfig(format=_LOG_FORMAT, level=level)
self.useFixture(fixtures.FakeLogger(format=_LOG_FORMAT,
level=level))
def create_tempfiles(self, files, ext='.conf'):
tempfiles = []

View File

@ -15,8 +15,8 @@ import threading
import eventlet
from eventlet import greenpool
from oslo_log import log as logging
from climate.openstack.common import log as logging
from climate.openstack.common import loopingcall

View File

@ -18,10 +18,10 @@ Helpers for comparing version strings.
"""
import functools
from oslo_log import log as logging
import pkg_resources
from climate.openstack.common.gettextutils import _
from climate.openstack.common import log as logging
LOG = logging.getLogger(__name__)

View File

@ -16,10 +16,10 @@
import abc
from oslo_config import cfg
from oslo_log import log as logging
import six
from climate.db import api as db_api
from climate.openstack.common import log as logging
LOG = logging.getLogger(__name__)
CONF = cfg.CONF

View File

@ -16,9 +16,9 @@
import eventlet
from novaclient import exceptions as nova_exceptions
from oslo_config import cfg
from oslo_log import log as logging
from climate import exceptions as climate_exceptions
from climate.openstack.common import log as logging
from climate.plugins import base
from climate.plugins import instances as plugin
from climate.utils.openstack import nova

View File

@ -18,10 +18,10 @@ import uuid as uuidgen
from novaclient import exceptions as nova_exceptions
from oslo_config import cfg
from oslo_log import log as logging
from climate import context
from climate.manager import exceptions as manager_exceptions
from climate.openstack.common import log as logging
from climate.plugins import oshosts as plugin
from climate.utils.openstack import nova

View File

@ -18,10 +18,10 @@
import functools
from oslo_config import cfg
from oslo_log import log as logging
from climate import context
from climate import exceptions
from climate.openstack.common import log as logging
from climate.openstack.common import policy
CONF = cfg.CONF

View File

@ -17,12 +17,12 @@
import abc
from oslo_log import log as logging
import six
from climate.db import api as db_api
from climate.db import exceptions as db_exc
from climate.manager import exceptions as mgr_exc
from climate.openstack.common import log as logging
LOG = logging.getLogger(__name__)

View File

@ -18,6 +18,7 @@ import tempfile
import testscenarios
from oslo_config import cfg
from oslo_log import log as logging
from climate import context
from climate.db.sqlalchemy import api as db_api
@ -25,14 +26,13 @@ from climate.db.sqlalchemy import facade_wrapper
from climate.openstack.common import fileutils
from climate.openstack.common.fixture import config
from climate.openstack.common.fixture import mockpatch
from climate.openstack.common import log as logging
from climate.openstack.common import policy as common_policy
from climate.openstack.common import test
from climate.tests import fake_policy
cfg.CONF.set_override('use_stderr', False)
logging.setup('climate')
logging.setup(cfg.CONF, 'climate')
_DB_CACHE = None

View File

@ -33,11 +33,11 @@ from alembic import config as alembic_config
from alembic import migration
from oslo_concurrency import lockutils
from oslo_config import cfg
from oslo_log import log as logging
import sqlalchemy
import sqlalchemy.exc
import climate.db.migration
from climate.openstack.common import log as logging
from climate import tests
LOG = logging.getLogger(__name__)

View File

@ -17,10 +17,10 @@ import sys
import eventlet
from novaclient import exceptions as nova_exceptions
from oslo_log import log as logging
import testtools
from climate import exceptions as climate_exceptions
from climate.openstack.common import log as logging
from climate.plugins.instances import vm_plugin
from climate import tests
from climate.utils.openstack import nova

View File

@ -18,11 +18,11 @@
import functools
from oslo_config import cfg
from oslo_log import log as logging
import oslo_messaging as messaging
from climate import context
from climate.openstack.common.gettextutils import _
from climate.openstack.common import log as logging
from climate.openstack.common import service
LOG = logging.getLogger(__name__)
@ -93,11 +93,4 @@ def with_empty_context(func):
def prepare_service(argv=[]):
cfg.set_defaults(logging.log_opts,
default_log_levels=['amqplib=WARN',
'qpid.messaging=INFO',
'stevedore=INFO',
'eventlet.wsgi.server=WARN'
])
cfg.CONF(argv[1:], project='climate')
logging.setup('climate')
logging.setup(cfg.CONF, 'climate')

View File

@ -1,5 +1,109 @@
[DEFAULT]
#
# Options defined in oslo.log
#
# If set to true, the logging level will be set to DEBUG
# instead of the default INFO level. (boolean value)
#debug=false
# If set to false, the logging level will be set to WARNING
# instead of the default INFO level. (boolean value)
#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. Note that when logging
# configuration files are used then all logging configuration
# is set in the configuration file and other logging
# configuration options are ignored (for example,
# logging_context_format_string). (string value)
# Deprecated group/name - [DEFAULT]/log_config
#log_config_append=<None>
# Defines the format string for %%(asctime)s in log records.
# Default: %(default)s . This option is ignored if
# log_config_append is set. (string value)
#log_date_format=%Y-%m-%d %H:%M:%S
# (Optional) Name of log file to send logging output to. If no
# default is set, logging will go to stderr as defined by
# use_stderr. This option is ignored if log_config_append is
# set. (string value)
# Deprecated group/name - [DEFAULT]/logfile
#log_file=<None>
# (Optional) The base directory used for relative log_file
# paths. This option is ignored if log_config_append is set.
# (string value)
# Deprecated group/name - [DEFAULT]/logdir
#log_dir=<None>
# Uses logging handler designed to watch file system. When log
# file is moved or removed this handler will open a new log
# file with specified path instantaneously. It makes sense
# only if log_file option is specified and Linux platform is
# used. This option is ignored if log_config_append is set.
# (boolean value)
#watch_log_file=false
# Use syslog for logging. Existing syslog format is DEPRECATED
# and will be changed later to honor RFC5424. This option is
# ignored if log_config_append is set. (boolean value)
#use_syslog=false
# Syslog facility to receive log lines. This option is ignored
# if log_config_append is set. (string value)
#syslog_log_facility=LOG_USER
# Log output to standard error. This option is ignored if
# log_config_append is set. (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 when context is
# undefined. (string value)
#logging_default_format_string=%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [-] %(instance)s%(message)s
# Additional data to append to log message when logging level
# for the message 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
# Defines the format string for %(user_identity)s that is used
# in logging_context_format_string. (string value)
#logging_user_identity_format=%(user)s %(tenant)s %(domain)s %(user_domain)s %(project_domain)s
# List of package logging levels in logger=LEVEL pairs. This
# option is ignored if log_config_append is set. (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,keystoneauth=WARN,oslo.cache=INFO,dogpile.core.dogpile=INFO
# 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
#
# Options defined in oslo.messaging
#
@ -260,97 +364,6 @@
#backdoor_port=<None>
#
# Options defined in climate.openstack.common.log
#
# Print debugging output (set logging level to DEBUG instead
# of default WARNING level). (boolean value)
#debug=false
# Print more verbose output (set logging level to INFO instead
# of default WARNING level). (boolean value)
#verbose=false
# 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 TRACE %(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,iso8601=WARN,requests.packages.urllib3.connectionpool=WARN
# Publish error events (boolean value)
#publish_errors=false
# Make deprecations fatal (boolean value)
#fatal_deprecations=false
# If an instance is passed with the log message, format it
# like this (string value)
#instance_format="[instance: %(uuid)s] "
# If an instance UUID is passed with the log message, format
# it like this (string value)
#instance_uuid_format="[instance: %(uuid)s] "
# The name of logging configuration file. It does not disable
# existing loggers, but just appends specified logging
# configuration to any other existing logging options. Please
# see the Python logging module documentation for details on
# logging configuration files. (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
# during I, and then will be changed in J to honor RFC5424
# (boolean value)
#use_syslog=false
# (Optional) Use syslog rfc5424 format for logging. If
# enabled, will add APP-NAME (RFC5424) before the MSG part of
# the syslog message. The old format without APP-NAME is
# deprecated in I, and will be removed in J. (boolean value)
#use_syslog_rfc_format=false
# Syslog facility to receive log lines (string value)
#syslog_log_facility=LOG_USER
#
# Options defined in climate.openstack.common.notifier.api

View File

@ -12,6 +12,7 @@ keystonemiddleware!=4.5.0,>=4.2.0 # Apache-2.0
kombu!=4.0.0,!=4.0.1,>=3.0.25 # BSD
oslo.concurrency>=3.8.0 # Apache-2.0
oslo.config!=3.18.0,>=3.14.0 # Apache-2.0
oslo.log>=3.11.0 # Apache-2.0
oslo.messaging>=5.14.0 # Apache-2.0
oslo.serialization>=1.10.0 # Apache-2.0
python-novaclient!=2.33.0,>=2.29.0 # Apache-2.0
@ -25,4 +26,3 @@ SQLAlchemy<1.1.0,>=1.0.10 # MIT
stevedore>=1.17.1 # Apache-2.0
WebOb>=1.6.0 # MIT
WSME>=0.8 # MIT

View File

@ -1,2 +1,2 @@
export CLIMATE_CONFIG_GENERATOR_EXTRA_MODULES=""
export CLIMATE_CONFIG_GENERATOR_EXTRA_LIBRARIES="keystonemiddleware.auth_token oslo.messaging oslo.concurrency"
export CLIMATE_CONFIG_GENERATOR_EXTRA_LIBRARIES="keystonemiddleware.auth_token oslo.messaging oslo.concurrency oslo.log"