Refactored daemon base API: added Logger. (#2672)

* Refactored daemon base API: added Logger.

Signed-off-by: Nazarii Hnydyn <nazariig@mellanox.com>
This commit is contained in:
Nazarii Hnydyn 2019-04-04 16:12:59 +03:00 committed by Andriy Moroz
parent 67113ad051
commit ab2c42ea8a

View File

@ -4,82 +4,111 @@ try:
import imp import imp
import signal import signal
import subprocess import subprocess
import os
import sys import sys
import syslog import syslog
from swsscommon import swsscommon from swsscommon import swsscommon
except ImportError, e: except ImportError, e:
raise ImportError (str(e) + " - required module not found") raise ImportError (str(e) + " - required module not found")
#============================= Constants ============================= #
# Constants ====================================================================
#
# Redis DB information
REDIS_HOSTNAME = 'localhost'
REDIS_PORT = 6379
REDIS_TIMEOUT_MSECS = 0
# Platform root directory inside docker # Platform root directory inside docker
PLATFORM_ROOT_DOCKER = "/usr/share/sonic/platform" PLATFORM_ROOT_DOCKER = '/usr/share/sonic/platform'
SONIC_CFGGEN_PATH = '/usr/local/bin/sonic-cfggen' SONIC_CFGGEN_PATH = '/usr/local/bin/sonic-cfggen'
HWSKU_KEY = 'DEVICE_METADATA.localhost.hwsku' HWSKU_KEY = 'DEVICE_METADATA.localhost.hwsku'
PLATFORM_KEY = 'DEVICE_METADATA.localhost.platform' PLATFORM_KEY = 'DEVICE_METADATA.localhost.platform'
# Port config information
PORT_CONFIG = 'port_config.ini'
PORTMAP = 'portmap.ini'
EEPROM_MODULE_NAME = 'eeprom' EEPROM_MODULE_NAME = 'eeprom'
EEPROM_CLASS_NAME = 'board' EEPROM_CLASS_NAME = 'board'
class DaemonBase(object): #
# Redis DB information # Helper functions =============================================================
redis_hostname = "localhost" #
redis_port = 6379
redis_timeout_msecs = 0
def db_connect(db):
return swsscommon.DBConnector(db,
REDIS_HOSTNAME,
REDIS_PORT,
REDIS_TIMEOUT_MSECS)
#
# Helper classes ===============================================================
#
class Logger(object):
def __init__(self, syslog_identifier):
syslog.openlog(ident=syslog_identifier, logoption=syslog.LOG_NDELAY, facility=syslog.LOG_DAEMON)
def __del__(self):
syslog.closelog()
def log_error(self, msg, also_print_to_console=False):
syslog.syslog(syslog.LOG_ERR, msg)
if also_print_to_console:
print msg
def log_warning(self, msg, also_print_to_console=False):
syslog.syslog(syslog.LOG_WARNING, msg)
if also_print_to_console:
print msg
def log_notice(self, msg, also_print_to_console=False):
syslog.syslog(syslog.LOG_NOTICE, msg)
if also_print_to_console:
print msg
def log_info(self, msg, also_print_to_console=False):
syslog.syslog(syslog.LOG_INFO, msg)
if also_print_to_console:
print msg
def log_debug(self, msg, also_print_to_console=False):
syslog.syslog(syslog.LOG_DEBUG, msg)
if also_print_to_console:
print msg
#
# Daemon =======================================================================
#
class DaemonBase(object):
def __init__(self): def __init__(self):
self.log_info("Starting up...")
# Register our signal handlers # Register our signal handlers
signal.signal(signal.SIGHUP, self.signal_handler) signal.signal(signal.SIGHUP, self.signal_handler)
signal.signal(signal.SIGINT, self.signal_handler) signal.signal(signal.SIGINT, self.signal_handler)
signal.signal(signal.SIGTERM, self.signal_handler) signal.signal(signal.SIGTERM, self.signal_handler)
def __del__(self): # Signal handler
self.log_error("Return from daemon, exiting...")
def run(self):
raise NotImplementedError()
# ========================== Connect to DB ============================
def db_connect(self, db):
return swsscommon.DBConnector(db,
self.redis_hostname,
self.redis_port,
self.redis_timeout_msecs)
# ========================== Syslog wrappers ==========================
def log_info(self, msg):
syslog.openlog()
syslog.syslog(syslog.LOG_INFO, msg)
syslog.closelog()
def log_warning(self, msg):
syslog.openlog()
syslog.syslog(syslog.LOG_WARNING, msg)
syslog.closelog()
def log_error(self, msg):
syslog.openlog()
syslog.syslog(syslog.LOG_ERR, msg)
syslog.closelog()
#========================== Signal Handling ==========================
def signal_handler(self, sig, frame): def signal_handler(self, sig, frame):
if sig == signal.SIGHUP: if sig == signal.SIGHUP:
self.log_info("Caught SIGHUP - ignoring...") syslog.syslog(syslog.LOG_INFO, "Caught SIGHUP - ignoring...")
return
elif sig == signal.SIGINT: elif sig == signal.SIGINT:
self.log_info("Caught SIGINT - exiting...") syslog.syslog(syslog.LOG_INFO, "Caught SIGINT - exiting...")
sys.exit(128 + sig) sys.exit(128 + sig)
elif sig == signal.SIGTERM: elif sig == signal.SIGTERM:
self.log_info("Caught SIGTERM - exiting...") syslog.syslog(syslog.LOG_INFO, "Caught SIGTERM - exiting...")
sys.exit(128 + sig) sys.exit(128 + sig)
else: else:
self.log_warning("Caught unhandled signal '" + sig + "'") syslog.syslog(syslog.LOG_WARNING, "Caught unhandled signal '" + sig + "'")
return
#============ Functions to load platform-specific classes ============ # Returns platform and hwsku
# Returns platform and HW SKU
def get_platform_and_hwsku(self): def get_platform_and_hwsku(self):
try: try:
proc = subprocess.Popen([SONIC_CFGGEN_PATH, '-H', '-v', PLATFORM_KEY], proc = subprocess.Popen([SONIC_CFGGEN_PATH, '-H', '-v', PLATFORM_KEY],
@ -98,12 +127,11 @@ class DaemonBase(object):
proc.wait() proc.wait()
hwsku = stdout.rstrip('\n') hwsku = stdout.rstrip('\n')
except OSError, e: except OSError, e:
self.log_error("Cannot to detect platform") raise OSError("Failed to detect platform: %s" % (str(e)))
raise OSError("Cannot detect platform")
return (platform, hwsku) return (platform, hwsku)
# Returns path to hwsku # Returns path to platform and hwsku
def get_path_to_platform_and_hwsku(self): def get_path_to_platform_and_hwsku(self):
# Get platform and hwsku # Get platform and hwsku
(platform, hwsku) = self.get_platform_and_hwsku() (platform, hwsku) = self.get_platform_and_hwsku()
@ -114,6 +142,21 @@ class DaemonBase(object):
return (platform_path, hwsku_path) return (platform_path, hwsku_path)
# Returns path to port config file
def get_path_to_port_config_file(self):
# Get platform and hwsku path
(platform_path, hwsku_path) = self.get_path_to_platform_and_hwsku()
# First check for the presence of the new 'port_config.ini' file
port_config_file_path = "/".join([hwsku_path, PORT_CONFIG])
if not os.path.isfile(port_config_file_path):
# port_config.ini doesn't exist. Try loading the legacy 'portmap.ini' file
port_config_file_path = "/".join([hwsku_path, PORTMAP])
if not os.path.isfile(port_config_file_path):
raise IOError("Failed to detect port config file: %s" % (port_config_file_path))
return port_config_file_path
# Loads platform specific psuutil module from source # Loads platform specific psuutil module from source
def load_platform_util(self, module_name, class_name): def load_platform_util(self, module_name, class_name):
platform_util = None platform_util = None
@ -125,8 +168,7 @@ class DaemonBase(object):
module_file = "/".join([platform_path, "plugins", module_name + ".py"]) module_file = "/".join([platform_path, "plugins", module_name + ".py"])
module = imp.load_source(module_name, module_file) module = imp.load_source(module_name, module_file)
except IOError, e: except IOError, e:
self.log_error("Failed to load platform module '%s': %s" % (module_name, str(e))) raise IOError("Failed to load platform module '%s': %s" % (module_name, str(e)))
return None
try: try:
platform_util_class = getattr(module, class_name) platform_util_class = getattr(module, class_name)
@ -136,8 +178,10 @@ class DaemonBase(object):
else: else:
platform_util = platform_util_class() platform_util = platform_util_class()
except AttributeError, e: except AttributeError, e:
self.log_error("Failed to instantiate '%s' class: %s" % (class_name, str(e))) raise AttributeError("Failed to instantiate '%s' class: %s" % (class_name, str(e)))
return None
return platform_util return platform_util
# Runs daemon
def run(self):
raise NotImplementedError()