114 lines
3.8 KiB
Python
Executable File
114 lines
3.8 KiB
Python
Executable File
#
|
|
# Copyright (c) 2015-2016 Wind River Systems, Inc.
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
import logging
|
|
import multiprocessing
|
|
import six
|
|
import sys
|
|
import threading
|
|
|
|
from logging.handlers import SysLogHandler
|
|
|
|
from nfv_common.helpers import Singleton
|
|
|
|
|
|
class DebugLoggingThreadFormatter(logging.Formatter):
|
|
"""
|
|
Debug Log Formatter
|
|
"""
|
|
def format(self, record):
|
|
"""
|
|
Override the formatter if the record has already been formatted
|
|
"""
|
|
if hasattr(record, 'formatted_log'):
|
|
return record.formatted_log
|
|
else:
|
|
super(DebugLoggingThreadFormatter, self).format(record)
|
|
|
|
|
|
@six.add_metaclass(Singleton)
|
|
class DebugLoggingThread(object):
|
|
"""
|
|
Debug Logging Thread
|
|
"""
|
|
def __init__(self):
|
|
self._handlers = list()
|
|
self._log_queue = multiprocessing.Queue()
|
|
self._thread = threading.Thread(target=self._receive_logs)
|
|
self._thread.daemon = True
|
|
self._thread.start()
|
|
|
|
def send_log_record(self, log_record):
|
|
"""
|
|
Send a log record to debug logging thread
|
|
"""
|
|
self._log_queue.put_nowait(['log-record', log_record])
|
|
|
|
def send_log_config(self, config):
|
|
"""
|
|
Send log configuration to debug logging thread
|
|
"""
|
|
self._log_queue.put_nowait(['log-config', config])
|
|
|
|
def _receive_logs(self):
|
|
"""
|
|
Receive log records sent to the debug logging thread
|
|
"""
|
|
formatter = DebugLoggingThreadFormatter()
|
|
|
|
while True:
|
|
try:
|
|
log_work = self._log_queue.get()
|
|
|
|
if log_work is not None:
|
|
action, work = log_work
|
|
|
|
if 'log-record' == action:
|
|
if self._handlers:
|
|
for handler in self._handlers:
|
|
if hasattr(handler, 'is_stdout'):
|
|
try:
|
|
date_time = work.asctime
|
|
text = str(work.formatted_log)
|
|
text = text.split('[', 1)[-1]
|
|
text = text.split(':', 1)[-1]
|
|
work.formatted_log = date_time + ' ' + text
|
|
except Exception:
|
|
pass
|
|
|
|
handler.emit(work)
|
|
|
|
elif 'log-config' == action:
|
|
if self._handlers:
|
|
for handler in self._handlers:
|
|
handler.close()
|
|
|
|
handler_names = work.get('handlers', '')
|
|
handler_list = [handler.strip()
|
|
for handler in handler_names.split(',')]
|
|
|
|
self._handlers[:] = list()
|
|
|
|
if 'syslog' in handler_list:
|
|
address = work.get('syslog_address', '/dev/log')
|
|
facility = work.get('syslog_facility', 'user')
|
|
facility = SysLogHandler.facility_names[facility]
|
|
syslog_handler = SysLogHandler(address=address,
|
|
facility=facility)
|
|
syslog_handler.setFormatter(formatter)
|
|
self._handlers.append(syslog_handler)
|
|
|
|
if 'stdout' in handler_list:
|
|
stdout_handler = logging.StreamHandler(sys.stdout)
|
|
stdout_handler.setFormatter(formatter)
|
|
stdout_handler.is_stdout = True
|
|
self._handlers.append(stdout_handler)
|
|
|
|
except EOFError:
|
|
return
|
|
|
|
except (KeyboardInterrupt, SystemExit):
|
|
raise
|