Remove statds from the logs module
We would like to remove any Statsd related code from logs.py. That requires that SwiftLogAdapter no longer provides a StatsdClient interface by default. However, for backwards compatibility the main utils.get_logger/get_prefixed_logger entrypoints must provide a SwiftLogAdapter that does have a StatdsClient interface. The new utils._patch_statsd_methods helper function is therefore used to retrospectively patch a SwiftLogAdapter instance with the StatsdClient interface when necessary. The _patch_statsd_helper is used in get_logger, and again when we clone a logger in get_prefixed_logger. Co-Authored-By: Shreeya Deshpande <shreeyad@nvidia.com> Change-Id: I44694b92264066ca427bb96456d6f944e09b31c0
This commit is contained in:
parent
ffbf17e47c
commit
8699af83c9
@ -30,10 +30,10 @@ from swift.common.exceptions import LockTimeout
|
||||
from swift.common.storage_policy import POLICIES
|
||||
from swift.common.utils import replace_partition_in_path, config_true_value, \
|
||||
audit_location_generator, get_logger, readconf, drop_privileges, \
|
||||
RateLimitedIterator, distribute_evenly, \
|
||||
RateLimitedIterator, distribute_evenly, get_prefixed_logger, \
|
||||
non_negative_float, non_negative_int, config_auto_int_value, \
|
||||
dump_recon_cache, get_partition_from_path, get_hub
|
||||
from swift.common.utils.logs import SwiftLogAdapter, get_prefixed_logger
|
||||
from swift.common.utils.logs import SwiftLogAdapter
|
||||
from swift.obj import diskfile
|
||||
from swift.common.recon import RECON_RELINKER_FILE, DEFAULT_RECON_CACHE_PATH
|
||||
|
||||
|
@ -87,8 +87,8 @@ from .base import ( # noqa
|
||||
from swift.common.utils.logs import ( # noqa
|
||||
SysLogHandler, # t.u.helpers.setup_servers monkey patch is sketch
|
||||
logging_monkey_patch,
|
||||
get_logger,
|
||||
get_prefixed_logger,
|
||||
get_swift_logger,
|
||||
get_prefixed_swift_logger,
|
||||
LogLevelFilter,
|
||||
NullLogger,
|
||||
capture_stdio,
|
||||
@ -157,7 +157,7 @@ from swift.common.utils.ipaddrs import ( # noqa
|
||||
parse_socket_string,
|
||||
whataremyips,
|
||||
)
|
||||
from swift.common.statsd_client import StatsdClient # noqa
|
||||
from swift.common.statsd_client import StatsdClient, get_statsd_client
|
||||
import logging
|
||||
|
||||
EUCLEAN = getattr(errno, 'EUCLEAN', 117) # otherwise not present on osx
|
||||
@ -205,6 +205,140 @@ DEFAULT_LOCK_TIMEOUT = 10
|
||||
DEFAULT_DRAIN_LIMIT = 65536
|
||||
|
||||
|
||||
def _patch_statsd_methods(target, statsd_client_source):
|
||||
"""
|
||||
Note: this function is only used to create backwards compatible
|
||||
legacy "hybrid" loggers that also have a StatsdClient interface.
|
||||
It should not otherwise be used to patch arbitrary objects to
|
||||
have a StatsdClient interface.
|
||||
|
||||
Patch the ``target`` object with methods that present an interface to a
|
||||
``StatsdClient`` instance that is an attribute ``statsd_client`` of
|
||||
``statsd_client_source``.
|
||||
|
||||
Note: ``statsd_client_source`` is an object that *has a* ``StatsdClient``
|
||||
and not an object that *is a* ``StatsdClient`` instance, because the
|
||||
actual ``StatsdClient`` instance may change. The patched target
|
||||
therefore forwards its methods to whatever instance of ``StatsdClient``
|
||||
the ``statsd_client_source`` currently has.
|
||||
|
||||
:param target: an object that will be patched to present an interface to a
|
||||
``StatsdClient``.
|
||||
:param statsd_client_source: an object that must have an attribute
|
||||
``statsd_client`` that must be an instance of a ``StatsdClient``.
|
||||
This is typically a core ``logging.Logger`` that has been patched with
|
||||
a ``StatsdClient`` by ``get_logger()``.
|
||||
"""
|
||||
try:
|
||||
if not isinstance(statsd_client_source.statsd_client, StatsdClient):
|
||||
raise ValueError()
|
||||
except (AttributeError, ValueError):
|
||||
raise ValueError(
|
||||
'statsd_client_source must have a statsd_client attribute')
|
||||
|
||||
def set_statsd_prefix(prefix):
|
||||
"""
|
||||
This method is deprecated. Callers should use the
|
||||
``statsd_tail_prefix`` argument of ``get_logger`` when instantiating a
|
||||
logger.
|
||||
|
||||
The StatsD client prefix defaults to the "name" of the logger. This
|
||||
method may override that default with a specific value. Currently used
|
||||
in the proxy-server to differentiate the Account, Container, and Object
|
||||
controllers.
|
||||
"""
|
||||
warnings.warn(
|
||||
'set_statsd_prefix() is deprecated; use the '
|
||||
'``statsd_tail_prefix`` argument to ``get_logger`` instead.',
|
||||
DeprecationWarning, stacklevel=2
|
||||
)
|
||||
if getattr(statsd_client_source, 'statsd_client'):
|
||||
statsd_client_source.statsd_client._set_prefix(prefix)
|
||||
|
||||
def statsd_delegate(statsd_func_name):
|
||||
"""
|
||||
Factory to create methods which delegate to methods on
|
||||
``statsd_client_source.statsd_client`` (an instance of StatsdClient).
|
||||
The created methods conditionally delegate to a method whose name is
|
||||
given in 'statsd_func_name'. The created delegate methods are a no-op
|
||||
when StatsD logging is not configured.
|
||||
|
||||
:param statsd_func_name: the name of a method on ``StatsdClient``.
|
||||
"""
|
||||
func = getattr(StatsdClient, statsd_func_name)
|
||||
|
||||
@functools.wraps(func)
|
||||
def wrapped(*a, **kw):
|
||||
if getattr(statsd_client_source, 'statsd_client'):
|
||||
func = getattr(statsd_client_source.statsd_client,
|
||||
statsd_func_name)
|
||||
return func(*a, **kw)
|
||||
return wrapped
|
||||
|
||||
target.update_stats = statsd_delegate('update_stats')
|
||||
target.increment = statsd_delegate('increment')
|
||||
target.decrement = statsd_delegate('decrement')
|
||||
target.timing = statsd_delegate('timing')
|
||||
target.timing_since = statsd_delegate('timing_since')
|
||||
target.transfer_rate = statsd_delegate('transfer_rate')
|
||||
target.set_statsd_prefix = set_statsd_prefix
|
||||
target.statsd_client_source = statsd_client_source
|
||||
|
||||
|
||||
def get_logger(conf, name=None, log_to_console=False, log_route=None,
|
||||
fmt="%(server)s: %(message)s", statsd_tail_prefix=None):
|
||||
"""
|
||||
Returns a ``SwiftLogAdapter`` that has been patched to also provide an
|
||||
interface to a ``StatsdClient``.
|
||||
|
||||
:param conf: Configuration dict to read settings from
|
||||
:param name: This value is used to populate the ``server`` field in the log
|
||||
format, as the prefix for statsd messages, and as the default
|
||||
value for ``log_route``; defaults to the ``log_name`` value in
|
||||
``conf``, if it exists, or to 'swift'.
|
||||
:param log_to_console: Add handler which writes to console on stderr.
|
||||
:param log_route: Route for the logging, not emitted to the log, just used
|
||||
to separate logging configurations; defaults to the value
|
||||
of ``name`` or whatever ``name`` defaults to. This value
|
||||
is used as the name attribute of the
|
||||
``SwiftLogAdapter`` that is returned.
|
||||
:param fmt: Override log format.
|
||||
:param statsd_tail_prefix: tail prefix to pass to ``StatsdClient``; if None
|
||||
then the tail prefix defaults to the value of ``name``.
|
||||
:return: an instance of ``SwiftLogAdapter``.
|
||||
"""
|
||||
conf = conf or {}
|
||||
swift_logger = get_swift_logger(
|
||||
conf, name, log_to_console, log_route, fmt)
|
||||
name = conf.get('log_name', 'swift') if name is None else name
|
||||
tail_prefix = name if statsd_tail_prefix is None else statsd_tail_prefix
|
||||
statsd_client = get_statsd_client(conf, tail_prefix, swift_logger.logger)
|
||||
swift_logger.logger.statsd_client = statsd_client
|
||||
_patch_statsd_methods(swift_logger, swift_logger.logger)
|
||||
return swift_logger
|
||||
|
||||
|
||||
def get_prefixed_logger(swift_logger, prefix):
|
||||
"""
|
||||
Return a clone of the given ``swift_logger`` with a new prefix string
|
||||
that replaces the prefix string of the given ``swift_logger``
|
||||
|
||||
If the given ``swift_logger`` has been patched with an interface to a
|
||||
``StatsdClient`` instance then the returned ``SwiftLogAdapter`` will also
|
||||
be patched with an interface to the same ``StatsdClient`` instance.
|
||||
|
||||
:param swift_logger: an instance of ``SwiftLogAdapter``.
|
||||
:param prefix: a string prefix.
|
||||
:returns: a new instance of ``SwiftLogAdapter``.
|
||||
"""
|
||||
new_logger = get_prefixed_swift_logger(swift_logger, prefix=prefix)
|
||||
if hasattr(swift_logger, 'statsd_client_source'):
|
||||
if getattr(swift_logger.statsd_client_source, 'statsd_client'):
|
||||
_patch_statsd_methods(
|
||||
new_logger, swift_logger.statsd_client_source)
|
||||
return new_logger
|
||||
|
||||
|
||||
class InvalidHashPathConfigError(ValueError):
|
||||
|
||||
def __str__(self):
|
||||
|
@ -24,9 +24,7 @@ import socket
|
||||
import stat
|
||||
import string
|
||||
import sys
|
||||
import functools
|
||||
import time
|
||||
import warnings
|
||||
import fcntl
|
||||
import eventlet
|
||||
import six
|
||||
@ -35,7 +33,6 @@ import datetime
|
||||
from swift.common.utils.base import md5, quote, split_path
|
||||
from swift.common.utils.timestamp import UTC
|
||||
from swift.common.utils.config import config_true_value
|
||||
from swift.common import statsd_client
|
||||
# common.utils imports a fully qualified common.exceptions so that
|
||||
# common.exceptions can import common.utils with out a circular import error
|
||||
# (if we only make reference to attributes of a module w/i our function/method
|
||||
@ -175,13 +172,13 @@ class PipeMutex(object):
|
||||
|
||||
def __del__(self):
|
||||
# We need this so we don't leak file descriptors. Otherwise, if you
|
||||
# call get_logger() and don't explicitly dispose of it by calling
|
||||
# call get_swift_logger() and don't explicitly dispose of it by calling
|
||||
# logger.logger.handlers[0].lock.close() [1], the pipe file
|
||||
# descriptors are leaked.
|
||||
#
|
||||
# This only really comes up in tests. Swift processes tend to call
|
||||
# get_logger() once and then hang on to it until they exit, but the
|
||||
# test suite calls get_logger() a lot.
|
||||
# get_swift_logger() once and then hang on to it until they exit,
|
||||
# but the test suite calls get_swift_logger() a lot.
|
||||
#
|
||||
# [1] and that's a completely ridiculous thing to expect callers to
|
||||
# do, so nobody does it and that's okay.
|
||||
@ -294,6 +291,7 @@ class SwiftLogAdapter(logging.LoggerAdapter, object):
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
# py3 does this for us already; add it for py2
|
||||
return self.logger.name
|
||||
|
||||
@property
|
||||
@ -389,52 +387,6 @@ class SwiftLogAdapter(logging.LoggerAdapter, object):
|
||||
call = self._exception
|
||||
call('%s: %s' % (msg, emsg), *args, **kwargs)
|
||||
|
||||
def set_statsd_prefix(self, prefix):
|
||||
"""
|
||||
This method is deprecated. Callers should use the
|
||||
``statsd_tail_prefix`` argument of ``get_logger`` when instantiating a
|
||||
logger.
|
||||
|
||||
The StatsD client prefix defaults to the "name" of the logger. This
|
||||
method may override that default with a specific value. Currently used
|
||||
in the proxy-server to differentiate the Account, Container, and Object
|
||||
controllers.
|
||||
"""
|
||||
warnings.warn(
|
||||
'set_statsd_prefix() is deprecated; use the '
|
||||
'``statsd_tail_prefix`` argument to ``get_logger`` instead.',
|
||||
DeprecationWarning, stacklevel=2
|
||||
)
|
||||
if self.logger.statsd_client:
|
||||
self.logger.statsd_client._set_prefix(prefix)
|
||||
|
||||
def statsd_delegate(statsd_func_name):
|
||||
"""
|
||||
Factory to create methods which delegate to methods on
|
||||
self.logger.statsd_client (an instance of StatsdClient). The
|
||||
created methods conditionally delegate to a method whose name is given
|
||||
in 'statsd_func_name'. The created delegate methods are a no-op when
|
||||
StatsD logging is not configured.
|
||||
|
||||
:param statsd_func_name: the name of a method on StatsdClient.
|
||||
"""
|
||||
func = getattr(statsd_client.StatsdClient, statsd_func_name)
|
||||
|
||||
@functools.wraps(func)
|
||||
def wrapped(self, *a, **kw):
|
||||
if getattr(self.logger, 'statsd_client'):
|
||||
func = getattr(self.logger.statsd_client, statsd_func_name)
|
||||
return func(*a, **kw)
|
||||
|
||||
return wrapped
|
||||
|
||||
update_stats = statsd_delegate('update_stats')
|
||||
increment = statsd_delegate('increment')
|
||||
decrement = statsd_delegate('decrement')
|
||||
timing = statsd_delegate('timing')
|
||||
timing_since = statsd_delegate('timing_since')
|
||||
transfer_rate = statsd_delegate('transfer_rate')
|
||||
|
||||
|
||||
class SwiftLogFormatter(logging.Formatter):
|
||||
"""
|
||||
@ -588,8 +540,8 @@ class LogLevelFilter(object):
|
||||
return 1
|
||||
|
||||
|
||||
def get_logger(conf, name=None, log_to_console=False, log_route=None,
|
||||
fmt="%(server)s: %(message)s", statsd_tail_prefix=None):
|
||||
def get_swift_logger(conf, name=None, log_to_console=False, log_route=None,
|
||||
fmt="%(server)s: %(message)s"):
|
||||
"""
|
||||
Get the current system logger using config settings.
|
||||
|
||||
@ -604,10 +556,10 @@ def get_logger(conf, name=None, log_to_console=False, log_route=None,
|
||||
log_address = /dev/log
|
||||
|
||||
:param conf: Configuration dict to read settings from
|
||||
:param name: This value is used to populate the ``server`` field in the log
|
||||
format, as the prefix for statsd messages, and as the default
|
||||
value for ``log_route``; defaults to the ``log_name`` value in
|
||||
``conf``, if it exists, or to 'swift'.
|
||||
:param name: This value is used to populate the ``server`` field in
|
||||
the log format, as the default value for ``log_route``;
|
||||
defaults to the ``log_name`` value in ``conf``, if it exists,
|
||||
or to 'swift'.
|
||||
:param log_to_console: Add handler which writes to console on stderr
|
||||
:param log_route: Route for the logging, not emitted to the log, just used
|
||||
to separate logging configurations; defaults to the value
|
||||
@ -615,13 +567,11 @@ def get_logger(conf, name=None, log_to_console=False, log_route=None,
|
||||
is used as the name attribute of the
|
||||
``logging.LogAdapter`` that is returned.
|
||||
:param fmt: Override log format
|
||||
:param statsd_tail_prefix: tail prefix to pass to statsd client; if None
|
||||
then the tail prefix defaults to the value of ``name``.
|
||||
:return: an instance of ``LogAdapter``
|
||||
:return: an instance of ``SwiftLogAdapter``
|
||||
"""
|
||||
# note: log_name is typically specified in conf (i.e. defined by
|
||||
# operators), whereas log_route is typically hard-coded in callers of
|
||||
# get_logger (i.e. defined by developers)
|
||||
# get_swift_logger (i.e. defined by developers)
|
||||
if not conf:
|
||||
conf = {}
|
||||
if name is None:
|
||||
@ -634,11 +584,11 @@ def get_logger(conf, name=None, log_to_console=False, log_route=None,
|
||||
formatter = SwiftLogFormatter(
|
||||
fmt=fmt, max_line_length=int(conf.get('log_max_line_length', 0)))
|
||||
|
||||
# get_logger will only ever add one SysLog Handler to a logger
|
||||
if not hasattr(get_logger, 'handler4logger'):
|
||||
get_logger.handler4logger = {}
|
||||
if logger in get_logger.handler4logger:
|
||||
logger.removeHandler(get_logger.handler4logger[logger])
|
||||
# get_swift_logger will only ever add one SysLog Handler to a logger
|
||||
if not hasattr(get_swift_logger, 'handler4logger'):
|
||||
get_swift_logger.handler4logger = {}
|
||||
if logger in get_swift_logger.handler4logger:
|
||||
logger.removeHandler(get_swift_logger.handler4logger[logger])
|
||||
|
||||
# facility for this logger will be set by last call wins
|
||||
facility = getattr(SysLogHandler, conf.get('log_facility', 'LOG_LOCAL0'),
|
||||
@ -667,31 +617,26 @@ def get_logger(conf, name=None, log_to_console=False, log_route=None,
|
||||
handler = ThreadSafeSysLogHandler(facility=facility)
|
||||
handler.setFormatter(formatter)
|
||||
logger.addHandler(handler)
|
||||
get_logger.handler4logger[logger] = handler
|
||||
get_swift_logger.handler4logger[logger] = handler
|
||||
|
||||
# setup console logging
|
||||
if log_to_console or hasattr(get_logger, 'console_handler4logger'):
|
||||
if log_to_console or hasattr(get_swift_logger, 'console_handler4logger'):
|
||||
# remove pre-existing console handler for this logger
|
||||
if not hasattr(get_logger, 'console_handler4logger'):
|
||||
get_logger.console_handler4logger = {}
|
||||
if logger in get_logger.console_handler4logger:
|
||||
logger.removeHandler(get_logger.console_handler4logger[logger])
|
||||
if not hasattr(get_swift_logger, 'console_handler4logger'):
|
||||
get_swift_logger.console_handler4logger = {}
|
||||
if logger in get_swift_logger.console_handler4logger:
|
||||
logger.removeHandler(
|
||||
get_swift_logger.console_handler4logger[logger])
|
||||
|
||||
console_handler = logging.StreamHandler(sys.__stderr__)
|
||||
console_handler.setFormatter(formatter)
|
||||
logger.addHandler(console_handler)
|
||||
get_logger.console_handler4logger[logger] = console_handler
|
||||
get_swift_logger.console_handler4logger[logger] = console_handler
|
||||
|
||||
# set the level for the logger
|
||||
logger.setLevel(
|
||||
getattr(logging, conf.get('log_level', 'INFO').upper(), logging.INFO))
|
||||
|
||||
# Setup logger with a StatsD client if so configured
|
||||
if statsd_tail_prefix is None:
|
||||
statsd_tail_prefix = name
|
||||
logger.statsd_client = statsd_client.get_statsd_client(
|
||||
conf, statsd_tail_prefix, logger)
|
||||
|
||||
adapted_logger = SwiftLogAdapter(logger, name)
|
||||
other_handlers = conf.get('log_custom_handlers', None)
|
||||
if other_handlers:
|
||||
@ -713,7 +658,15 @@ def get_logger(conf, name=None, log_to_console=False, log_route=None,
|
||||
return adapted_logger
|
||||
|
||||
|
||||
def get_prefixed_logger(swift_logger, prefix):
|
||||
def get_prefixed_swift_logger(swift_logger, prefix):
|
||||
"""
|
||||
Return a clone of the given ``swift_logger`` with a new prefix string
|
||||
that replaces the prefix string of the given ``swift_logger``.
|
||||
|
||||
:param swift_logger: an instance of ``SwiftLogAdapter``.
|
||||
:param prefix: a string prefix.
|
||||
:returns: a new instance of ``SwiftLogAdapter``.
|
||||
"""
|
||||
return SwiftLogAdapter(
|
||||
swift_logger.logger, swift_logger.server, prefix=prefix)
|
||||
|
||||
@ -760,7 +713,7 @@ def capture_stdio(logger, **kwargs):
|
||||
# collect stdio file desc not in use for logging
|
||||
stdio_files = [sys.stdin, sys.stdout, sys.stderr]
|
||||
console_fds = [h.stream.fileno() for _junk, h in getattr(
|
||||
get_logger, 'console_handler4logger', {}).items()]
|
||||
get_swift_logger, 'console_handler4logger', {}).items()]
|
||||
stdio_files = [f for f in stdio_files if f.fileno() not in console_fds]
|
||||
|
||||
with open(os.devnull, 'r+b') as nullfile:
|
||||
|
@ -272,7 +272,9 @@ class DebugLogAdapter(utils.logs.SwiftLogAdapter):
|
||||
|
||||
def debug_logger(name='test'):
|
||||
"""get a named adapted debug logger"""
|
||||
return DebugLogAdapter(DebugLogger(), name)
|
||||
adapted_logger = DebugLogAdapter(DebugLogger(), name)
|
||||
utils._patch_statsd_methods(adapted_logger, adapted_logger.logger)
|
||||
return adapted_logger
|
||||
|
||||
|
||||
class ForwardingLogHandler(logging.NullHandler):
|
||||
@ -327,7 +329,7 @@ def capture_logger(conf, *args, **kwargs):
|
||||
"""
|
||||
with mock.patch('swift.common.utils.logs.SwiftLogAdapter',
|
||||
CaptureLogAdapter):
|
||||
log_adapter = utils.logs.get_logger(conf, *args, **kwargs)
|
||||
log_adapter = utils.get_logger(conf, *args, **kwargs)
|
||||
log_adapter.start_capture()
|
||||
try:
|
||||
yield log_adapter
|
||||
|
@ -23,7 +23,7 @@ from logging.handlers import SysLogHandler
|
||||
import six
|
||||
from six.moves.urllib.parse import unquote
|
||||
|
||||
from swift.common.utils import get_logger, split_path
|
||||
from swift.common.utils import get_swift_logger, split_path
|
||||
from swift.common.statsd_client import StatsdClient
|
||||
from swift.common.middleware import proxy_logging
|
||||
from swift.common.registry import register_sensitive_header, \
|
||||
@ -969,7 +969,7 @@ class TestProxyLogging(unittest.TestCase):
|
||||
FakeApp(),
|
||||
{'log_headers': 'yes',
|
||||
'access_log_facility': 'LOG_LOCAL7'})
|
||||
handler = get_logger.handler4logger[app.access_logger.logger]
|
||||
handler = get_swift_logger.handler4logger[app.access_logger.logger]
|
||||
self.assertEqual(SysLogHandler.LOG_LOCAL7, handler.facility)
|
||||
|
||||
def test_filter(self):
|
||||
|
@ -819,39 +819,3 @@ class TestModuleFunctions(unittest.TestCase):
|
||||
self.assertEqual(self.logger, client.logger)
|
||||
warn_lines = self.logger.get_lines_for_level('warning')
|
||||
self.assertEqual([], warn_lines)
|
||||
|
||||
|
||||
class TestSwiftLogAdapterDelegation(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.logger = utils.get_logger({'log_statsd_host': 'some.host.com'},
|
||||
'some-name', log_route='some-route')
|
||||
self.mock_socket = MockUdpSocket()
|
||||
self.logger.logger.statsd_client._open_socket = \
|
||||
lambda *_: self.mock_socket
|
||||
self.address = ('some.host.com', 8125)
|
||||
|
||||
def test_setup(self):
|
||||
self.logger.increment('foo')
|
||||
self.assertEqual(self.mock_socket.sent,
|
||||
[(b'some-name.foo:1|c', self.address)])
|
||||
|
||||
def test_get_prefix_logger(self):
|
||||
prefixed_logger = utils.get_prefixed_logger(self.logger, 'my-prefix')
|
||||
prefixed_logger.increment('bar')
|
||||
self.assertEqual(self.mock_socket.sent,
|
||||
[(b'some-name.bar:1|c', self.address)])
|
||||
|
||||
def test_adapted_logger(self):
|
||||
adapted_logger = utils.logs.SwiftLogAdapter(
|
||||
self.logger.logger, 'my-adapter')
|
||||
adapted_logger.increment('buz')
|
||||
self.assertEqual(self.mock_socket.sent,
|
||||
[(b'some-name.buz:1|c', self.address)])
|
||||
|
||||
def test_wrapped_adapter(self):
|
||||
wrapped_adapter = utils.logs.SwiftLogAdapter(
|
||||
self.logger, 'wrapped-adapter')
|
||||
with self.assertRaises(AttributeError) as ctx:
|
||||
wrapped_adapter.increment('baz')
|
||||
self.assertIn("has no attribute 'statsd_client'", str(ctx.exception))
|
||||
|
@ -16,10 +16,11 @@
|
||||
"""Tests for swift.common.utils"""
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import itertools
|
||||
|
||||
from test.debug_logger import debug_logger
|
||||
from test.debug_logger import debug_logger, FakeStatsdClient
|
||||
from test.unit import temptree, make_timestamp_iter, with_tempdir, \
|
||||
mock_timestamp_now, FakeIterable
|
||||
|
||||
@ -7367,3 +7368,283 @@ class TestContextPool(unittest.TestCase):
|
||||
self.assertEqual(pool.running(), size)
|
||||
pool.close()
|
||||
self.assertEqual(pool.running(), 0)
|
||||
|
||||
|
||||
class TestLoggerStatsdClientDelegation(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.logger_name = 'server'
|
||||
|
||||
def tearDown(self):
|
||||
# Avoid test coupling by removing any StatsdClient instance
|
||||
# that may have been patched on to a Logger.
|
||||
core_logger = logging.getLogger(self.logger_name)
|
||||
if hasattr(core_logger, 'statsd_client'):
|
||||
del core_logger.statsd_client
|
||||
|
||||
def test_patch_statsd_methods(self):
|
||||
client = FakeStatsdClient('host.com', 1234)
|
||||
source = argparse.Namespace()
|
||||
source.statsd_client = client
|
||||
|
||||
target = argparse.Namespace()
|
||||
utils._patch_statsd_methods(target, source)
|
||||
target.increment('a')
|
||||
target.decrement('b')
|
||||
target.update_stats('c', 4)
|
||||
target.timing('d', 23.4)
|
||||
target.timing_since('e', 23.4)
|
||||
target.transfer_rate('f', 56.7, 1234.5)
|
||||
exp = {
|
||||
'decrement': [(('b',), {})],
|
||||
'increment': [(('a',), {})],
|
||||
'timing': [(('d', 23.4), {}),
|
||||
(('f', 45929.52612393682, None), {})],
|
||||
'timing_since': [(('e', 23.4), {})],
|
||||
'transfer_rate': [(('f', 56.7, 1234.5), {})],
|
||||
'update_stats': [(('a', 1, None), {}),
|
||||
(('b', -1, None), {}),
|
||||
(('c', 4), {})]
|
||||
}
|
||||
self.assertEqual(exp, client.calls)
|
||||
|
||||
def test_patch_statsd_methods_source_is_none(self):
|
||||
with self.assertRaises(ValueError) as cm:
|
||||
utils._patch_statsd_methods(object, None)
|
||||
self.assertEqual(
|
||||
'statsd_client_source must have a statsd_client attribute',
|
||||
str(cm.exception))
|
||||
|
||||
def test_patch_statsd_methods_source_no_statsd_client(self):
|
||||
source = argparse.Namespace()
|
||||
with self.assertRaises(ValueError) as cm:
|
||||
utils._patch_statsd_methods(object, source)
|
||||
self.assertEqual(
|
||||
'statsd_client_source must have a statsd_client attribute',
|
||||
str(cm.exception))
|
||||
|
||||
def test_patch_statsd_methods_source_statsd_client_is_none(self):
|
||||
source = argparse.Namespace()
|
||||
source.statsd_client = None
|
||||
with self.assertRaises(ValueError) as cm:
|
||||
utils._patch_statsd_methods(object, source)
|
||||
self.assertEqual(
|
||||
'statsd_client_source must have a statsd_client attribute',
|
||||
str(cm.exception))
|
||||
|
||||
def test_patch_statsd_methods_client_deleted_from_source(self):
|
||||
client = FakeStatsdClient('host.com', 1234)
|
||||
source = argparse.Namespace()
|
||||
source.statsd_client = client
|
||||
target = argparse.Namespace()
|
||||
utils._patch_statsd_methods(target, source)
|
||||
target.increment('a')
|
||||
exp = {
|
||||
'increment': [(('a',), {})],
|
||||
'update_stats': [(('a', 1, None), {})],
|
||||
}
|
||||
self.assertEqual(exp, client.calls)
|
||||
|
||||
# if the statsd_client is deleted you will blow up...
|
||||
del source.statsd_client
|
||||
try:
|
||||
target.increment('b')
|
||||
except AttributeError as err:
|
||||
self.assertEqual(
|
||||
str(err),
|
||||
"'Namespace' object has no attribute 'statsd_client'")
|
||||
|
||||
def test_get_logger_provides_a_swift_log_adapter(self):
|
||||
orig_get_swift_logger = utils.logs.get_swift_logger
|
||||
calls = []
|
||||
|
||||
def fake_get_swift_logger(*args, **kwargs):
|
||||
result = orig_get_swift_logger(*args, **kwargs)
|
||||
calls.append((args, kwargs, result))
|
||||
return result
|
||||
|
||||
conf = {}
|
||||
fmt = 'test %(message)s'
|
||||
with mock.patch(
|
||||
'swift.common.utils.get_swift_logger', fake_get_swift_logger):
|
||||
logger = utils.get_logger(
|
||||
conf, name=self.logger_name, log_to_console=True,
|
||||
log_route='test', fmt=fmt)
|
||||
self.assertEqual(1, len(calls))
|
||||
self.assertEqual(
|
||||
((conf, self.logger_name, True, 'test', fmt), {}),
|
||||
calls[0][:2])
|
||||
self.assertIs(calls[0][2], logger)
|
||||
|
||||
def test_get_logger_provides_statsd_client(self):
|
||||
with mock.patch(
|
||||
'swift.common.statsd_client.StatsdClient', FakeStatsdClient):
|
||||
swift_logger = utils.get_logger(None, name=self.logger_name)
|
||||
self.assertTrue(hasattr(swift_logger.logger, 'statsd_client'))
|
||||
self.assertIsInstance(swift_logger.logger.statsd_client,
|
||||
FakeStatsdClient)
|
||||
swift_logger.increment('a')
|
||||
swift_logger.decrement('b')
|
||||
swift_logger.update_stats('c', 4)
|
||||
swift_logger.timing('d', 23.4)
|
||||
swift_logger.timing_since('e', 23.4)
|
||||
swift_logger.transfer_rate('f', 56.7, 1234.5)
|
||||
exp = {
|
||||
'decrement': [(('b',), {})],
|
||||
'increment': [(('a',), {})],
|
||||
'timing': [(('d', 23.4), {}),
|
||||
(('f', 45929.52612393682, None), {})],
|
||||
'timing_since': [(('e', 23.4), {})],
|
||||
'transfer_rate': [(('f', 56.7, 1234.5), {})],
|
||||
'update_stats': [(('a', 1, None), {}),
|
||||
(('b', -1, None), {}),
|
||||
(('c', 4), {})]
|
||||
}
|
||||
self.assertTrue(hasattr(swift_logger.logger, 'statsd_client'))
|
||||
client = swift_logger.logger.statsd_client
|
||||
self.assertEqual(exp, client.calls)
|
||||
|
||||
def test_get_logger_statsd_client_prefix(self):
|
||||
def call_get_logger(conf, name, statsd_tail_prefix):
|
||||
with mock.patch('swift.common.statsd_client.StatsdClient',
|
||||
FakeStatsdClient):
|
||||
swift_logger = utils.get_logger(
|
||||
conf, name=name, statsd_tail_prefix=statsd_tail_prefix)
|
||||
self.assertTrue(hasattr(swift_logger.logger, 'statsd_client'))
|
||||
self.assertIsInstance(swift_logger.logger.statsd_client,
|
||||
FakeStatsdClient)
|
||||
return swift_logger.logger.statsd_client
|
||||
|
||||
# tail prefix defaults to swift
|
||||
statsd_client = call_get_logger(None, None, None)
|
||||
self.assertEqual('swift.', statsd_client._prefix)
|
||||
|
||||
# tail prefix defaults to conf log_name
|
||||
conf = {'log_name': 'bar'}
|
||||
statsd_client = call_get_logger(conf, None, None)
|
||||
self.assertEqual('bar.', statsd_client._prefix)
|
||||
|
||||
# tail prefix defaults to name arg which overrides conf log_name
|
||||
statsd_client = call_get_logger(conf, '', None)
|
||||
self.assertEqual('', statsd_client._prefix)
|
||||
|
||||
# tail prefix defaults to name arg which overrides conf log_name
|
||||
statsd_client = call_get_logger(conf, 'baz', None)
|
||||
self.assertEqual('baz.', statsd_client._prefix)
|
||||
|
||||
# tail prefix set to statsd_tail_prefix arg which overrides name arg
|
||||
statsd_client = call_get_logger(conf, 'baz', '')
|
||||
self.assertEqual('', statsd_client._prefix)
|
||||
|
||||
# tail prefix set to statsd_tail_prefix arg which overrides name arg
|
||||
statsd_client = call_get_logger(conf, 'baz', 'boo')
|
||||
self.assertEqual('boo.', statsd_client._prefix)
|
||||
|
||||
# base prefix is configured, tail prefix defaults to swift
|
||||
conf = {'log_statsd_metric_prefix': 'foo'}
|
||||
statsd_client = call_get_logger(conf, None, None)
|
||||
self.assertEqual('foo.swift.', statsd_client._prefix)
|
||||
|
||||
# base prefix is configured, tail prefix defaults to conf log_name
|
||||
conf = {'log_statsd_metric_prefix': 'foo', 'log_name': 'bar'}
|
||||
statsd_client = call_get_logger(conf, None, None)
|
||||
self.assertEqual('foo.bar.', statsd_client._prefix)
|
||||
|
||||
# base prefix is configured, tail prefix defaults to name arg
|
||||
statsd_client = call_get_logger(conf, 'baz', None)
|
||||
self.assertEqual('foo.baz.', statsd_client._prefix)
|
||||
|
||||
# base prefix is configured, tail prefix set to statsd_tail_prefix arg
|
||||
statsd_client = call_get_logger(conf, None, '')
|
||||
self.assertEqual('foo.', statsd_client._prefix)
|
||||
|
||||
# base prefix is configured, tail prefix set to statsd_tail_prefix arg
|
||||
statsd_client = call_get_logger(conf, 'baz', 'boo')
|
||||
self.assertEqual('foo.boo.', statsd_client._prefix)
|
||||
|
||||
def test_get_logger_replaces_statsd_client(self):
|
||||
# Each call to get_logger creates a *new* StatsdClient instance and
|
||||
# sets it as an attribute of the potentially *shared* Logger instance.
|
||||
# This is a questionable pattern but the test at least reminds us.
|
||||
orig_logger = utils.get_logger(
|
||||
{'log_statsd_port': 1234},
|
||||
name=self.logger_name,
|
||||
statsd_tail_prefix='orig')
|
||||
self.assertTrue(hasattr(orig_logger.logger, 'statsd_client'))
|
||||
orig_client = orig_logger.logger.statsd_client
|
||||
self.assertEqual('orig.', orig_client._prefix)
|
||||
self.assertEqual(1234, orig_client._port)
|
||||
|
||||
new_adapted_logger = utils.get_logger(
|
||||
{'log_statsd_port': 5678},
|
||||
name=self.logger_name,
|
||||
statsd_tail_prefix='new')
|
||||
self.assertTrue(hasattr(new_adapted_logger.logger, 'statsd_client'))
|
||||
new_client = new_adapted_logger.logger.statsd_client
|
||||
# same core Logger...
|
||||
self.assertIs(orig_logger.logger, new_adapted_logger.logger)
|
||||
# ... different StatsdClient !
|
||||
self.assertIsNot(new_client, orig_client)
|
||||
self.assertIs(new_client, orig_logger.logger.statsd_client)
|
||||
self.assertEqual('new.', new_client._prefix)
|
||||
self.assertEqual(5678, new_client._port)
|
||||
|
||||
def test_get_prefixed_logger_calls_get_prefixed_swift_logger(self):
|
||||
orig_get_prefixed_swift_logger = utils.logs.get_prefixed_swift_logger
|
||||
base_logger = utils.logs.get_swift_logger(None)
|
||||
calls = []
|
||||
|
||||
def fake_get_prefixed_swift_logger(*args, **kwargs):
|
||||
result = orig_get_prefixed_swift_logger(*args, **kwargs)
|
||||
calls.append((args, kwargs, result))
|
||||
return result
|
||||
|
||||
with mock.patch(
|
||||
'swift.common.utils.get_prefixed_swift_logger',
|
||||
fake_get_prefixed_swift_logger):
|
||||
logger = utils.get_prefixed_logger(base_logger, 'boo')
|
||||
self.assertEqual(1, len(calls))
|
||||
self.assertEqual(((base_logger,), {'prefix': 'boo'}), calls[0][:2])
|
||||
self.assertEqual(calls[0][2], logger)
|
||||
self.assertEqual('boo', logger.prefix)
|
||||
|
||||
def test_get_prefixed_logger_adopts_statsd_client(self):
|
||||
# verify that get_prefixed_logger installs an interface to any existing
|
||||
# StatsdClient that the source logger has
|
||||
with mock.patch(
|
||||
'swift.common.statsd_client.StatsdClient', FakeStatsdClient):
|
||||
adapted_logger = utils.get_logger(None, name=self.logger_name)
|
||||
self.assertTrue(hasattr(adapted_logger.logger, 'statsd_client'))
|
||||
self.assertIsInstance(adapted_logger.logger.statsd_client,
|
||||
FakeStatsdClient)
|
||||
|
||||
prefixed_logger = utils.get_prefixed_logger(adapted_logger, 'test')
|
||||
self.assertTrue(hasattr(prefixed_logger.logger, 'statsd_client'))
|
||||
self.assertIs(prefixed_logger.logger.statsd_client,
|
||||
adapted_logger.logger.statsd_client)
|
||||
|
||||
prefixed_logger.increment('foo')
|
||||
prefixed_logger.decrement('boo')
|
||||
|
||||
exp = {
|
||||
'increment': [(('foo',), {})],
|
||||
'decrement': [(('boo',), {})],
|
||||
'update_stats': [(('foo', 1, None), {}),
|
||||
(('boo', -1, None), {})]
|
||||
}
|
||||
self.assertEqual(exp, prefixed_logger.logger.statsd_client.calls)
|
||||
self.assertEqual(exp, adapted_logger.logger.statsd_client.calls)
|
||||
|
||||
def test_get_prefixed_logger_no_statsd_client(self):
|
||||
# verify get_prefixed_logger can be used to mutate the prefix of a
|
||||
# SwiftLogAdapter that does *not* have a StatsdClient interface
|
||||
adapted_logger = utils.logs.get_swift_logger(
|
||||
None, name=self.logger_name)
|
||||
self.assertFalse(
|
||||
hasattr(adapted_logger.logger, 'statsd_client'))
|
||||
self.assertFalse(hasattr(adapted_logger, 'statsd_client_source'))
|
||||
self.assertFalse(hasattr(adapted_logger, 'increment'))
|
||||
|
||||
prefixed_logger = utils.get_prefixed_logger(adapted_logger, 'test')
|
||||
self.assertFalse(hasattr(prefixed_logger, 'statsd_client_source'))
|
||||
self.assertFalse(hasattr(prefixed_logger.logger, 'statsd_client'))
|
||||
self.assertFalse(hasattr(prefixed_logger, 'increment'))
|
||||
|
@ -36,8 +36,7 @@ from six.moves import http_client
|
||||
from test.unit import with_tempdir
|
||||
from test.unit import quiet_eventlet_exceptions
|
||||
from test.unit.common.test_utils import MockOs, MockSys
|
||||
from swift.common.exceptions import Timeout, \
|
||||
MessageTimeout, ConnectionTimeout
|
||||
from swift.common.exceptions import Timeout, MessageTimeout, ConnectionTimeout
|
||||
|
||||
if six.PY2:
|
||||
import eventlet.green.httplib as green_http_client
|
||||
@ -48,23 +47,24 @@ from swift.common import utils
|
||||
|
||||
from swift.common.swob import Request, Response
|
||||
from swift.common.utils.logs import SwiftLogFormatter, SwiftLogAdapter, \
|
||||
get_prefixed_logger
|
||||
get_swift_logger, get_prefixed_swift_logger
|
||||
|
||||
|
||||
def reset_loggers():
|
||||
if hasattr(utils.get_logger, 'handler4logger'):
|
||||
for logger, handler in utils.get_logger.handler4logger.items():
|
||||
if hasattr(get_swift_logger, 'handler4logger'):
|
||||
for logger, handler in get_swift_logger.handler4logger.items():
|
||||
logger.removeHandler(handler)
|
||||
delattr(utils.get_logger, 'handler4logger')
|
||||
if hasattr(utils.get_logger, 'console_handler4logger'):
|
||||
for logger, h in utils.get_logger.console_handler4logger.items():
|
||||
delattr(get_swift_logger, 'handler4logger')
|
||||
if hasattr(get_swift_logger, 'console_handler4logger'):
|
||||
for logger, h in \
|
||||
get_swift_logger.console_handler4logger.items():
|
||||
logger.removeHandler(h)
|
||||
delattr(utils.get_logger, 'console_handler4logger')
|
||||
# Reset the LogAdapter class thread local state. Use get_logger() here
|
||||
# to fetch a LogAdapter instance because the items from
|
||||
# get_logger.handler4logger above are the underlying logger instances,
|
||||
# not the LogAdapter.
|
||||
utils.get_logger(None).thread_locals = (None, None)
|
||||
delattr(get_swift_logger, 'console_handler4logger')
|
||||
# Reset the LogAdapter class thread local state. Use get_swift_logger()
|
||||
# here to fetch a LogAdapter instance because the items from
|
||||
# get_swift_logger.handler4logger above are the underlying logger
|
||||
# instances not the LogAdapter.
|
||||
get_swift_logger(None).thread_locals = (None, None)
|
||||
|
||||
|
||||
def reset_logger_state(f):
|
||||
@ -192,22 +192,22 @@ class TestUtilsLogs(unittest.TestCase):
|
||||
|
||||
logger.removeHandler(handler)
|
||||
|
||||
def test_get_logger(self):
|
||||
def test_get_swift_logger(self):
|
||||
sio = StringIO()
|
||||
logger = logging.getLogger('server')
|
||||
logger.addHandler(logging.StreamHandler(sio))
|
||||
logger = utils.get_logger(None, 'server', log_route='server')
|
||||
logger = get_swift_logger(None, 'server', log_route='server')
|
||||
logger.warning('test1')
|
||||
self.assertEqual(sio.getvalue(), 'test1\n')
|
||||
logger.debug('test2')
|
||||
self.assertEqual(sio.getvalue(), 'test1\n')
|
||||
logger = utils.get_logger({'log_level': 'DEBUG'}, 'server',
|
||||
logger = get_swift_logger({'log_level': 'DEBUG'}, 'server',
|
||||
log_route='server')
|
||||
logger.debug('test3')
|
||||
self.assertEqual(sio.getvalue(), 'test1\ntest3\n')
|
||||
# Doesn't really test that the log facility is truly being used all the
|
||||
# way to syslog; but exercises the code.
|
||||
logger = utils.get_logger({'log_facility': 'LOG_LOCAL3'}, 'server',
|
||||
logger = get_swift_logger({'log_facility': 'LOG_LOCAL3'}, 'server',
|
||||
log_route='server')
|
||||
logger.warning('test4')
|
||||
self.assertEqual(sio.getvalue(),
|
||||
@ -221,7 +221,7 @@ class TestUtilsLogs(unittest.TestCase):
|
||||
self.assertEqual(sio.getvalue(),
|
||||
'test1\ntest3\ntest4\ntest6\n')
|
||||
|
||||
def test_get_logger_name_and_route(self):
|
||||
def test_get_swift_logger_name_and_route(self):
|
||||
@contextlib.contextmanager
|
||||
def add_log_handler(logger):
|
||||
# install a handler to capture log messages formatted as per swift
|
||||
@ -234,7 +234,7 @@ class TestUtilsLogs(unittest.TestCase):
|
||||
yield sio
|
||||
logger.logger.removeHandler(handler)
|
||||
|
||||
logger = utils.get_logger({}, name='name', log_route='route')
|
||||
logger = utils.get_swift_logger({}, name='name', log_route='route')
|
||||
# log_route becomes the LogAdapter.name and logging.Logger.name
|
||||
self.assertEqual('route', logger.name)
|
||||
self.assertEqual('route', logger.logger.name)
|
||||
@ -245,36 +245,37 @@ class TestUtilsLogs(unittest.TestCase):
|
||||
logger.info('testing')
|
||||
self.assertEqual('name: testing\n', sio.getvalue())
|
||||
|
||||
logger = utils.get_logger({'log_name': 'conf-name'}, name='name',
|
||||
log_route='route')
|
||||
logger = utils.get_swift_logger({'log_name': 'conf-name'},
|
||||
name='name', log_route='route')
|
||||
self.assertEqual('route', logger.name)
|
||||
self.assertEqual('name', logger.server)
|
||||
with add_log_handler(logger) as sio:
|
||||
logger.info('testing')
|
||||
self.assertEqual('name: testing\n', sio.getvalue())
|
||||
|
||||
logger = utils.get_logger({'log_name': 'conf-name'}, log_route='route')
|
||||
logger = utils.get_swift_logger({'log_name': 'conf-name'},
|
||||
log_route='route')
|
||||
self.assertEqual('route', logger.name)
|
||||
self.assertEqual('conf-name', logger.server)
|
||||
with add_log_handler(logger) as sio:
|
||||
logger.info('testing')
|
||||
self.assertEqual('conf-name: testing\n', sio.getvalue())
|
||||
|
||||
logger = utils.get_logger({'log_name': 'conf-name'})
|
||||
logger = utils.get_swift_logger({'log_name': 'conf-name'})
|
||||
self.assertEqual('conf-name', logger.name)
|
||||
self.assertEqual('conf-name', logger.server)
|
||||
with add_log_handler(logger) as sio:
|
||||
logger.info('testing')
|
||||
self.assertEqual('conf-name: testing\n', sio.getvalue())
|
||||
|
||||
logger = utils.get_logger({})
|
||||
logger = utils.get_swift_logger({})
|
||||
self.assertEqual('swift', logger.name)
|
||||
self.assertEqual('swift', logger.server)
|
||||
with add_log_handler(logger) as sio:
|
||||
logger.info('testing')
|
||||
self.assertEqual('swift: testing\n', sio.getvalue())
|
||||
|
||||
logger = utils.get_logger({}, log_route='route')
|
||||
logger = utils.get_swift_logger({}, log_route='route')
|
||||
self.assertEqual('route', logger.name)
|
||||
self.assertEqual('swift', logger.server)
|
||||
with add_log_handler(logger) as sio:
|
||||
@ -282,20 +283,16 @@ class TestUtilsLogs(unittest.TestCase):
|
||||
self.assertEqual('swift: testing\n', sio.getvalue())
|
||||
|
||||
# same log_route, different names...
|
||||
logger1 = utils.get_logger({'log_statsd_host': '1.2.3.4'},
|
||||
name='name1', log_route='route')
|
||||
logger2 = utils.get_logger({'log_statsd_host': '1.2.3.5'},
|
||||
name='name2', log_route='route')
|
||||
logger1 = utils.get_swift_logger({'log_statsd_host': '1.2.3.4'},
|
||||
name='name1', log_route='route')
|
||||
logger2 = utils.get_swift_logger({'log_statsd_host': '1.2.3.5'},
|
||||
name='name2', log_route='route')
|
||||
self.assertEqual('route', logger1.name)
|
||||
self.assertEqual('route', logger1.logger.name)
|
||||
self.assertEqual('name1', logger1.server)
|
||||
# oh dear, the statsd client on the common logging.Logger instance got
|
||||
# mutated when logger2 was created
|
||||
self.assertEqual('name2.', logger1.logger.statsd_client._prefix)
|
||||
self.assertEqual('route', logger2.name)
|
||||
self.assertEqual('route', logger2.logger.name)
|
||||
self.assertEqual('name2', logger2.server)
|
||||
self.assertEqual('name2.', logger2.logger.statsd_client._prefix)
|
||||
self.assertIs(logger2.logger, logger1.logger)
|
||||
with add_log_handler(logger1) as sio:
|
||||
logger1.info('testing')
|
||||
@ -305,18 +302,16 @@ class TestUtilsLogs(unittest.TestCase):
|
||||
self.assertEqual('name2: testing\n', sio.getvalue())
|
||||
|
||||
# different log_route, different names...
|
||||
logger1 = utils.get_logger({'log_statsd_host': '1.2.3.4'},
|
||||
name='name1', log_route='route1')
|
||||
logger2 = utils.get_logger({'log_statsd_host': '1.2.3.5'},
|
||||
name='name2', log_route='route2')
|
||||
logger1 = utils.get_swift_logger({'log_statsd_host': '1.2.3.4'},
|
||||
name='name1', log_route='route1')
|
||||
logger2 = utils.get_swift_logger({'log_statsd_host': '1.2.3.5'},
|
||||
name='name2', log_route='route2')
|
||||
self.assertEqual('route1', logger1.name)
|
||||
self.assertEqual('route1', logger1.logger.name)
|
||||
self.assertEqual('name1', logger1.server)
|
||||
self.assertEqual('name1.', logger1.logger.statsd_client._prefix)
|
||||
self.assertEqual('route2', logger2.name)
|
||||
self.assertEqual('route2', logger2.logger.name)
|
||||
self.assertEqual('name2', logger2.server)
|
||||
self.assertEqual('name2.', logger2.logger.statsd_client._prefix)
|
||||
self.assertIsNot(logger2.logger, logger1.logger)
|
||||
with add_log_handler(logger1) as sio:
|
||||
logger1.info('testing')
|
||||
@ -326,7 +321,7 @@ class TestUtilsLogs(unittest.TestCase):
|
||||
self.assertEqual('name2: testing\n', sio.getvalue())
|
||||
|
||||
@with_tempdir
|
||||
def test_get_logger_sysloghandler_plumbing(self, tempdir):
|
||||
def test_get_swift_logger_sysloghandler_plumbing(self, tempdir):
|
||||
orig_sysloghandler = utils.logs.ThreadSafeSysLogHandler
|
||||
syslog_handler_args = []
|
||||
|
||||
@ -348,7 +343,7 @@ class TestUtilsLogs(unittest.TestCase):
|
||||
syslog_handler_catcher), \
|
||||
mock.patch.object(socket, 'getaddrinfo', fake_getaddrinfo):
|
||||
# default log_address
|
||||
utils.get_logger({
|
||||
get_swift_logger({
|
||||
'log_facility': 'LOG_LOCAL3',
|
||||
}, 'server', log_route='server')
|
||||
expected_args = [((), {'address': '/dev/log',
|
||||
@ -365,7 +360,7 @@ class TestUtilsLogs(unittest.TestCase):
|
||||
# custom log_address - file doesn't exist: fallback to UDP
|
||||
log_address = os.path.join(tempdir, 'foo')
|
||||
syslog_handler_args = []
|
||||
utils.get_logger({
|
||||
get_swift_logger({
|
||||
'log_facility': 'LOG_LOCAL3',
|
||||
'log_address': log_address,
|
||||
}, 'server', log_route='server')
|
||||
@ -378,7 +373,7 @@ class TestUtilsLogs(unittest.TestCase):
|
||||
with open(log_address, 'w'):
|
||||
pass
|
||||
syslog_handler_args = []
|
||||
utils.get_logger({
|
||||
get_swift_logger({
|
||||
'log_facility': 'LOG_LOCAL3',
|
||||
'log_address': log_address,
|
||||
}, 'server', log_route='server')
|
||||
@ -394,7 +389,7 @@ class TestUtilsLogs(unittest.TestCase):
|
||||
sock.settimeout(5)
|
||||
sock.bind(log_address)
|
||||
syslog_handler_args = []
|
||||
utils.get_logger({
|
||||
get_swift_logger({
|
||||
'log_facility': 'LOG_LOCAL3',
|
||||
'log_address': log_address,
|
||||
}, 'server', log_route='server')
|
||||
@ -406,7 +401,7 @@ class TestUtilsLogs(unittest.TestCase):
|
||||
|
||||
# Using UDP with default port
|
||||
syslog_handler_args = []
|
||||
utils.get_logger({
|
||||
get_swift_logger({
|
||||
'log_udp_host': 'syslog.funtimes.com',
|
||||
}, 'server', log_route='server')
|
||||
self.assertEqual([
|
||||
@ -417,7 +412,7 @@ class TestUtilsLogs(unittest.TestCase):
|
||||
|
||||
# Using UDP with non-default port
|
||||
syslog_handler_args = []
|
||||
utils.get_logger({
|
||||
get_swift_logger({
|
||||
'log_udp_host': 'syslog.funtimes.com',
|
||||
'log_udp_port': '2123',
|
||||
}, 'server', log_route='server')
|
||||
@ -429,13 +424,13 @@ class TestUtilsLogs(unittest.TestCase):
|
||||
with mock.patch.object(utils.logs, 'ThreadSafeSysLogHandler',
|
||||
side_effect=OSError(errno.EPERM, 'oops')):
|
||||
with self.assertRaises(OSError) as cm:
|
||||
utils.get_logger({
|
||||
get_swift_logger({
|
||||
'log_facility': 'LOG_LOCAL3',
|
||||
'log_address': 'log_address',
|
||||
}, 'server', log_route='server')
|
||||
self.assertEqual(errno.EPERM, cm.exception.errno)
|
||||
|
||||
def test_get_logger_custom_log_handlers(self):
|
||||
def test_get_swift_logger_custom_log_handlers(self):
|
||||
def custom_log_handler(conf, name, log_to_console, log_route, fmt,
|
||||
logger, adapted_logger):
|
||||
adapted_logger.server = adapted_logger.server.upper()
|
||||
@ -449,7 +444,7 @@ class TestUtilsLogs(unittest.TestCase):
|
||||
|
||||
# sanity check...
|
||||
conf = {}
|
||||
adapted_logger = utils.get_logger(
|
||||
adapted_logger = get_swift_logger(
|
||||
conf, 'my_server', log_route='my_logger_name')
|
||||
adapted_logger.warning('test')
|
||||
self.assertEqual(sio.getvalue(),
|
||||
@ -461,7 +456,7 @@ class TestUtilsLogs(unittest.TestCase):
|
||||
patch_target = 'test.unit.common.utils.custom_log_handler'
|
||||
conf = {'log_custom_handlers': patch_target}
|
||||
with mock.patch(patch_target, custom_log_handler, create=True):
|
||||
adapted_logger = utils.get_logger(
|
||||
adapted_logger = get_swift_logger(
|
||||
conf, 'my_server', log_route='my_logger_name')
|
||||
adapted_logger.warning('test')
|
||||
self.assertEqual(sio.getvalue(),
|
||||
@ -471,7 +466,7 @@ class TestUtilsLogs(unittest.TestCase):
|
||||
def test_clean_logger_exception(self):
|
||||
# setup stream logging
|
||||
sio = StringIO()
|
||||
logger = utils.get_logger(None)
|
||||
logger = get_swift_logger(None)
|
||||
handler = logging.StreamHandler(sio)
|
||||
logger.logger.addHandler(handler)
|
||||
|
||||
@ -610,7 +605,7 @@ class TestUtilsLogs(unittest.TestCase):
|
||||
def test_swift_log_formatter_max_line_length(self):
|
||||
# setup stream logging
|
||||
sio = StringIO()
|
||||
logger = utils.get_logger(None)
|
||||
logger = get_swift_logger(None)
|
||||
handler = logging.StreamHandler(sio)
|
||||
formatter = utils.SwiftLogFormatter(max_line_length=10)
|
||||
handler.setFormatter(formatter)
|
||||
@ -666,7 +661,7 @@ class TestUtilsLogs(unittest.TestCase):
|
||||
def test_swift_log_formatter(self):
|
||||
# setup stream logging
|
||||
sio = StringIO()
|
||||
logger = utils.get_logger(None)
|
||||
logger = get_swift_logger(None)
|
||||
handler = logging.StreamHandler(sio)
|
||||
handler.setFormatter(utils.SwiftLogFormatter())
|
||||
logger.logger.addHandler(handler)
|
||||
@ -728,13 +723,13 @@ class TestUtilsLogs(unittest.TestCase):
|
||||
logger.logger.removeHandler(handler)
|
||||
|
||||
@reset_logger_state
|
||||
def test_get_prefixed_logger(self):
|
||||
def test_get_prefixed_swift_logger(self):
|
||||
# setup stream logging
|
||||
sio = StringIO()
|
||||
base_logger = utils.get_logger(None)
|
||||
base_logger = get_swift_logger(None)
|
||||
handler = logging.StreamHandler(sio)
|
||||
base_logger.logger.addHandler(handler)
|
||||
logger = get_prefixed_logger(base_logger, 'some prefix: ')
|
||||
logger = get_prefixed_swift_logger(base_logger, 'some prefix: ')
|
||||
|
||||
def strip_value(sio):
|
||||
sio.seek(0)
|
||||
@ -759,13 +754,13 @@ class TestUtilsLogs(unittest.TestCase):
|
||||
base_logger.logger.removeHandler(handler)
|
||||
|
||||
@reset_logger_state
|
||||
def test_get_prefixed_logger_exception_method(self):
|
||||
def test_get_prefixed_swift_logger_exception_method(self):
|
||||
# setup stream logging
|
||||
sio = StringIO()
|
||||
base_logger = utils.get_logger(None)
|
||||
base_logger = get_swift_logger(None)
|
||||
handler = logging.StreamHandler(sio)
|
||||
base_logger.logger.addHandler(handler)
|
||||
logger = get_prefixed_logger(base_logger, 'some prefix: ')
|
||||
logger = get_prefixed_swift_logger(base_logger, 'some prefix: ')
|
||||
|
||||
def strip_value(sio):
|
||||
sio.seek(0)
|
||||
@ -816,13 +811,13 @@ class TestUtilsLogs(unittest.TestCase):
|
||||
base_logger.logger.removeHandler(handler)
|
||||
|
||||
@reset_logger_state
|
||||
def test_get_prefixed_logger_non_string_values(self):
|
||||
def test_get_prefixed_swift_logger_non_string_values(self):
|
||||
# setup stream logging
|
||||
sio = StringIO()
|
||||
base_logger = utils.get_logger(None)
|
||||
base_logger = get_swift_logger(None)
|
||||
handler = logging.StreamHandler(sio)
|
||||
base_logger.logger.addHandler(handler)
|
||||
logger = get_prefixed_logger(base_logger, 'some prefix: ')
|
||||
logger = get_prefixed_swift_logger(base_logger, 'some prefix: ')
|
||||
exc = Exception('blah')
|
||||
|
||||
def strip_value(sio):
|
||||
@ -832,21 +827,21 @@ class TestUtilsLogs(unittest.TestCase):
|
||||
return v
|
||||
|
||||
try:
|
||||
logger = get_prefixed_logger(logger, 'abc')
|
||||
logger = get_prefixed_swift_logger(logger, 'abc')
|
||||
self.assertEqual('abc', logger.prefix)
|
||||
logger.info('test')
|
||||
self.assertEqual(strip_value(sio), 'abctest\n')
|
||||
logger.info(exc)
|
||||
self.assertEqual(strip_value(sio), 'abcblah\n')
|
||||
|
||||
logger = get_prefixed_logger(logger, '')
|
||||
logger = get_prefixed_swift_logger(logger, '')
|
||||
self.assertEqual('', logger.prefix)
|
||||
logger.info('test')
|
||||
self.assertEqual(strip_value(sio), 'test\n')
|
||||
logger.info(exc)
|
||||
self.assertEqual(strip_value(sio), 'blah\n')
|
||||
|
||||
logger = get_prefixed_logger(logger, 0)
|
||||
logger = get_prefixed_swift_logger(logger, 0)
|
||||
self.assertEqual(0, logger.prefix)
|
||||
logger.info('test')
|
||||
self.assertEqual(strip_value(sio), '0test\n')
|
||||
@ -856,14 +851,14 @@ class TestUtilsLogs(unittest.TestCase):
|
||||
logger.logger.removeHandler(handler)
|
||||
|
||||
@reset_logger_state
|
||||
def test_get_prefixed_logger_replaces_prefix(self):
|
||||
def test_get_prefixed_swift_logger_replaces_prefix(self):
|
||||
# setup stream logging
|
||||
sio = StringIO()
|
||||
base_logger = utils.get_logger(None)
|
||||
base_logger = get_swift_logger(None)
|
||||
handler = logging.StreamHandler(sio)
|
||||
base_logger.logger.addHandler(handler)
|
||||
logger1 = get_prefixed_logger(base_logger, 'one: ')
|
||||
logger2 = get_prefixed_logger(logger1, 'two: ')
|
||||
logger1 = get_prefixed_swift_logger(base_logger, 'one: ')
|
||||
logger2 = get_prefixed_swift_logger(logger1, 'two: ')
|
||||
|
||||
def strip_value(sio):
|
||||
sio.seek(0)
|
||||
@ -886,17 +881,17 @@ class TestUtilsLogs(unittest.TestCase):
|
||||
finally:
|
||||
base_logger.logger.removeHandler(handler)
|
||||
|
||||
def test_get_prefixed_logger_isolation(self):
|
||||
def test_get_prefixed_swift_logger_isolation(self):
|
||||
# verify that the new instance's attributes are copied by value
|
||||
# from the old (except prefix), but the thread_locals are still shared
|
||||
adapted_logger = utils.get_logger(None, name='server')
|
||||
adapted_logger = get_swift_logger(None, name='server')
|
||||
adapted_logger.thread_locals = ('id', 'ip')
|
||||
adapted_logger = get_prefixed_logger(adapted_logger, 'foo')
|
||||
adapted_logger = get_prefixed_swift_logger(adapted_logger, 'foo')
|
||||
self.assertEqual(adapted_logger.server, 'server')
|
||||
self.assertEqual(adapted_logger.thread_locals, ('id', 'ip'))
|
||||
self.assertEqual(adapted_logger.prefix, 'foo')
|
||||
|
||||
cloned_adapted_logger = get_prefixed_logger(
|
||||
cloned_adapted_logger = get_prefixed_swift_logger(
|
||||
adapted_logger, 'boo')
|
||||
self.assertEqual(cloned_adapted_logger.server, 'server')
|
||||
self.assertEqual(cloned_adapted_logger.thread_locals, ('id', 'ip'))
|
||||
@ -907,7 +902,7 @@ class TestUtilsLogs(unittest.TestCase):
|
||||
self.assertEqual(adapted_logger.prefix, 'foo')
|
||||
self.assertIs(adapted_logger.logger, cloned_adapted_logger.logger)
|
||||
|
||||
cloned_adapted_logger = get_prefixed_logger(
|
||||
cloned_adapted_logger = get_prefixed_swift_logger(
|
||||
adapted_logger, adapted_logger.prefix + 'bar')
|
||||
adapted_logger.server = 'waiter'
|
||||
self.assertEqual(adapted_logger.server, 'waiter')
|
||||
@ -923,7 +918,7 @@ class TestUtilsLogs(unittest.TestCase):
|
||||
@reset_logger_state
|
||||
def test_capture_stdio(self):
|
||||
# stubs
|
||||
logger = utils.logs.get_logger(None, 'dummy')
|
||||
logger = get_swift_logger(None, 'dummy')
|
||||
|
||||
# mock utils system modules
|
||||
mock_os = MockOs()
|
||||
@ -958,7 +953,7 @@ class TestUtilsLogs(unittest.TestCase):
|
||||
mock_sys = MockSys()
|
||||
with mock.patch.object(utils.logs, 'os', mock_os), \
|
||||
mock.patch.object(utils.logs, 'sys', mock_sys):
|
||||
logger = utils.get_logger(None, log_to_console=True)
|
||||
logger = get_swift_logger(None, log_to_console=True)
|
||||
|
||||
# test console log
|
||||
utils.logs.capture_stdio(logger, capture_stdout=False,
|
||||
@ -976,19 +971,19 @@ class TestUtilsLogs(unittest.TestCase):
|
||||
utils.logs.LoggerFileObject))
|
||||
|
||||
@reset_logger_state
|
||||
def test_get_logger_console(self):
|
||||
logger = utils.get_logger(None)
|
||||
def test_get_swift_logger_console(self):
|
||||
logger = get_swift_logger(None)
|
||||
console_handlers = [h for h in logger.logger.handlers if
|
||||
isinstance(h, logging.StreamHandler)]
|
||||
self.assertFalse(console_handlers)
|
||||
logger = utils.get_logger(None, log_to_console=True)
|
||||
logger = get_swift_logger(None, log_to_console=True)
|
||||
console_handlers = [h for h in logger.logger.handlers if
|
||||
isinstance(h, logging.StreamHandler)]
|
||||
self.assertTrue(console_handlers)
|
||||
# make sure you can't have two console handlers
|
||||
self.assertEqual(len(console_handlers), 1)
|
||||
old_handler = console_handlers[0]
|
||||
logger = utils.get_logger(None, log_to_console=True)
|
||||
logger = get_swift_logger(None, log_to_console=True)
|
||||
console_handlers = [h for h in logger.logger.handlers if
|
||||
isinstance(h, logging.StreamHandler)]
|
||||
self.assertEqual(len(console_handlers), 1)
|
||||
|
@ -53,7 +53,7 @@ from six.moves import range
|
||||
from six.moves.urllib.parse import quote, parse_qsl
|
||||
|
||||
from test import listen_zero
|
||||
from test.debug_logger import debug_logger
|
||||
from test.debug_logger import debug_logger, FakeStatsdClient
|
||||
from test.unit import (
|
||||
connect_tcp, readuntil2crlfs, fake_http_connect, FakeRing,
|
||||
FakeMemcache, patch_policies, write_fake_ring, mocked_http_conn,
|
||||
@ -2295,16 +2295,17 @@ class TestProxyServerConfigLoading(unittest.TestCase):
|
||||
use = egg:swift#proxy
|
||||
""" % self.tempdir
|
||||
conf_path = self._write_conf(dedent(conf_sections))
|
||||
with mock.patch('swift.common.statsd_client.StatsdClient') \
|
||||
as mock_statsd:
|
||||
with mock.patch('swift.common.statsd_client.StatsdClient',
|
||||
FakeStatsdClient):
|
||||
app = loadapp(conf_path, allow_modify_pipeline=False)
|
||||
# logger name is hard-wired 'proxy-server'
|
||||
self.assertEqual('proxy-server', app.logger.name)
|
||||
self.assertEqual('swift', app.logger.server)
|
||||
mock_statsd.assert_called_once_with(
|
||||
'example.com', 8125, base_prefix='', tail_prefix='proxy-server',
|
||||
default_sample_rate=1.0, sample_rate_factor=1.0,
|
||||
logger=app.logger.logger)
|
||||
self.assertIsInstance(app.logger.logger.statsd_client, StatsdClient)
|
||||
self.assertEqual(app.logger.logger.statsd_client._host, 'example.com')
|
||||
self.assertEqual(app.logger.logger.statsd_client._port, 8125)
|
||||
self.assertEqual(app.logger.logger.statsd_client._prefix,
|
||||
'proxy-server.')
|
||||
|
||||
conf_sections = """
|
||||
[DEFAULT]
|
||||
@ -2320,18 +2321,19 @@ class TestProxyServerConfigLoading(unittest.TestCase):
|
||||
""" % self.tempdir
|
||||
conf_path = self._write_conf(dedent(conf_sections))
|
||||
|
||||
with mock.patch('swift.common.statsd_client.StatsdClient') \
|
||||
as mock_statsd:
|
||||
with mock.patch('swift.common.statsd_client.StatsdClient',
|
||||
FakeStatsdClient):
|
||||
app = loadapp(conf_path, allow_modify_pipeline=False)
|
||||
# logger name is hard-wired 'proxy-server'
|
||||
self.assertEqual('proxy-server', app.logger.name)
|
||||
# server is defined by log_name option
|
||||
self.assertEqual('test-name', app.logger.server)
|
||||
# statsd tail prefix is hard-wired 'proxy-server'
|
||||
mock_statsd.assert_called_once_with(
|
||||
'example.com', 8125, base_prefix='', tail_prefix='proxy-server',
|
||||
default_sample_rate=1.0, sample_rate_factor=1.0,
|
||||
logger=app.logger.logger)
|
||||
self.assertIsInstance(app.logger.logger.statsd_client, StatsdClient)
|
||||
self.assertEqual(app.logger.logger.statsd_client._host, 'example.com')
|
||||
self.assertEqual(app.logger.logger.statsd_client._port, 8125)
|
||||
self.assertEqual(app.logger.logger.statsd_client._prefix,
|
||||
'proxy-server.')
|
||||
|
||||
|
||||
class TestProxyServerConfigStringLoading(TestProxyServerConfigLoading):
|
||||
|
Loading…
Reference in New Issue
Block a user