Skip to content

Commit

Permalink
Remove log_instances
Browse files Browse the repository at this point in the history
  • Loading branch information
Junchao-Mellanox committed Aug 26, 2024
1 parent d81abd5 commit 61c0853
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 64 deletions.
62 changes: 11 additions & 51 deletions src/sonic-py-common/sonic_py_common/syslogger.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,15 @@ class SysLogger:
"""
SysLogger class for Python applications using SysLogHandler
"""

log_registry = {}

DEFAULT_LOG_FACILITY = SysLogHandler.LOG_USER
DEFAULT_LOG_LEVEL = logging.NOTICE

def __init__(self, log_identifier=None, log_facility=DEFAULT_LOG_FACILITY, log_level=DEFAULT_LOG_LEVEL, enable_runtime_config=False):
if log_identifier is None:
log_identifier = os.path.basename(sys.argv[0])
self.log_identifier = log_identifier if log_identifier else os.path.basename(sys.argv[0])

# Initialize SysLogger
self.logger = logging.getLogger(log_identifier)
self.logger = logging.getLogger(self.log_identifier)

# Reset all existing handlers
for handler in self.logger.handlers[:]:
Expand All @@ -44,64 +41,27 @@ def __init__(self, log_identifier=None, log_facility=DEFAULT_LOG_FACILITY, log_l
self.set_min_log_priority(log_level)

if enable_runtime_config:
self.register_for_runtime_config(log_identifier)

def register_for_runtime_config(self, log_identifier):
"""Register current log instance to log registry. If DB entry exists,
update log level according to DB configuration; otherwise, save current
log level to DB.
self.update_log_level()

def update_log_level(self):
"""Refresh log level.
Args:
log_identifier (str): key of LOGGER table
"""
if log_identifier not in SysLogger.log_registry:
SysLogger.log_registry[log_identifier] = [self]
else:
SysLogger.log_registry[log_identifier].append(self)

Returns:
tuple: (refresh result, fail reason)
"""
from swsscommon import swsscommon
try:
config_db = swsscommon.SonicV2Connector(use_unix_socket_path=True)
config_db.connect(CONFIG_DB)
log_level_in_db = config_db.get(CONFIG_DB, f'{swsscommon.CFG_LOGGER_TABLE_NAME}|{log_identifier}', FIELD_LOG_LEVEL)
log_level_in_db = config_db.get(CONFIG_DB, f'{swsscommon.CFG_LOGGER_TABLE_NAME}|{self.log_identifier}', FIELD_LOG_LEVEL)
if log_level_in_db:
self.set_min_log_priority(self.log_priority_from_str(log_level_in_db))
else:
data = {
FIELD_LOG_LEVEL: self.log_priority_to_str(self._min_log_level),
FIELD_REQUIRE_REFRESH: 'true'
}
config_db.hmset(CONFIG_DB, f'{swsscommon.CFG_LOGGER_TABLE_NAME}|{log_identifier}', data)
except Exception as e:
self.log_notice(f'DB is not available when initialize logger instance - {e}')

@classmethod
def update_log_level(cls):
"""Refresh log level for each log instances registered to cls.log_registry.
Returns:
tuple: (refresh result, fail reason)
"""
if not cls.log_registry:
return True, ''

from swsscommon import swsscommon
try:
config_db = swsscommon.SonicV2Connector(use_unix_socket_path=True)
config_db.connect(CONFIG_DB)
for log_identifier, log_instances in cls.log_registry.items():
log_level_in_db = config_db.get(CONFIG_DB, f'{swsscommon.CFG_LOGGER_TABLE_NAME}|{log_identifier}', FIELD_LOG_LEVEL)
if log_level_in_db:
for log_instance in log_instances:
log_instance.set_min_log_priority(log_instance.log_priority_from_str(log_level_in_db))
else:
for log_instance in log_instances:
data = {
FIELD_LOG_LEVEL: log_instance.log_priority_to_str(log_instance._min_log_level),
FIELD_REQUIRE_REFRESH: 'true'
}
config_db.hmset(CONFIG_DB, f'{swsscommon.CFG_LOGGER_TABLE_NAME}|{log_identifier}', data)
break
config_db.hmset(CONFIG_DB, f'{swsscommon.CFG_LOGGER_TABLE_NAME}|{self.log_identifier}', data)
return True, ''
except Exception as e:
return False, f'Failed to refresh log configuration - {e}'
Expand Down
16 changes: 3 additions & 13 deletions src/sonic-py-common/tests/test_syslogger.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,30 +71,20 @@ def test_runtime_config(self, mock_connector):
mock_db = mock.MagicMock()
mock_db.get = mock.MagicMock(return_value='DEBUG')
mock_connector.return_value = mock_db
log1 = syslogger.SysLogger(log_identifier='log1', enable_runtime_config=True, log_level=logging.INFO)
assert 'log1' in syslogger.SysLogger.log_registry
assert log1.logger.level == logging.DEBUG

mock_db.get.return_value = None
mock_db.hmset = mock.MagicMock()
log2 = syslogger.SysLogger(log_identifier='log2', enable_runtime_config=True, log_level=logging.INFO)
assert 'log2' in syslogger.SysLogger.log_registry
mock_db.hmset.assert_called_once()
log = syslogger.SysLogger(log_identifier='log1', enable_runtime_config=True, log_level=logging.INFO)
assert log.logger.level == logging.DEBUG

mock_db.get.return_value = 'ERROR'
ret, msg = syslogger.SysLogger.update_log_level()
ret, msg = log.update_log_level()
assert ret
assert not msg
assert log1.logger.level == logging.ERROR
assert log2.logger.level == logging.ERROR

@mock.patch('swsscommon.swsscommon.SonicV2Connector')
def test_runtime_config_negative(self, mock_connector):
mock_db = mock.MagicMock()
mock_db.get = mock.MagicMock(side_effect=Exception(''))
mock_connector.return_value = mock_db
syslogger.SysLogger(log_identifier='log', enable_runtime_config=True)
assert 'log' in syslogger.SysLogger.log_registry

ret, msg = syslogger.SysLogger.update_log_level()
assert not ret
Expand Down

0 comments on commit 61c0853

Please sign in to comment.