Add and use ceilometer own log module

This fixes bug #1004130

Change-Id: I143124ad411d5efefa604e831173dca87548bd7f
Signed-off-by: Julien Danjou <julien.danjou@enovance.com>
This commit is contained in:
Julien Danjou 2012-06-06 11:02:20 +02:00
parent 14c068d2e8
commit 8780157755
9 changed files with 180 additions and 30 deletions

View File

@ -23,13 +23,13 @@ eventlet.monkey_patch()
import sys
from nova import flags
from nova import log as logging
from nova import service
from nova import utils
from ceilometer import log
if __name__ == '__main__':
flags.parse_args(sys.argv)
logging.setup()
log.setup()
utils.monkey_patch()
server = \
service.Service.create(binary='ceilometer-agent',

View File

@ -23,13 +23,13 @@ eventlet.monkey_patch()
import sys
from nova import flags
from nova import log as logging
from nova import service
from nova import utils
from ceilometer import log
if __name__ == '__main__':
flags.parse_args(sys.argv)
logging.setup()
log.setup()
utils.monkey_patch()
server = \
service.Service.create(binary='ceilometer-collector',

View File

@ -18,18 +18,15 @@
import pkg_resources
from nova import log as logging
from nova import manager
from nova import rpc
from ceilometer import meter
from ceilometer import cfg
from ceilometer import log
# FIXME(dhellmann): We need to have the main program set up logging
# correctly so messages from modules outside of the nova package
# appear in the output.
LOG = logging.getLogger('nova.' + __name__)
LOG = log.getLogger(__name__)
COMPUTE_PLUGIN_NAMESPACE = 'ceilometer.poll.compute'

View File

@ -21,12 +21,9 @@ and publish the results.
import pkg_resources
from nova import log as logging
from ceilometer import log
# FIXME(dhellmann): We need to have the main program set up logging
# correctly so messages from modules outside of the nova package
# appear in the output.
LOG = logging.getLogger('nova.' + __name__)
LOG = log.getLogger(__name__)
class NotificationDispatcher(object):

View File

@ -18,12 +18,12 @@
from nova import context
from nova import flags
from nova import log as logging
from nova import manager
from nova import rpc as nova_rpc
from nova.rpc import dispatcher as rpc_dispatcher
from ceilometer import rpc
from ceilometer import log
from ceilometer import meter
from ceilometer import cfg
from ceilometer.collector import dispatcher
@ -33,10 +33,7 @@ from ceilometer.collector import dispatcher
import nova.notifier.rabbit_notifier
FLAGS = flags.FLAGS
# FIXME(dhellmann): We need to have the main program set up logging
# correctly so messages from modules outside of the nova package
# appear in the output.
LOG = logging.getLogger('nova.' + __name__)
LOG = log.getLogger(__name__)
COMPUTE_COLLECTOR_NAMESPACE = 'ceilometer.collector.compute'

View File

@ -20,19 +20,15 @@ import datetime
from lxml import etree
from nova import log as logging
from nova import flags
import nova.virt.connection
from .. import counter
from .. import plugin
from ceilometer import log
from ceilometer import counter
from ceilometer import plugin
FLAGS = flags.FLAGS
# FIXME(dhellmann): We need to have the main program set up logging
# correctly so messages from modules outside of the nova package
# appear in the output.
LOG = logging.getLogger('nova.' + __name__)
MIB = 2 ** 20 # mebibytes
@ -57,7 +53,7 @@ def make_counter_from_instance(instance, type, volume):
class DiskIOPollster(plugin.PollsterBase):
LOG = logging.getLogger('nova.' + __name__ + '.diskio')
LOG = log.getLogger(__name__ + '.diskio')
def _get_disks(self, conn, instance):
"""Get disks of an instance, only used to bypass bug#998089."""
@ -98,7 +94,7 @@ class DiskIOPollster(plugin.PollsterBase):
class CPUPollster(plugin.PollsterBase):
LOG = logging.getLogger('nova.' + __name__ + '.cpu')
LOG = log.getLogger(__name__ + '.cpu')
def get_counters(self, manager, context):
conn = nova.virt.connection.get_connection(read_only=True)

View File

@ -16,16 +16,17 @@
# License for the specific language governing permissions and limitations
# under the License.
from nova import log as logging
from nova import exception
from ceilometer import log
from .. import counter
from .. import plugin
class FloatingIPPollster(plugin.PollsterBase):
LOG = logging.getLogger('nova.' + __name__ + '.floatingip')
LOG = log.getLogger(__name__ + '.floatingip')
def get_counters(self, manager, context):
try:

98
ceilometer/log.py Normal file
View File

@ -0,0 +1,98 @@
# -*- encoding: utf-8 -*-
#
# Copyright © 2012 eNovance <licensing@enovance.com>
#
# Author: Julien Danjou <julien@danjou.info>
#
# 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.
import os
import inspect
import logging
import logging.config
import traceback
import sys
from ceilometer import cfg
cfg.CONF.register_opts([
cfg.StrOpt('log_config',
help='Log configuration file',
),
cfg.StrOpt('log_file',
help='Log file',
),
cfg.StrOpt('log_dir',
help='Log file directory',
),
cfg.StrOpt('log_level',
default="debug",
help='Log level',
),
cfg.StrOpt('logging_default_format_string',
default='%(asctime)s %(levelname)s %(name)s: %(message)s',
help='format string to use for log messages'),
])
def _get_binary_name():
return os.path.basename(inspect.stack()[-1][1])
def _get_log_file_path(binary=None):
if cfg.CONF.log_file and not cfg.CONF.log_dir:
return cfg.CONF.log_file
if cfg.CONF.log_file and cfg.CONF.log_dir:
return os.path.join(cfg.CONF.log_file,
cfg.CONF.log_file)
if cfg.CONF.log_dir:
binary = binary or _get_binary_name()
return '%s.log' % (os.path.join(cfg.CONF.log_dir, binary),)
def getLogger(name='ceilometer'):
return logging.getLogger(name)
def setup():
if cfg.CONF.log_config:
try:
logging.config.fileConfig(cfg.CONF.log_config)
except Exception:
traceback.print_exc()
raise
else:
root = getLogger()
for handler in root.handlers:
root.removeHandler(handler)
logpath = _get_log_file_path()
if logpath:
filelog = logging.handlers.WatchedFileHandler(logpath)
filelog.setFormatter(
logging.Formatter(cfg.CONF.logging_default_format_string))
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)
else:
streamlog = logging.StreamHandler(sys.stdout)
streamlog.setFormatter(
logging.Formatter(cfg.CONF.logging_default_format_string))
root.addHandler(streamlog)
if cfg.CONF.log_level:
root.setLevel(logging.getLevelName(cfg.CONF.log_level.upper()))

64
tests/test_log.py Normal file
View File

@ -0,0 +1,64 @@
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
#
# Copyright © 2012 eNovance <licensing@enovance.com>
#
# Author: Julien Danjou <julien@danjou.info>
#
# 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.
import unittest
import logging
from ceilometer import log
from ceilometer import cfg
class LoggerTestCase(unittest.TestCase):
def setUp(self):
super(LoggerTestCase, self).setUp()
self.log = log.getLogger()
def test_log_level(self):
cfg.CONF.log_level = "info"
log.setup()
self.assertEqual(logging.INFO, self.log.getEffectiveLevel())
def test_child_log_level(self):
cfg.CONF.log_level = "info"
log.setup()
self.assertEqual(logging.INFO, log.getLogger('ceilometer.foobar').getEffectiveLevel())
class LogfilePathTestCase(unittest.TestCase):
def test_log_path_logdir(self):
cfg.CONF.log_dir = '/some/path'
cfg.CONF.log_file = None
self.assertEquals(log._get_log_file_path(binary='foo-bar'),
'/some/path/foo-bar.log')
def test_log_path_logfile(self):
cfg.CONF.log_file = '/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):
cfg.CONF.log_dir = None
cfg.CONF.log_file = None
self.assertTrue(log._get_log_file_path(binary='foo-bar') is None)
def test_log_path_logfile_overrides_logdir(self):
cfg.CONF.log_dir = '/some/other/path'
cfg.CONF.log_file = '/some/path/foo-bar.log'
self.assertEquals(log._get_log_file_path(binary='foo-bar'),
'/some/path/foo-bar.log')