oslo.messaging/oslo_messaging/notify/log_handler.py
gtt116 fb8c431ad6 Make notify driver messaging play well with publish_errors
When publish_errors is True, and using `messaging` notify driver,
produces a infinite loop that report sending notification error.

The reason is we always passing None to the content argument in
logger handlers (LoggingNotificationHandler, LoggingErrorNotificationHandler),
when pack the context object which expected as a dict, raise TypeError
exception, so result in infinite retry looping.

To match what document said, passing a empty dict rather than None. Also
modify unittests to make sure context is a empty dict.

Change-Id: Ic2c4c43f5bbafa8107ea370ba959da16cfa4a24c
Closes-bug: #1346466
2015-03-28 11:32:24 +00:00

44 lines
1.7 KiB
Python

# 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 logging
from oslo_config import cfg
class LoggingErrorNotificationHandler(logging.Handler):
def __init__(self, *args, **kwargs):
# NOTE(dhellmann): Avoid a cyclical import by doing this one
# at runtime.
import oslo_messaging
logging.Handler.__init__(self, *args, **kwargs)
self._transport = oslo_messaging.get_transport(cfg.CONF)
self._notifier = oslo_messaging.Notifier(
self._transport,
publisher_id='error.publisher')
def emit(self, record):
# NOTE(bnemec): Notifier registers this opt with the transport.
if ('log' in self._transport.conf.notification_driver):
# NOTE(lbragstad): If we detect that log is one of the
# notification drivers, then return. This protects from infinite
# recursion where something bad happens, it gets logged, the log
# handler sends a notification, and the log_notifier sees the
# notification and logs it.
return
self._notifier.error({},
'error_notification',
dict(error=record.msg))
PublishErrorsHandler = LoggingErrorNotificationHandler