Merge "Use openstack.common.log for logging."

This commit is contained in:
Jenkins 2012-07-20 15:08:03 +00:00 committed by Gerrit Code Review
commit d8ae1541c4
77 changed files with 316 additions and 488 deletions

View File

@ -6,6 +6,7 @@ Brian Waldon <brian.waldon@rackspace.com>
Chris Behrens <cbehrens@codestud.com>
Christopher MacGown <chris@pistoncloud.com>
Chuck Short <zulcss@ubuntu.com>
Chmouel Boudjnah <chmouel@chmouel.com>
Clark Boylan <clark.boylan@gmail.com>
Craig Vyvial <cp16net@gmail.com>
Devin Carlen <devin.carlen@gmail.com>

View File

@ -41,7 +41,7 @@ if os.path.exists(os.path.join(possible_topdir, "cinder", "__init__.py")):
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder import service
from cinder import utils
@ -50,7 +50,7 @@ LOG = logging.getLogger('cinder.all')
if __name__ == '__main__':
flags.parse_args(sys.argv)
logging.setup()
logging.setup("cinder")
utils.monkey_patch()
servers = []
# cinder-api

View File

@ -33,13 +33,13 @@ if os.path.exists(os.path.join(possible_topdir, "cinder", "__init__.py")):
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder import service
from cinder import utils
if __name__ == '__main__':
flags.parse_args(sys.argv)
logging.setup()
logging.setup("cinder")
utils.monkey_patch()
server = service.WSGIService('osapi_volume')
service.serve(server)

View File

@ -81,7 +81,7 @@ from cinder import db
from cinder.db import migration
from cinder import exception
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder.openstack.common import cfg
from cinder.openstack.common import importutils
from cinder.openstack.common import rpc
@ -531,7 +531,7 @@ def main():
try:
argv = flags.parse_args(sys.argv)
logging.setup()
logging.setup("cinder")
except cfg.ConfigFilesNotFoundError:
cfgfile = FLAGS.config_file[-1] if FLAGS.config_file else None
if cfgfile and not os.access(cfgfile, os.R_OK):

View File

@ -37,13 +37,13 @@ if os.path.exists(os.path.join(possible_topdir, 'cinder', '__init__.py')):
gettext.install('cinder', unicode=1)
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder import service
from cinder import utils
if __name__ == '__main__':
flags.parse_args(sys.argv)
logging.setup()
logging.setup("cinder")
utils.monkey_patch()
server = service.Service.create(binary='cinder-scheduler')
service.serve(server)

View File

@ -35,12 +35,12 @@ if os.path.exists(os.path.join(possible_topdir, 'cinder', '__init__.py')):
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder import service
if __name__ == '__main__':
flags.parse_args(sys.argv)
logging.setup()
logging.setup("cinder")
utils.monkey_patch()
server = service.Service.create(binary='cinder-volume')
service.serve(server)

View File

@ -43,7 +43,7 @@ gettext.install('cinder', unicode=1)
from cinder import context
from cinder import exception
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder.openstack.common import cfg
from cinder.openstack.common import rpc
@ -71,7 +71,7 @@ def delete_queues(queues):
if __name__ == '__main__':
args = flags.parse_args(sys.argv)
logging.setup()
logging.setup("cinder")
delete_queues(args[1:])
if FLAGS.delete_exchange:
delete_exchange(FLAGS.control_exchange)

View File

@ -23,7 +23,7 @@ import webob.exc
from cinder import context
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder.openstack.common import cfg
from cinder import wsgi

View File

@ -25,7 +25,7 @@ import webob.dec
import webob.exc
from cinder.api.openstack import wsgi
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder import wsgi as base_wsgi

View File

@ -23,7 +23,7 @@ import webob.exc
from cinder.api.openstack import wsgi
from cinder import context
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder import wsgi as base_wsgi
LOG = logging.getLogger(__name__)

View File

@ -26,7 +26,7 @@ from xml.dom import minidom
from cinder.api.openstack import wsgi
from cinder.api.openstack import xmlutil
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder import quota

View File

@ -26,7 +26,7 @@ from cinder.api.openstack import wsgi
from cinder.api.openstack import xmlutil
from cinder import exception
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder.openstack.common import exception as common_exception
from cinder.openstack.common import importutils
import cinder.policy

View File

@ -19,7 +19,7 @@ import paste.urlmap
import re
import urllib2
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder.api.openstack import wsgi

View File

@ -26,7 +26,7 @@ from cinder.api.openstack.volume import snapshots
from cinder.api.openstack.volume import types
from cinder.api.openstack.volume import volumes
from cinder.api.openstack.volume import versions
from cinder import log as logging
from cinder.openstack.common import log as logging
LOG = logging.getLogger(__name__)

View File

@ -22,7 +22,7 @@ It can't be called 'extensions' because that causes namespacing problems.
"""
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder.api.openstack import extensions

View File

@ -23,7 +23,7 @@ from cinder import volume
from cinder import db
from cinder import exception
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
FLAGS = flags.FLAGS

View File

@ -24,7 +24,7 @@ from cinder.api.openstack import wsgi
from cinder import volume
from cinder import exception
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
FLAGS = flags.FLAGS

View File

@ -17,7 +17,7 @@
from cinder.api.openstack import extensions as base_extensions
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
LOG = logging.getLogger(__name__)

View File

@ -23,7 +23,7 @@ from cinder.api.openstack import wsgi
from cinder.api.openstack import xmlutil
from cinder import exception
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder import volume

View File

@ -23,7 +23,7 @@ from cinder.api.openstack import wsgi
from cinder.api.openstack import xmlutil
from cinder import exception
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder import volume
from cinder.volume import volume_types

View File

@ -25,7 +25,7 @@ from lxml import etree
import webob
from cinder import exception
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder.openstack.common import jsonutils
from cinder import wsgi

View File

@ -23,7 +23,7 @@ import webob.exc
from cinder import context
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder.openstack.common import cfg
from cinder import wsgi

View File

@ -21,7 +21,7 @@
import copy
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder.openstack.common import local
from cinder.openstack.common import timeutils
from cinder import utils

View File

@ -26,7 +26,7 @@ from cinder import db
from cinder import exception
from cinder import flags
from cinder import utils
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder.db.sqlalchemy import models
from cinder.db.sqlalchemy.session import get_session
from cinder.openstack.common import timeutils

View File

@ -18,7 +18,7 @@ from sqlalchemy import Boolean, Column, DateTime, ForeignKey
from sqlalchemy import Integer, MetaData, String, Table
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
FLAGS = flags.FLAGS

View File

@ -24,7 +24,7 @@ from cinder.db import migration
from cinder.db.sqlalchemy.session import get_engine
from cinder import exception
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
import sqlalchemy

View File

@ -27,7 +27,7 @@ from sqlalchemy.pool import NullPool, StaticPool
import cinder.exception
import cinder.flags as flags
import cinder.log as logging
from cinder.openstack.common import log as logging
FLAGS = flags.FLAGS

View File

@ -29,7 +29,7 @@ import sys
import webob.exc
from cinder import log as logging
from cinder.openstack.common import log as logging
LOG = logging.getLogger(__name__)

View File

@ -73,18 +73,6 @@ def _get_my_ip():
return "127.0.0.1"
log_opts = [
cfg.StrOpt('logdir',
default=None,
help='Log output to a per-service log file in named directory'),
cfg.StrOpt('logfile',
default=None,
help='Log output to a named file'),
cfg.BoolOpt('use_stderr',
default=True,
help='Log output to standard error'),
]
core_opts = [
cfg.StrOpt('connection_type',
default=None,
@ -116,7 +104,6 @@ core_opts = [
debug_opts = [
]
FLAGS.register_cli_opts(log_opts)
FLAGS.register_cli_opts(core_opts)
FLAGS.register_cli_opts(debug_opts)
@ -205,9 +192,6 @@ global_opts = [
cfg.IntOpt('auth_token_ttl',
default=3600,
help='Seconds for auth tokens to linger'),
cfg.StrOpt('logfile_mode',
default='0644',
help='Default file mode used when creating log files'),
cfg.StrOpt('sqlite_db',
default='cinder.sqlite',
help='the filename to use with sqlite'),

View File

@ -55,7 +55,7 @@ This module provides Manager, a base class for managers.
from cinder.db import base
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder.openstack.common.rpc import dispatcher as rpc_dispatcher
from cinder.scheduler import rpcapi as scheduler_rpcapi
from cinder import version

View File

@ -17,7 +17,7 @@ import uuid
from cinder import flags
from cinder import utils
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder.openstack.common import cfg
from cinder.openstack.common import importutils
from cinder.openstack.common import jsonutils

View File

@ -15,7 +15,7 @@
from cinder import context
from cinder import db
from cinder import log as logging
from cinder.openstack.common import log as logging
LOG = logging.getLogger(__name__)

View File

@ -14,7 +14,7 @@
# under the License.
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder.openstack.common import cfg
from cinder.openstack.common import exception as common_exception
from cinder.openstack.common import importutils

View File

@ -15,7 +15,7 @@
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder.openstack.common import jsonutils

View File

@ -17,7 +17,7 @@
import cinder.context
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder.openstack.common import cfg
from cinder.openstack.common import rpc

View File

@ -19,6 +19,7 @@
Exceptions common to OpenStack projects
"""
import itertools
import logging

View File

@ -44,6 +44,6 @@ def save_and_reraise_exception():
yield
except Exception:
logging.error('Original exception being dropped: %s' %
(traceback.format_exception(type_, value, tb)))
(traceback.format_exception(type_, value, tb)))
raise
raise type_, value, tb

View File

@ -20,8 +20,7 @@ Import related utilities and helper functions.
"""
import sys
from cinder.openstack.common import exception
import traceback
def import_class(import_str):
@ -30,8 +29,10 @@ def import_class(import_str):
try:
__import__(mod_str)
return getattr(sys.modules[mod_str], class_str)
except (ImportError, ValueError, AttributeError):
raise exception.NotFound('Class %s cannot be found' % class_str)
except (ImportError, ValueError, AttributeError), exc:
raise ImportError('Class %s cannot be found (%s)' %
(class_str,
traceback.format_exception(*sys.exc_info())))
def import_object(import_str, *args, **kwargs):
@ -39,6 +40,19 @@ def import_object(import_str, *args, **kwargs):
return import_class(import_str)(*args, **kwargs)
def import_object_ns(name_space, import_str, *args, **kwargs):
"""
Import a class and return an instance of it, first by trying
to find the class in a default namespace, then failing back to
a full path if not found in the default namespace.
"""
import_value = "%s.%s" % (name_space, import_str)
try:
return import_class(import_value)(*args, **kwargs)
except ImportError:
return import_class(import_str)(*args, **kwargs)
def import_module(import_str):
"""Import a module."""
__import__(import_str)

View File

@ -53,7 +53,8 @@ class BaseParser(object):
key, value = line[:colon], line[colon + 1:]
value = value.strip()
if value[0] == value[-1] and value[0] == "\"" or value[0] == "'":
if ((value and value[0] == value[-1]) and
(value[0] == "\"" or value[0] == "'")):
value = value[1:-1]
return key.strip(), [value]

View File

@ -17,7 +17,7 @@
# License for the specific language governing permissions and limitations
# under the License.
"""Cinder logging handler.
"""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
@ -25,7 +25,7 @@ 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 flags.
It also allows setting of formatting information through conf.
"""
@ -40,12 +40,11 @@ import stat
import sys
import traceback
import cinder
from cinder import flags
from cinder.openstack.common import cfg
from cinder.openstack.common.gettextutils import _
from cinder.openstack.common import jsonutils
from cinder.openstack.common import local
from cinder import version
from cinder import notifier
log_opts = [
@ -67,12 +66,13 @@ log_opts = [
help='prefix each line of exception output with this format'),
cfg.ListOpt('default_log_levels',
default=[
'amqplib=WARN',
'sqlalchemy=WARN',
'boto=WARN',
'suds=INFO',
'eventlet.wsgi.server=WARN'
],
'amqplib=WARN',
'sqlalchemy=WARN',
'boto=WARN',
'suds=INFO',
'keystone=INFO',
'eventlet.wsgi.server=WARN'
],
help='list of logger=LEVEL pairs'),
cfg.BoolOpt('publish_errors',
default=False,
@ -89,10 +89,28 @@ log_opts = [
default='[instance: %(uuid)s] ',
help='If an instance UUID is passed with the log message, '
'format it like this'),
]
]
FLAGS = flags.FLAGS
FLAGS.register_opts(log_opts)
generic_log_opts = [
cfg.StrOpt('logdir',
default=None,
help='Log output to a per-service log file in named directory'),
cfg.StrOpt('logfile',
default=None,
help='Log output to a named file'),
cfg.BoolOpt('use_stderr',
default=True,
help='Log output to standard error'),
cfg.StrOpt('logfile_mode',
default='0644',
help='Default file mode used when creating log files'),
]
CONF = cfg.CONF
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
@ -128,8 +146,8 @@ def _get_binary_name():
def _get_log_file_path(binary=None):
logfile = FLAGS.log_file or FLAGS.logfile
logdir = FLAGS.log_dir or FLAGS.logdir
logfile = CONF.log_file or CONF.logfile
logdir = CONF.log_dir or CONF.logdir
if logfile and not logdir:
return logfile
@ -142,11 +160,13 @@ def _get_log_file_path(binary=None):
return '%s.log' % (os.path.join(logdir, binary),)
class CinderContextAdapter(logging.LoggerAdapter):
class ContextAdapter(logging.LoggerAdapter):
warn = logging.LoggerAdapter.warning
def __init__(self, logger):
def __init__(self, logger, project_name, version_string):
self.logger = logger
self.project = project_name
self.version = version_string
def audit(self, msg, *args, **kwargs):
self.log(logging.AUDIT, msg, *args, **kwargs)
@ -165,15 +185,16 @@ class CinderContextAdapter(logging.LoggerAdapter):
instance = kwargs.pop('instance', None)
instance_extra = ''
if instance:
instance_extra = FLAGS.instance_format % instance
instance_extra = CONF.instance_format % instance
else:
instance_uuid = kwargs.pop('instance_uuid', None)
if instance_uuid:
instance_extra = (FLAGS.instance_uuid_format
instance_extra = (CONF.instance_uuid_format
% {'uuid': instance_uuid})
extra.update({'instance': instance_extra})
extra.update({"cinder_version": version.version_string_with_vcs()})
extra.update({"project": self.project})
extra.update({"version": self.version})
extra['extra'] = extra.copy()
return msg, kwargs
@ -187,9 +208,9 @@ class JSONFormatter(logging.Formatter):
def formatException(self, ei, strip_newlines=True):
lines = traceback.format_exception(*ei)
if strip_newlines:
lines = [itertools.ifilter(lambda x: x,
line.rstrip().splitlines())
for line in lines]
lines = [itertools.ifilter(
lambda x: x,
line.rstrip().splitlines()) for line in lines]
lines = list(itertools.chain(*lines))
return lines
@ -224,8 +245,153 @@ class JSONFormatter(logging.Formatter):
return jsonutils.dumps(message)
class LegacyCinderFormatter(logging.Formatter):
"""A cinder.context.RequestContext aware formatter configured via flags.
class PublishErrorsHandler(logging.Handler):
def emit(self, record):
if 'list_notifier_drivers' in CONF:
if ('cinder.openstack.common.notifier.log_notifier' in
CONF.list_notifier_drivers):
return
notifier.api.notify('error.publisher',
'error_notification',
notifier.api.ERROR,
dict(error=record.msg))
def handle_exception(type, value, tb):
extra = {}
if CONF.verbose:
extra['exc_info'] = (type, value, tb)
getLogger().critical(str(value), **extra)
def setup(product_name):
"""Setup logging."""
sys.excepthook = handle_exception
if CONF.log_config:
try:
logging.config.fileConfig(CONF.log_config)
except Exception:
traceback.print_exc()
raise
else:
_setup_logging_from_conf(product_name)
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
def _setup_logging_from_conf(product_name):
log_root = getLogger(product_name).logger
for handler in log_root.handlers:
log_root.removeHandler(handler)
if CONF.use_syslog:
facility = _find_facility_from_conf()
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)
mode = int(CONF.logfile_mode, 8)
st = os.stat(logpath)
if st.st_mode != (stat.S_IFREG | mode):
os.chmod(logpath, mode)
if CONF.use_stderr:
streamlog = ColorHandler()
log_root.addHandler(streamlog)
elif not CONF.log_file:
# 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:
log_root.addHandler(PublishErrorsHandler(logging.ERROR))
for handler in log_root.handlers:
datefmt = CONF.log_date_format
if CONF.log_format:
handler.setFormatter(logging.Formatter(fmt=CONF.log_format,
datefmt=datefmt))
handler.setFormatter(LegacyFormatter(datefmt=datefmt))
if CONF.verbose or CONF.debug:
log_root.setLevel(logging.DEBUG)
else:
log_root.setLevel(logging.INFO)
level = logging.NOTSET
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)
for handler in log_root.handlers:
logger.addHandler(handler)
# NOTE(jkoelker) Clear the handlers for the root logger that was setup
# by basicConfig in nova/__init__.py and install the
# NullHandler.
root = logging.getLogger()
for handler in root.handlers:
root.removeHandler(handler)
handler = NullHandler()
handler.setFormatter(logging.Formatter())
root.addHandler(handler)
_loggers = {}
def getLogger(name='unknown', version='unknown'):
if name not in _loggers:
_loggers[name] = ContextAdapter(logging.getLogger(name),
name,
version)
return _loggers[name]
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)
class LegacyFormatter(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
@ -243,13 +409,13 @@ class LegacyCinderFormatter(logging.Formatter):
record.__dict__['instance'] = ''
if record.__dict__.get('request_id', None):
self._fmt = FLAGS.logging_context_format_string
self._fmt = CONF.logging_context_format_string
else:
self._fmt = FLAGS.logging_default_format_string
self._fmt = CONF.logging_default_format_string
if (record.levelno == logging.DEBUG and
FLAGS.logging_debug_format_suffix):
self._fmt += " " + FLAGS.logging_debug_format_suffix
CONF.logging_debug_format_suffix):
self._fmt += " " + CONF.logging_debug_format_suffix
# Cache this on the record, Logger will respect our formated copy
if record.exc_info:
@ -257,7 +423,7 @@ class LegacyCinderFormatter(logging.Formatter):
return logging.Formatter.format(self, record)
def formatException(self, exc_info, record=None):
"""Format exception output with FLAGS.logging_exception_prefix."""
"""Format exception output with CONF.logging_exception_prefix."""
if not record:
return logging.Formatter.formatException(self, exc_info)
@ -267,150 +433,27 @@ class LegacyCinderFormatter(logging.Formatter):
lines = stringbuffer.getvalue().split('\n')
stringbuffer.close()
if FLAGS.logging_exception_prefix.find('%(asctime)') != -1:
if CONF.logging_exception_prefix.find('%(asctime)') != -1:
record.asctime = self.formatTime(record, self.datefmt)
formatted_lines = []
for line in lines:
pl = FLAGS.logging_exception_prefix % record.__dict__
pl = CONF.logging_exception_prefix % record.__dict__
fl = '%s%s' % (pl, line)
formatted_lines.append(fl)
return '\n'.join(formatted_lines)
class PublishErrorsHandler(logging.Handler):
def emit(self, record):
if 'list_notifier_drivers' in FLAGS:
if 'cinder.notifier.log_notifier' in FLAGS.list_notifier_drivers:
return
cinder.notifier.api.notify('cinder.error.publisher',
'error_notification',
cinder.notifier.api.ERROR,
dict(error=record.msg))
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 handle_exception(type, value, tb):
extra = {}
if FLAGS.verbose:
extra['exc_info'] = (type, value, tb)
getLogger().critical(str(value), **extra)
def setup():
"""Setup cinder logging."""
sys.excepthook = handle_exception
if FLAGS.log_config:
try:
logging.config.fileConfig(FLAGS.log_config)
except Exception:
traceback.print_exc()
raise
else:
_setup_logging_from_flags()
def _find_facility_from_flags():
facility_names = logging.handlers.SysLogHandler.facility_names
facility = getattr(logging.handlers.SysLogHandler,
FLAGS.syslog_log_facility,
None)
if facility is None and FLAGS.syslog_log_facility in facility_names:
facility = facility_names.get(FLAGS.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
def _setup_logging_from_flags():
cinder_root = getLogger().logger
for handler in cinder_root.handlers:
cinder_root.removeHandler(handler)
if FLAGS.use_syslog:
facility = _find_facility_from_flags()
syslog = logging.handlers.SysLogHandler(address='/dev/log',
facility=facility)
cinder_root.addHandler(syslog)
logpath = _get_log_file_path()
if logpath:
filelog = logging.handlers.WatchedFileHandler(logpath)
cinder_root.addHandler(filelog)
mode = int(FLAGS.logfile_mode, 8)
st = os.stat(logpath)
if st.st_mode != (stat.S_IFREG | mode):
os.chmod(logpath, mode)
if FLAGS.use_stderr:
streamlog = logging.StreamHandler()
cinder_root.addHandler(streamlog)
elif not FLAGS.log_file:
streamlog = logging.StreamHandler(stream=sys.stdout)
cinder_root.addHandler(streamlog)
if FLAGS.publish_errors:
cinder_root.addHandler(PublishErrorsHandler(logging.ERROR))
for handler in cinder_root.handlers:
datefmt = FLAGS.log_date_format
if FLAGS.log_format:
handler.setFormatter(logging.Formatter(fmt=FLAGS.log_format,
datefmt=datefmt))
handler.setFormatter(LegacyCinderFormatter(datefmt=datefmt))
if FLAGS.verbose or FLAGS.debug:
cinder_root.setLevel(logging.DEBUG)
else:
cinder_root.setLevel(logging.INFO)
level = logging.NOTSET
for pair in FLAGS.default_log_levels:
mod, _sep, level_name = pair.partition('=')
level = logging.getLevelName(level_name)
logger = logging.getLogger(mod)
logger.setLevel(level)
# NOTE(jkoelker) Clear the handlers for the root logger that was setup
# by basicConfig in cinder/__init__.py and install the
# NullHandler.
root = logging.getLogger()
for handler in root.handlers:
root.removeHandler(handler)
handler = NullHandler()
handler.setFormatter(logging.Formatter())
root.addHandler(handler)
_loggers = {}
def getLogger(name='cinder'):
if name not in _loggers:
_loggers[name] = CinderContextAdapter(logging.getLogger(name))
return _loggers[name]
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)
def format(self, record):
record.color = self.LEVEL_COLORS[record.levelno]
return logging.StreamHandler.format(self, record)

View File

@ -52,7 +52,7 @@ zmq_opts = [
default=('cinder.openstack.common.rpc.'
'matchmaker.MatchMakerLocalhost'),
help='MatchMaker driver',
),
),
# The following port is unassigned by IANA as of 2012-05-21
cfg.IntOpt('rpc_zmq_port', default=9501,

View File

@ -23,7 +23,7 @@ Scheduler base class that all Schedulers should inherit from
from cinder import db
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder.openstack.common import cfg
from cinder.openstack.common import importutils
from cinder.openstack.common import rpc

View File

@ -26,7 +26,7 @@ import functools
from cinder import db
from cinder import exception
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder import manager
from cinder.notifier import api as notifier
from cinder.openstack.common import cfg

View File

@ -31,7 +31,7 @@ from cinder import context
from cinder import db
from cinder import exception
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder.openstack.common import cfg
from cinder.openstack.common import importutils
from cinder.openstack.common import rpc

View File

@ -34,7 +34,7 @@ import nose.plugins.skip
import stubout
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder.openstack.common import cfg
from cinder.openstack.common import timeutils
from cinder import utils

View File

@ -74,7 +74,7 @@ absdir = os.path.abspath(reldir)
sys.path.insert(0, absdir)
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder.openstack.common import cfg
@ -345,7 +345,7 @@ def run():
# arbitrary nosetest flags as well
argv = [x for x in sys.argv if x != '--hide-elapsed']
hide_elapsed = argv != sys.argv
logging.setup()
logging.setup("cinder")
# If any argument looks like a test name but doesn't have "cinder.tests" in
# front of it, automatically add that so we don't have to type as much

View File

@ -20,7 +20,7 @@ from cinder.api.openstack.volume import volumes
from cinder.api.openstack.volume import versions
from cinder.api.openstack import wsgi
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder import test
from cinder.tests.api.openstack import fakes

View File

@ -21,7 +21,7 @@ import webob
from cinder.api.openstack.volume import snapshots
from cinder import exception
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder import test
from cinder import volume
from cinder.tests.api.openstack import fakes

View File

@ -21,7 +21,7 @@ import re
from eventlet import greenthread
from cinder import exception
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder import utils
LOG = logging.getLogger(__name__)

View File

@ -18,7 +18,7 @@ import httplib
import urllib
import urlparse
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder.openstack.common import jsonutils

View File

@ -22,7 +22,7 @@ Provides common functionality for integrated unit tests
import random
import string
from cinder.log import logging
from cinder.openstack.common import log as logging
from cinder import service
from cinder import test # For the flags
from cinder.tests.integrated.api import client

View File

@ -17,7 +17,7 @@
from cinder.api.openstack.volume import extensions
from cinder import flags
from cinder.log import logging
from cinder.openstack.common import log as logging
from cinder.tests.integrated import integrated_helpers

View File

@ -16,7 +16,7 @@
# under the License.
from cinder.log import logging
from cinder.openstack.common import log as logging
from cinder.tests.integrated import integrated_helpers

View File

@ -19,7 +19,7 @@ import unittest
import time
from cinder import service
from cinder.log import logging
from cinder.openstack.common import log as logging
from cinder.tests.integrated import integrated_helpers
from cinder.tests.integrated.api import client
from cinder.volume import driver

View File

@ -17,7 +17,7 @@
from lxml import etree
from cinder.log import logging
from cinder.openstack.common import log as logging
from cinder.tests.integrated import integrated_helpers
from cinder.api.openstack import common
from cinder.api.openstack import xmlutil

View File

@ -14,7 +14,7 @@
# under the License.
import cinder
from cinder import log as logging
from cinder.openstack.common import log as logging
import cinder.notifier.api
import cinder.notifier.log_notifier
import cinder.notifier.no_op_notifier

View File

@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
from cinder import exception
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder import test
from cinder.volume import san

View File

@ -16,7 +16,7 @@
# under the License.
from cinder import exception
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder.volume import san
from cinder import test

View File

@ -1,217 +0,0 @@
import cStringIO
import logging
from cinder import context
from cinder import flags
from cinder import log
from cinder.openstack.common import jsonutils
from cinder.notifier import api as notifier
from cinder import test
FLAGS = flags.FLAGS
flags.DECLARE('list_notifier_drivers',
'cinder.notifier.list_notifier')
def _fake_context():
return context.RequestContext(1, 1)
class LoggerTestCase(test.TestCase):
def setUp(self):
super(LoggerTestCase, self).setUp()
self.log = log.getLogger()
def test_handlers_have_cinder_formatter(self):
formatters = []
for h in self.log.logger.handlers:
f = h.formatter
if isinstance(f, log.LegacyCinderFormatter):
formatters.append(f)
self.assert_(formatters)
self.assertEqual(len(formatters), len(self.log.logger.handlers))
def test_handles_context_kwarg(self):
self.log.info("foo", context=_fake_context())
self.assert_(True) # didn't raise exception
def test_audit_handles_context_arg(self):
self.log.audit("foo", context=_fake_context())
self.assert_(True) # didn't raise exception
def test_will_be_verbose_if_verbose_flag_set(self):
self.flags(verbose=True)
log.setup()
self.assertEqual(logging.DEBUG, self.log.logger.getEffectiveLevel())
def test_will_not_be_verbose_if_verbose_flag_not_set(self):
self.flags(verbose=False)
log.setup()
self.assertEqual(logging.INFO, self.log.logger.getEffectiveLevel())
def test_no_logging_via_module(self):
for func in ('critical', 'error', 'exception', 'warning', 'warn',
'info', 'debug', 'log', 'audit'):
self.assertRaises(AttributeError, getattr, log, func)
class LogHandlerTestCase(test.TestCase):
def test_log_path_logdir(self):
self.flags(logdir='/some/path', logfile=None)
self.assertEquals(log._get_log_file_path(binary='foo-bar'),
'/some/path/foo-bar.log')
def test_log_path_logfile(self):
self.flags(logfile='/some/path/foo-bar.log')
self.assertEquals(log._get_log_file_path(binary='foo-bar'),
'/some/path/foo-bar.log')
def test_log_path_none(self):
self.flags(logdir=None, logfile=None)
self.assertTrue(log._get_log_file_path(binary='foo-bar') is None)
def test_log_path_logfile_overrides_logdir(self):
self.flags(logdir='/some/other/path',
logfile='/some/path/foo-bar.log')
self.assertEquals(log._get_log_file_path(binary='foo-bar'),
'/some/path/foo-bar.log')
class PublishErrorsHandlerTestCase(test.TestCase):
"""Tests for cinder.log.PublishErrorsHandler"""
def setUp(self):
super(PublishErrorsHandlerTestCase, self).setUp()
self.publiserrorshandler = log.PublishErrorsHandler(logging.ERROR)
def test_emit_cfg_list_notifier_drivers_in_flags(self):
self.stub_flg = False
def fake_notifier(*args, **kwargs):
self.stub_flg = True
self.stubs.Set(notifier, 'notify', fake_notifier)
logrecord = logging.LogRecord('name', 'WARN', '/tmp', 1,
'Message', None, None)
self.publiserrorshandler.emit(logrecord)
self.assertTrue(self.stub_flg)
def test_emit_cfg_log_notifier_in_list_notifier_drivers(self):
self.flags(list_notifier_drivers=['cinder.notifier.rabbit_notifier',
'cinder.notifier.log_notifier'])
self.stub_flg = True
def fake_notifier(*args, **kwargs):
self.stub_flg = False
self.stubs.Set(notifier, 'notify', fake_notifier)
logrecord = logging.LogRecord('name', 'WARN', '/tmp', 1,
'Message', None, None)
self.publiserrorshandler.emit(logrecord)
self.assertTrue(self.stub_flg)
class CinderFormatterTestCase(test.TestCase):
def setUp(self):
super(CinderFormatterTestCase, self).setUp()
self.flags(logging_context_format_string="HAS CONTEXT "
"[%(request_id)s]: "
"%(message)s",
logging_default_format_string="NOCTXT: %(message)s",
logging_debug_format_suffix="--DBG")
self.log = log.getLogger()
self.stream = cStringIO.StringIO()
self.handler = logging.StreamHandler(self.stream)
self.handler.setFormatter(log.LegacyCinderFormatter())
self.log.logger.addHandler(self.handler)
self.level = self.log.logger.getEffectiveLevel()
self.log.logger.setLevel(logging.DEBUG)
def tearDown(self):
self.log.logger.setLevel(self.level)
self.log.logger.removeHandler(self.handler)
super(CinderFormatterTestCase, self).tearDown()
def test_uncontextualized_log(self):
self.log.info("foo")
self.assertEqual("NOCTXT: foo\n", self.stream.getvalue())
def test_contextualized_log(self):
ctxt = _fake_context()
self.log.info("bar", context=ctxt)
expected = "HAS CONTEXT [%s]: bar\n" % ctxt.request_id
self.assertEqual(expected, self.stream.getvalue())
def test_debugging_log(self):
self.log.debug("baz")
self.assertEqual("NOCTXT: baz --DBG\n", self.stream.getvalue())
class CinderLoggerTestCase(test.TestCase):
def setUp(self):
super(CinderLoggerTestCase, self).setUp()
levels = FLAGS.default_log_levels
levels.append("cinder-test=AUDIT")
self.flags(default_log_levels=levels,
verbose=True)
log.setup()
self.log = log.getLogger('cinder-test')
def test_has_level_from_flags(self):
self.assertEqual(logging.AUDIT, self.log.logger.getEffectiveLevel())
def test_child_log_has_level_of_parent_flag(self):
l = log.getLogger('cinder-test.foo')
self.assertEqual(logging.AUDIT, l.logger.getEffectiveLevel())
class JSONFormatterTestCase(test.TestCase):
def setUp(self):
super(JSONFormatterTestCase, self).setUp()
self.log = log.getLogger('test-json')
self.stream = cStringIO.StringIO()
handler = logging.StreamHandler(self.stream)
handler.setFormatter(log.JSONFormatter())
self.log.logger.addHandler(handler)
self.log.logger.setLevel(logging.DEBUG)
def test_json(self):
test_msg = 'This is a %(test)s line'
test_data = {'test': 'log'}
self.log.debug(test_msg, test_data)
data = jsonutils.loads(self.stream.getvalue())
self.assertTrue(data)
self.assertTrue('extra' in data)
self.assertEqual('test-json', data['name'])
self.assertEqual(test_msg % test_data, data['message'])
self.assertEqual(test_msg, data['msg'])
self.assertEqual(test_data, data['args'])
self.assertEqual('test_log.py', data['filename'])
self.assertEqual('test_json', data['funcname'])
self.assertEqual('DEBUG', data['levelname'])
self.assertEqual(logging.DEBUG, data['levelno'])
self.assertFalse(data['traceback'])
def test_json_exception(self):
test_msg = 'This is %s'
test_data = 'exceptional'
try:
raise Exception('This is exceptional')
except Exception:
self.log.exception(test_msg, test_data)
data = jsonutils.loads(self.stream.getvalue())
self.assertTrue(data)
self.assertTrue('extra' in data)
self.assertEqual('test-json', data['name'])
self.assertEqual(test_msg % test_data, data['message'])
self.assertEqual(test_msg, data['msg'])
self.assertEqual([test_data], data['args'])
self.assertEqual('ERROR', data['levelname'])
self.assertEqual(logging.ERROR, data['levelno'])
self.assertTrue(data['traceback'])

View File

@ -36,7 +36,7 @@ import sqlalchemy
import cinder.db.sqlalchemy.migrate_repo
import cinder.db.migration as migration
from cinder.db.sqlalchemy.migration import versioning_api as migration_api
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder import test
LOG = logging.getLogger('cinder.tests.test_migrations')

View File

@ -25,7 +25,7 @@ import StringIO
from lxml import etree
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder import test
from cinder.volume import netapp

View File

@ -15,7 +15,7 @@
import cinder
from cinder import flags
from cinder import log
from cinder.openstack.common import log as logging
import cinder.notifier.no_op_notifier
from cinder.notifier import api as notifier_api
from cinder import test
@ -98,8 +98,8 @@ class NotifierTestCase(test.TestCase):
self.stubs.Set(cinder.flags.FLAGS, 'notification_driver',
'cinder.notifier.rabbit_notifier')
self.stubs.Set(cinder.flags.FLAGS, 'publish_errors', True)
LOG = log.getLogger('cinder')
log.setup()
LOG = logging.getLogger('cinder')
logging.setup("cinder")
msgs = []
def mock_notify(context, topic, data):

View File

@ -21,6 +21,7 @@ Tests for Volume Code.
"""
import cStringIO
import logging
import mox
@ -28,7 +29,7 @@ from cinder import context
from cinder import exception
from cinder import db
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as os_logging
from cinder.openstack.common import importutils
from cinder.openstack.common import rpc
import cinder.policy
@ -36,7 +37,7 @@ from cinder import test
import cinder.volume.api
FLAGS = flags.FLAGS
LOG = logging.getLogger(__name__)
LOG = os_logging.getLogger(__name__)
class VolumeTestCase(test.TestCase):
@ -354,7 +355,7 @@ class DriverTestCase(test.TestCase):
log = logging.getLogger()
self.stream = cStringIO.StringIO()
log.logger.addHandler(logging.logging.StreamHandler(self.stream))
log.addHandler(logging.StreamHandler(self.stream))
def _attach_volume(self):
"""Attach volumes to an instance. This function also sets

View File

@ -21,7 +21,7 @@ import time
from cinder import context
from cinder import exception
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder import test
from cinder.volume import volume_types
from cinder.db.sqlalchemy import session as sql_session

View File

@ -50,7 +50,7 @@ import netaddr
from cinder import exception
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder.openstack.common import cfg
from cinder.openstack.common import excutils
from cinder.openstack.common import importutils

View File

@ -26,7 +26,7 @@ from eventlet import greenthread
from cinder import exception
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder.openstack.common import rpc
import cinder.policy
from cinder.openstack.common import timeutils

View File

@ -24,7 +24,7 @@ import time
from cinder import exception
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder.openstack.common import cfg
from cinder import utils
from cinder.volume import iscsi

View File

@ -41,7 +41,7 @@ intact.
from cinder import context
from cinder import exception
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder import manager
from cinder.openstack.common import cfg
from cinder.openstack.common import excutils

View File

@ -32,7 +32,7 @@ from suds.sax import text
from cinder import exception
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder.openstack.common import cfg
from cinder.volume import driver

View File

@ -26,7 +26,7 @@ import urllib2
from cinder.openstack.common import jsonutils
from cinder.volume import nexenta
from cinder import log as logging
from cinder.openstack.common import log as logging
LOG = logging.getLogger("cinder.volume.nexenta.jsonrpc")

View File

@ -24,7 +24,7 @@
from cinder import exception
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder.openstack.common import cfg
from cinder.volume import driver
from cinder.volume import nexenta

View File

@ -34,7 +34,7 @@ from lxml import etree
from cinder import exception
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder.openstack.common import cfg
from cinder.openstack.common import jsonutils
from cinder import utils

View File

@ -25,7 +25,7 @@ from cinder import context
from cinder import db
from cinder import exception
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
FLAGS = flags.FLAGS
LOG = logging.getLogger(__name__)

View File

@ -14,7 +14,7 @@
from cinder import exception
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder import utils
from cinder.virt.xenapi import connection as xenapi_conn
from cinder.virt.xenapi import volumeops

View File

@ -31,7 +31,7 @@ import webob.exc
from cinder import exception
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import log as logging
from cinder import utils

View File

@ -65,12 +65,12 @@ args = ('/dev/log', handlers.SysLogHandler.LOG_USER)
formatter = legacycinder
[handler_null]
class = cinder.log.NullHandler
class = cinder.common.openstack.NullHandler
formatter = default
args = ()
[formatter_legacycinder]
class = cinder.log.LegacyCinderFormatter
class = cinder.common.openstack.LegacyCinderFormatter
[formatter_default]
format = %(message)s

View File

@ -1,7 +1,7 @@
[DEFAULT]
# The list of modules to copy from openstack-common
modules=cfg,exception,excutils,gettextutils,importutils,iniparser,jsonutils,local,rpc,timeutils
modules=cfg,exception,excutils,gettextutils,importutils,iniparser,jsonutils,local,rpc,timeutils,log
# The base module to hold the copy of openstack.common
base=cinder