diff --git a/.release b/.release index 11be6e82dbc6a5a022c2ee6635a426a294bd4c15..9c6ab870c4320b0bac96a3c660900e5b8c98d0fc 100644 --- a/.release +++ b/.release @@ -1,2 +1,2 @@ -release=0.1.4 -tag=lmcbaseclasses-0.1.4 +release=0.2.0 +tag=lmcbaseclasses-0.2.0 diff --git a/Makefile b/Makefile index 206f4c49f2db5fbb5ea131dae5f53858fe57e8f6..886f9c3a3c2acc7dfd43235a4382977707b1098c 100644 --- a/Makefile +++ b/Makefile @@ -118,11 +118,9 @@ make = tar -c test-harness/ | \ docker run -i --rm --network=$(NETWORK_MODE) \ -e TANGO_HOST=$(TANGO_HOST) \ -v $(CACHE_VOLUME):/home/tango/.cache \ - --volumes-from=$(CONTAINER_NAME_PREFIX)rsyslog-lmcbaseclasses:rw \ -v /build -w /build -u tango $(DOCKER_RUN_ARGS) $(IMAGE_TO_TEST) \ bash -c "sudo chown -R tango:tango /build && \ tar x --strip-components 1 --warning=all && \ - sudo ln -sf /var/run/rsyslog/dev/log /dev/log && \ make TANGO_HOST=$(TANGO_HOST) $1" test: DOCKER_RUN_ARGS = --volumes-from=$(BUILD) @@ -158,7 +156,7 @@ piplock: build ## overwrite Pipfile.lock with the image version interactive: up interactive: ## start an interactive session using the project image (caution: R/W mounts source directory to /app) docker run --rm -it -p 3000:3000 --name=$(CONTAINER_NAME_PREFIX)dev -e TANGO_HOST=$(TANGO_HOST) --network=$(NETWORK_MODE) \ - -v $(CURDIR):/app --volumes-from=$(CONTAINER_NAME_PREFIX)rsyslog-lmcbaseclasses:rw $(IMAGE_TO_TEST) /bin/bash + -v $(CURDIR):/app $(IMAGE_TO_TEST) /bin/bash down: ## stop develop/test environment and any interactive session docker ps | grep $(CONTAINER_NAME_PREFIX)dev && docker stop $(PROJECT)-dev || true diff --git a/docker-compose.yml b/docker-compose.yml index cf28383fbfe80c94b73c8241b353009ce98939b6..79923c01ec9dea8dc33d141d5e63faefac76d179 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,12 +1,10 @@ # # Docker compose file for LMC Base classes. # Contains services for TANGO database, database device server. -# Also uses rsyslog service # # Defines: # - tangodb: MariaDB database with TANGO schema # - databaseds: TANGO database device server -# - rsyslog-lmcbaseclasses:Container which provice rsyslog service for local logging # - basedevice: Container having SKABaseDevice class # - alarmhandler: Container having SKAAlarmHandler class # - capability: Container having SKACapability class @@ -30,8 +28,6 @@ services: restart: unless-stopped network_mode: ${NETWORK_MODE} container_name: ${CONTAINER_NAME_PREFIX}tangodb - depends_on: - - rsyslog-lmcbaseclasses environment: - MYSQL_ROOT_PASSWORD=secret - MYSQL_DATABASE=tango @@ -64,18 +60,11 @@ services: - -ORBendPoint - giop:tcp::10000 - rsyslog-lmcbaseclasses: - image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/rsyslog:latest - restart: unless-stopped - container_name: ${CONTAINER_NAME_PREFIX}rsyslog-lmcbaseclasses - network_mode: ${NETWORK_MODE} - basedevice: image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/lmcbaseclasses:latest restart: unless-stopped depends_on: - databaseds - - rsyslog-lmcbaseclasses network_mode: ${NETWORK_MODE} container_name: ${CONTAINER_NAME_PREFIX}basedevice environment: @@ -83,17 +72,13 @@ services: command: > sh -c "wait-for-it.sh ${TANGO_HOST} --timeout=30 --strict -- tango_admin --add-server SKABaseDevice/01 SKABaseDevice ska/basedevice/01 &&\ - sudo ln -sf /var/run/rsyslog/dev/log /dev/log &&\ /venv/bin/python /app/skabase/SKABaseDevice/SKABaseDevice.py 01" - volumes_from: - - rsyslog-lmcbaseclasses:rw alarmhandler: image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/lmcbaseclasses:latest restart: unless-stopped depends_on: - databaseds - - rsyslog-lmcbaseclasses network_mode: ${NETWORK_MODE} container_name: ${CONTAINER_NAME_PREFIX}alarmhandler environment: @@ -101,17 +86,13 @@ services: command: > sh -c "wait-for-it.sh ${TANGO_HOST} --timeout=30 --strict -- tango_admin --add-server SKAAlarmHandler/01 SKAAlarmhandler ska/alarmhandler/01 &&\ - sudo ln -sf /var/run/rsyslog/dev/log /dev/log &&\ /venv/bin/python /app/skabase/SKAAlarmHandler/SKAAlarmHandler.py 01" - volumes_from: - - rsyslog-lmcbaseclasses:rw capability: image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/lmcbaseclasses:latest restart: unless-stopped depends_on: - databaseds - - rsyslog-lmcbaseclasses network_mode: ${NETWORK_MODE} container_name: ${CONTAINER_NAME_PREFIX}capability environment: @@ -119,17 +100,13 @@ services: command: > sh -c "wait-for-it.sh ${TANGO_HOST} --timeout=30 --strict -- tango_admin --add-server SKACapability/01 SKACapability ska/capability/01 &&\ - sudo ln -sf /var/run/rsyslog/dev/log /dev/log &&\ /venv/bin/python /app/skabase/SKACapability/SKACapability.py 01" - volumes_from: - - rsyslog-lmcbaseclasses:rw logger: image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/lmcbaseclasses:latest restart: unless-stopped depends_on: - databaseds - - rsyslog-lmcbaseclasses network_mode: ${NETWORK_MODE} container_name: ${CONTAINER_NAME_PREFIX}logger environment: @@ -137,17 +114,13 @@ services: command: > sh -c "wait-for-it.sh ${TANGO_HOST} --timeout=30 --strict -- tango_admin --add-server SKALogger/01 SKALogger ska/logger/01 &&\ - sudo ln -sf /var/run/rsyslog/dev/log /dev/log &&\ /venv/bin/python /app/skabase/SKALogger/SKALogger.py 01" - volumes_from: - - rsyslog-lmcbaseclasses:rw master: image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/lmcbaseclasses:latest restart: unless-stopped depends_on: - databaseds - - rsyslog-lmcbaseclasses network_mode: ${NETWORK_MODE} container_name: ${CONTAINER_NAME_PREFIX}master environment: @@ -155,17 +128,13 @@ services: command: > sh -c "wait-for-it.sh ${TANGO_HOST} --timeout=30 --strict -- tango_admin --add-server SKAMaster/01 SKAMaster ska/master/01 &&\ - sudo ln -sf /var/run/rsyslog/dev/log /dev/log &&\ /venv/bin/python /app/skabase/SKAMaster/SKAMaster.py 01" - volumes_from: - - rsyslog-lmcbaseclasses:rw obsdevice: image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/lmcbaseclasses:latest restart: unless-stopped depends_on: - databaseds - - rsyslog-lmcbaseclasses network_mode: ${NETWORK_MODE} container_name: ${CONTAINER_NAME_PREFIX}obsdevice environment: @@ -173,17 +142,13 @@ services: command: > sh -c "wait-for-it.sh ${TANGO_HOST} --timeout=30 --strict -- tango_admin --add-server SKAObsDevice/01 SKAObsDevice ska/obsdevice/01 &&\ - sudo ln -sf /var/run/rsyslog/dev/log /dev/log &&\ /venv/bin/python /app/skabase/SKAObsDevice/SKAObsDevice.py 01" - volumes_from: - - rsyslog-lmcbaseclasses:rw subarray: image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/lmcbaseclasses:latest restart: unless-stopped depends_on: - databaseds - - rsyslog-lmcbaseclasses network_mode: ${NETWORK_MODE} container_name: ${CONTAINER_NAME_PREFIX}subarray environment: @@ -191,17 +156,13 @@ services: command: > sh -c "wait-for-it.sh ${TANGO_HOST} --timeout=30 --strict -- tango_admin --add-server SKASubarray/01 SKASubarray ska/subarray/01 &&\ - sudo ln -sf /var/run/rsyslog/dev/log /dev/log &&\ /venv/bin/python /app/skabase/SKASubarray/SKASubarray.py 01" - volumes_from: - - rsyslog-lmcbaseclasses:rw telstate: image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/lmcbaseclasses:latest restart: unless-stopped depends_on: - databaseds - - rsyslog-lmcbaseclasses network_mode: ${NETWORK_MODE} container_name: ${CONTAINER_NAME_PREFIX}telstate environment: @@ -209,17 +170,13 @@ services: command: > sh -c "wait-for-it.sh ${TANGO_HOST} --timeout=30 --strict -- tango_admin --add-server SKATelState/01 SKATelState ska/telstate/01 &&\ - sudo ln -sf /var/run/rsyslog/dev/log /dev/log &&\ /venv/bin/python /app/skabase/SKATelState/SKATelState.py 01" - volumes_from: - - rsyslog-lmcbaseclasses:rw testdevice: image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/lmcbaseclasses:latest restart: unless-stopped depends_on: - databaseds - - rsyslog-lmcbaseclasses network_mode: ${NETWORK_MODE} container_name: ${CONTAINER_NAME_PREFIX}testdevice environment: @@ -227,7 +184,4 @@ services: command: > sh -c "wait-for-it.sh ${TANGO_HOST} --timeout=30 --strict -- tango_admin --add-server SKATestDevice/01 SKATestDevice logger/test/1 &&\ - sudo ln -sf /var/run/rsyslog/dev/log /dev/log &&\ /venv/bin/python /app/skabase/SKATestDevice/SKATestDevice.py 01" - volumes_from: - - rsyslog-lmcbaseclasses:rw \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index 37a23b80d72cab290d928109a409d31739894376..5f9606aa2fbed97d87cc60a010fabff9e054350c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -8,4 +8,4 @@ source = skabase [tool:pytest] testpaths = skabase addopts = --forked --verbose --json-report --json-report-file=htmlcov/report.json --cov-report term --cov-report html --cov-report xml --cov=skabase --junitxml=/build/reports/unit-tests.xml -console_output_style = progress \ No newline at end of file +console_output_style = progress diff --git a/skabase/SKAAlarmHandler/SKAAlarmHandler.xmi b/skabase/SKAAlarmHandler/SKAAlarmHandler.xmi index 2253e8c085c9173add88ba93b1719d2aaa2cafb8..414fcbbf891a2ad041cdca54845a96fe94c7b06d 100644 --- a/skabase/SKAAlarmHandler/SKAAlarmHandler.xmi +++ b/skabase/SKAAlarmHandler/SKAAlarmHandler.xmi @@ -23,18 +23,15 @@ <type xsi:type="pogoDsl:StringVectorType"/> <status abstract="false" inherited="true" concrete="true"/> </deviceProperties> - <deviceProperties name="CentralLoggingTarget" description="Pre-configured logging target CentralLogger DS"> - <type xsi:type="pogoDsl:StringType"/> - <status abstract="false" inherited="true" concrete="true"/> - </deviceProperties> - <deviceProperties name="ElementLoggingTarget" description="Pre-configured logging target ElementLogger DS"> - <type xsi:type="pogoDsl:StringType"/> + <deviceProperties name="LoggingLevelDefault" description="Default logging level at device startup.
(0=OFF, 1=FATAL, 2=ERROR, 3=WARNING, 4=INFO, 5=DEBUG)"> + <type xsi:type="pogoDsl:UShortType"/> <status abstract="false" inherited="true" concrete="true"/> + <DefaultPropValue>4</DefaultPropValue> </deviceProperties> - <deviceProperties name="StorageLoggingTarget" description="Pre-configured logging target for syslog"> - <type xsi:type="pogoDsl:StringType"/> + <deviceProperties name="LoggingTargetsDefault" description="Default logging targets at device startup.
Each item has the format: target_type::target_name.
To log to stdout, use 'console::cout'.
To log to syslog, use 'syslog::<address>',
 where <address> is a file path,
 for example 'syslog::/var/run/rsyslog/dev/log'.
To log to a file, use 'file::<path>',
 where <path> is a file path,
 for example 'file::/tmp/my_dev.log'."> + <type xsi:type="pogoDsl:StringVectorType"/> <status abstract="false" inherited="true" concrete="true"/> - <DefaultPropValue>localhost</DefaultPropValue> + <DefaultPropValue>console::cout</DefaultPropValue> </deviceProperties> <commands name="State" description="This command gets the device state (stored in its device_state data member) and returns it to the caller." execMethod="dev_state" displayLevel="OPERATOR" polledPeriod="0"> <argin description="none"> @@ -171,26 +168,12 @@ <status abstract="false" inherited="true" concrete="true"/> <properties description="Build state of this device" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> - <attributes name="centralLoggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true"> - <dataType xsi:type="pogoDsl:UShortType"/> - <changeEvent fire="false" libCheckCriteria="false"/> - <archiveEvent fire="false" libCheckCriteria="false"/> - <status abstract="false" inherited="true" concrete="true"/> - <properties description="Current logging level to Central logging target for this device - 
initialises to CentralLoggingLevelDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> - </attributes> - <attributes name="elementLoggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true"> - <dataType xsi:type="pogoDsl:UShortType"/> - <changeEvent fire="false" libCheckCriteria="false"/> - <archiveEvent fire="false" libCheckCriteria="false"/> - <status abstract="false" inherited="true" concrete="true"/> - <properties description="Current logging level to Element logging target for this device - 
initialises to ElementLoggingLevelDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> - </attributes> - <attributes name="storageLoggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" memorized="true" allocReadMember="true"> - <dataType xsi:type="pogoDsl:UShortType"/> + <attributes name="loggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true"> + <dataType xsi:type="pogoDsl:EnumType"/> <changeEvent fire="false" libCheckCriteria="false"/> <archiveEvent fire="false" libCheckCriteria="false"/> <status abstract="false" inherited="true" concrete="true"/> - <properties description="Current logging level to Syslog for this device - 
initialises from StorageLoggingLevelDefault on first execution of device.
Needs to be READ_WRITE To make it memorized - but writing this attribute should 
do the same as command SetStorageLoggingLevel to ensure the targets and adjustments
are made correctly" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + <properties description="Current logging level for this device - initialises to LoggingLevelDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> <attributes name="healthState" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true"> <dataType xsi:type="pogoDsl:EnumType"/> @@ -243,6 +226,14 @@ <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> <properties description="List of active alarms" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> + <attributes name="loggingTargets" attType="Spectrum" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="3" maxY="" allocReadMember="true" isDynamic="false"> + <dataType xsi:type="pogoDsl:StringType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <dataReadyEvent fire="false" libCheckCriteria="true"/> + <status abstract="false" inherited="true" concrete="true"/> + <properties description="Current logging targets for this device - 
initialises to LoggingTargetsDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> <states name="ON" description="This state could have been called OK or OPERATIONAL. It means that the device is in its operational state. (E.g. the power supply is giving its nominal current, th motor is ON and ready to move, the instrument is operating). This state is modified by the Attribute alarm checking of the DeviceImpl:dev_state method. i.e. if the State is ON and one attribute has its quality factor to ATTR_WARNING or ATTR_ALARM, then the State is modified to ALARM."> <status abstract="false" inherited="true" concrete="true"/> </states> diff --git a/skabase/SKAAlarmHandler/test/SKAAlarmHandler_test.py b/skabase/SKAAlarmHandler/test/SKAAlarmHandler_test.py index 7b0e4693456e3a23ec3d489df884323f1f8b18bd..142a75b3d3743206d55336c038ccfdbf2c1452ca 100644 --- a/skabase/SKAAlarmHandler/test/SKAAlarmHandler_test.py +++ b/skabase/SKAAlarmHandler/test/SKAAlarmHandler_test.py @@ -34,9 +34,7 @@ class TestSKAAlarmHandler(object): 'AlarmConfigFile': '', 'SkaLevel': '4', 'GroupDefinitions': '', - 'CentralLoggingTarget': '', - 'ElementLoggingTarget': '', - 'StorageLoggingTarget': 'localhost', + 'LoggingTargetsDefault': ['console::cout'] } @classmethod diff --git a/skabase/SKABaseDevice/SKABaseDevice.py b/skabase/SKABaseDevice/SKABaseDevice.py index a4c7e8b468ad6222b677b93ecd908a6525d45e67..97926aee8ffe00b39010e6e10031171d29d4264d 100644 --- a/skabase/SKABaseDevice/SKABaseDevice.py +++ b/skabase/SKABaseDevice/SKABaseDevice.py @@ -10,14 +10,18 @@ properties and commands of an SKA device. """ # PROTECTED REGION ID(SKABaseDevice.additionnal_import) ENABLED START # # Standard imports -import os -import sys +import enum import json import logging import logging.handlers +import os +import sys +import time + +from future.utils import with_metaclass +from logging import StreamHandler from logging.handlers import SysLogHandler from logging.handlers import RotatingFileHandler -from future.utils import with_metaclass # Tango imports import tango @@ -36,13 +40,128 @@ from utils import (get_dp_command, coerce_value, get_groups_from_json, get_tango_device_type_id) +from faults import (GroupDefinitionsError, + LoggingTargetError, + LoggingLevelError) + +LOG_FILE_SIZE = 1024 * 1024 # Log file size 1MB. + -from faults import GroupDefinitionsError +class TangoLoggingLevel(enum.IntEnum): + """Python enumerated type for TANGO logging levels. + + There is a tango.LogLevel type already, but this is a wrapper around + a C++ enum. The Python IntEnum type is more convenient. + """ + OFF = int(tango.LogLevel.LOG_OFF) + FATAL = int(tango.LogLevel.LOG_FATAL) + ERROR = int(tango.LogLevel.LOG_ERROR) + WARNING = int(tango.LogLevel.LOG_WARN) + INFO = int(tango.LogLevel.LOG_INFO) + DEBUG = int(tango.LogLevel.LOG_DEBUG) + + +def _sanitise_logging_targets(targets, device_name): + """Validate and return logging targets '<type>::<name>' strings. + + :param target: + List of candidate logging target strings, like '<type>[::<name>]' + + :param device_name: + TANGO device name, like 'domain/family/member', used + for the default file name + + :return: list of '<type>::<name>' strings, with default name, if applicable + + :raises: LoggingTargetError for invalid target string that cannot be corrected + """ + default_target_names = { + "console": "cout", + "file": "{}.log".format(device_name.replace("/", "_")), + "syslog": None} + + valid_targets = [] + for target in targets: + if "::" in target: + target_type, target_name = target.split("::", 1) + else: + target_type = target + target_name = None + if target_type not in default_target_names: + raise LoggingTargetError( + "Invalid target type: {} - options are {}".format( + target_type, list(default_target_names.keys()))) + if not target_name: + target_name = default_target_names[target_type] + if not target_name: + raise LoggingTargetError( + "Target name required for type {}".format(target_type)) + valid_target = "{}::{}".format(target_type, target_name) + valid_targets.append(valid_target) + + return valid_targets + + +def _create_logging_handler(target, device_name): + """Create a Python log handler based on the target type (console, file, syslog) + + :param target: Logging target for logger, <type>::<name> + + :param device_name: TANGO device name + + :return: StreamHandler, RotatingFileHandler, or SysLogHandler + """ + target_type, target_name = target.split("::", 1) + + class UTCFormatter(logging.Formatter): + converter = time.gmtime + + # Format defined here: + # https://developer.skatelescope.org/en/latest/development/logging-format.html + # VERSION "|" TIMESTAMP "|" SEVERITY "|" [THREAD-ID] "|" [FUNCTION] "|" [LINE-LOC] "|" + # [TAGS] "|" MESSAGE LF + formatter = UTCFormatter( + fmt="1|" + "%(asctime)s.%(msecs)03dZ|" + "%(levelname)s|" + "%(threadName)s|" + "%(funcName)s|" + "%(filename)s#%(lineno)d|" + "tango-device:{}|" + "%(message)s".format(device_name), + datefmt='%Y-%m-%dT%H:%M:%S') + + if target_type == "console": + handler = StreamHandler(sys.stdout) + elif target_type == "file": + log_file_name = target_name + handler = RotatingFileHandler(log_file_name, 'a', LOG_FILE_SIZE, 2, None, False) + elif target_type == "syslog": + handler = SysLogHandler(address=target_name, facility='syslog') + handler.setFormatter(formatter) + handler.name = target + return handler + + +def _update_logging_handlers(targets, logger, device_name): + old_targets = [handler.name for handler in logger.handlers] + added_targets = set(targets) - set(old_targets) + removed_targets = set(old_targets) - set(targets) + + for handler in list(logger.handlers): + if handler.name in removed_targets: + logger.removeHandler(handler) + for target in targets: + if target in added_targets: + handler = _create_logging_handler(target, device_name) + logger.addHandler(handler) + + logger.info('Logging targets set to %s', targets) -LOG_FILE_SIZE = 1024 * 1024 #Log file size 1MB. # PROTECTED REGION END # // SKABaseDevice.additionnal_import -__all__ = ["SKABaseDevice", "main"] + +__all__ = ["SKABaseDevice", "TangoLoggingLevel", "main"] class SKABaseDevice(with_metaclass(DeviceMeta, Device)): @@ -53,34 +172,29 @@ class SKABaseDevice(with_metaclass(DeviceMeta, Device)): def _init_logging(self): """ - This method initializes the logging mechanism. It first tries to create a syslog handler. - If syslog is not available then the logs are written to a file. + This method initializes the logging mechanism, based on default properties. - :parameter: None. + :param: None. :return: None. """ - try: - # Initialize logging - logging.basicConfig() - self.logger = logging.getLogger(__name__) - - formatter = logging.Formatter(fmt='%(module)s - [%(levelname)-8s] - %(message)s', - datefmt='%Y-%m-%d %H:%M:%S') - # Add syslog handler - syslog_handler = SysLogHandler(address='/var/run/rsyslog/dev/log', facility='syslog') - syslog_handler.setFormatter(formatter) - self.logger.addHandler(syslog_handler) - except EnvironmentError: - # Add rotaling file handler - log_file_name = self.get_name() - log_file_name = log_file_name.replace("/", "_") - log_file_name += ".log" - formatter = logging.Formatter(fmt='%(asctime)s - %(module)s - [%(levelname)-8s] - %(message)s', - datefmt='%Y-%m-%d %H:%M:%S') - filehandler = RotatingFileHandler(log_file_name, 'a', LOG_FILE_SIZE, 2, None, False) - filehandler.setFormatter(formatter) - self.logger.addHandler(filehandler) + self.logger = logging.getLogger(__name__) + # device may be reinitialised, so remove existing handlers + for handler in list(self.logger.handlers): + self.logger.removeHandler(handler) + # initialise using defaults in device properties + self._logging_level = None + self.write_loggingLevel(self.LoggingLevelDefault) + self.write_loggingTargets(self.LoggingTargetsDefault) + self.logger.debug('Logger initialised') + + # Monkey patch TANGO Logging System streams so they go to the Python + # logger instead + self.debug_stream = self.logger.debug + self.info_stream = self.logger.info + self.warn_stream = self.logger.warning + self.error_stream = self.logger.error + self.fatal_stream = self.logger.critical def _get_device_json(self, args_dict): """ @@ -230,82 +344,35 @@ class SKABaseDevice(with_metaclass(DeviceMeta, Device)): def dev_logging(self, dev_log_msg, dev_log_level): """ - This method logs the message to SKA Element Logger, Central Logger and Storage - Logger. + DEPRECATED: Log the message to the Python logger. - :param dev_log_msg: DevString. + DEPRECATED - Use ``self.logger`` directly instead. For example, + ``self.logger.info("My message")`` for something at LOG_INFO level. - Message to log + :param dev_log_msg: DevString. + Message to log :param dev_log_level: DevEnum - Logging level of the message. The message can have one of the following - logging level: + logging levels: LOG_FATAL - LOG_ERROR - LOG_WARN - LOG_INFO - LOG_DEBUG :return: None """ - # Element Level Logging - if self._element_logging_level >= int(tango.LogLevel.LOG_FATAL) and dev_log_level == int( - tango.LogLevel.LOG_FATAL): - self.fatal_stream(dev_log_msg) - elif self._element_logging_level >= int(tango.LogLevel.LOG_ERROR) and dev_log_level == int( - tango.LogLevel.LOG_ERROR): - self.error_stream(dev_log_msg) - elif self._element_logging_level >= int(tango.LogLevel.LOG_WARN) and dev_log_level == int( - tango.LogLevel.LOG_WARN): - self.warn_stream(dev_log_msg) - elif self._element_logging_level >= int(tango.LogLevel.LOG_INFO) and dev_log_level == int( - tango.LogLevel.LOG_INFO): - self.info_stream(dev_log_msg) - elif self._element_logging_level >= int(tango.LogLevel.LOG_DEBUG) and dev_log_level == int( - tango.LogLevel.LOG_DEBUG): - self.debug_stream(dev_log_msg) - - # Central Level Logging - if self._central_logging_level >= int(tango.LogLevel.LOG_FATAL) and dev_log_level == int( - tango.LogLevel.LOG_FATAL): - self.fatal_stream(dev_log_msg) - elif self._central_logging_level >= int(tango.LogLevel.LOG_ERROR) and dev_log_level == int( - tango.LogLevel.LOG_ERROR): - self.error_stream(dev_log_msg) - elif self._central_logging_level >= int(tango.LogLevel.LOG_WARN) and dev_log_level == int( - tango.LogLevel.LOG_WARN): - self.warn_stream(dev_log_msg) - elif self._central_logging_level >= int(tango.LogLevel.LOG_INFO) and dev_log_level == int( - tango.LogLevel.LOG_INFO): - self.info_stream(dev_log_msg) - elif self._central_logging_level >= int(tango.LogLevel.LOG_DEBUG) and dev_log_level == int( - tango.LogLevel.LOG_DEBUG): - self.debug_stream(dev_log_msg) - - # Storage Level Logging - if self._storage_logging_level >= int(tango.LogLevel.LOG_FATAL) and dev_log_level == int( - tango.LogLevel.LOG_FATAL): + if dev_log_level == TangoLoggingLevel.FATAL: self.logger.fatal(dev_log_msg) - elif self._storage_logging_level >= int(tango.LogLevel.LOG_ERROR) and dev_log_level == int( - tango.LogLevel.LOG_ERROR): + elif dev_log_level == TangoLoggingLevel.ERROR: self.logger.error(dev_log_msg) - elif self._storage_logging_level >= int(tango.LogLevel.LOG_WARN) and dev_log_level == int( - tango.LogLevel.LOG_WARN): + elif dev_log_level == TangoLoggingLevel.WARNING: self.logger.warning(dev_log_msg) - elif self._storage_logging_level >= int(tango.LogLevel.LOG_INFO) and dev_log_level == int( - tango.LogLevel.LOG_INFO): + elif dev_log_level == TangoLoggingLevel.INFO: self.logger.info(dev_log_msg) - elif self._storage_logging_level >= int(tango.LogLevel.LOG_DEBUG) and dev_log_level == int( - tango.LogLevel.LOG_DEBUG): + elif dev_log_level == TangoLoggingLevel.DEBUG: self.logger.debug(dev_log_msg) - else: - pass - # PROTECTED REGION END # // SKABaseDevice.class_variable @@ -321,16 +388,12 @@ class SKABaseDevice(with_metaclass(DeviceMeta, Device)): dtype=('str',), ) - CentralLoggingTarget = device_property( - dtype='str', + LoggingLevelDefault = device_property( + dtype='uint16', default_value=4 ) - ElementLoggingTarget = device_property( - dtype='str', - ) - - StorageLoggingTarget = device_property( - dtype='str', default_value="localhost" + LoggingTargetsDefault = device_property( + dtype='DevVarStringArray', default_value=["console::cout"] ) # ---------- @@ -347,30 +410,19 @@ class SKABaseDevice(with_metaclass(DeviceMeta, Device)): doc="Version Id of this device", ) - centralLoggingLevel = attribute( - dtype='uint16', - access=AttrWriteType.READ_WRITE, - doc="Current logging level to Central logging target for this device - " - "\ninitialises to CentralLoggingLevelDefault on startup", - ) - - elementLoggingLevel = attribute( - dtype='uint16', + loggingLevel = attribute( + dtype=TangoLoggingLevel, access=AttrWriteType.READ_WRITE, - doc="Current logging level to Element logging target for this device - " - "\ninitialises to ElementLoggingLevelDefault on startup", + doc="Current logging level for this device - " + "initialises to LoggingLevelDefault on startup", ) - storageLoggingLevel = attribute( - dtype='uint16', + loggingTargets = attribute( + dtype=('str',), access=AttrWriteType.READ_WRITE, - memorized=True, - doc="Current logging level to Syslog for this device - " - "initialises from StorageLoggingLevelDefault on first " - "execution of device.Needs to be READ_WRITE To make it" - " memorized - but writing this attribute should do the " - "same as command SetStorageLoggingLevel to ensure the " - "targets and adjustmentsare made correctly", + max_dim_x=3, + doc="Current logging targets for this device" + " - initialises to LoggingTargetsDefault on startup", ) healthState = attribute( @@ -433,16 +485,12 @@ class SKABaseDevice(with_metaclass(DeviceMeta, Device)): Device.init_device(self) # PROTECTED REGION ID(SKABaseDevice.init_device) ENABLED START # - # Start sysLogHandler self._init_logging() # Initialize attribute values. self._build_state = '{}, {}, {}'.format(release.name, release.version, release.description) self._version_id = release.version - self._central_logging_level = int(tango.LogLevel.LOG_OFF) - self._element_logging_level = int(tango.LogLevel.LOG_OFF) - self._storage_logging_level = int(tango.LogLevel.LOG_OFF) self._health_state = 0 self._admin_mode = 0 self._control_mode = 0 @@ -458,6 +506,7 @@ class SKABaseDevice(with_metaclass(DeviceMeta, Device)): except GroupDefinitionsError: self.info_stream("No Groups loaded for device: {}".format(self.get_name())) + self.logger.info("Completed SKABaseDevice.init_device") # PROTECTED REGION END # // SKABaseDevice.init_device def always_executed_hook(self): @@ -502,83 +551,68 @@ class SKABaseDevice(with_metaclass(DeviceMeta, Device)): return self._version_id # PROTECTED REGION END # // SKABaseDevice.versionId_read - def read_centralLoggingLevel(self): - # PROTECTED REGION ID(SKABaseDevice.centralLoggingLevel_read) ENABLED START # - """ - Reads the central logging level of the device. - - :return: Central logging level of the device - """ - return self._central_logging_level - # PROTECTED REGION END # // SKABaseDevice.centralLoggingLevel_read - - def write_centralLoggingLevel(self, value): - # PROTECTED REGION ID(SKABaseDevice.centralLoggingLevel_write) ENABLED START # - """ - Sets central logging level of the device - - :param value: Logging level for Central Logger - - :return: None + def read_loggingLevel(self): + # PROTECTED REGION ID(SKABaseDevice.loggingLevel_read) ENABLED START # """ - self._central_logging_level = value - # PROTECTED REGION END # // SKABaseDevice.centralLoggingLevel_write + Reads logging level of the device. - def read_elementLoggingLevel(self): - # PROTECTED REGION ID(SKABaseDevice.elementLoggingLevel_read) ENABLED START # + :return: Logging level of the device. """ - Reads element logging level of the device. + return self._logging_level + # PROTECTED REGION END # // SKABaseDevice.loggingLevel_read - :return: Element logging level of the device. + def write_loggingLevel(self, value): + # PROTECTED REGION ID(SKABaseDevice.loggingLevel_write) ENABLED START # """ - return self._element_logging_level - # PROTECTED REGION END # // SKABaseDevice.elementLoggingLevel_read + Sets logging level for the device. - def write_elementLoggingLevel(self, value): - # PROTECTED REGION ID(SKABaseDevice.elementLoggingLevel_write) ENABLED START # - """ - Sets element logging level of the device + :param value: Logging level for logger - :param value: Logging Level for Element Logger - - :return: None + :return: None. """ - self._element_logging_level = value - # PROTECTED REGION END # // SKABaseDevice.elementLoggingLevel_write + self._logging_level = TangoLoggingLevel(value) + if self._logging_level == TangoLoggingLevel.OFF: + self.logger.setLevel(logging.CRITICAL) # not allowed to be "off" + elif self._logging_level == TangoLoggingLevel.FATAL: + self.logger.setLevel(logging.CRITICAL) + elif self._logging_level == TangoLoggingLevel.ERROR: + self.logger.setLevel(logging.ERROR) + elif self._logging_level == TangoLoggingLevel.WARNING: + self.logger.setLevel(logging.WARNING) + elif self._logging_level == TangoLoggingLevel.INFO: + self.logger.setLevel(logging.INFO) + elif self._logging_level == TangoLoggingLevel.DEBUG: + self.logger.setLevel(logging.DEBUG) + else: + raise LoggingLevelError( + "Invalid level - {} - must be between {} and {}".format( + self._logging_level, TangoLoggingLevel.OFF, TangoLoggingLevel.DEBUG)) + self.logger.info('Logging level set to %s', self._logging_level) + # PROTECTED REGION END # // SKABaseDevice.loggingLevel_write - def read_storageLoggingLevel(self): - # PROTECTED REGION ID(SKABaseDevice.storageLoggingLevel_read) ENABLED START # + def read_loggingTargets(self): + # PROTECTED REGION ID(SKABaseDevice.loggingTargets_read) ENABLED START # """ - Reads storage logging level of the device. + Reads logging level of the device. - :return: Storage logging level of the device. + :return: Logging level of the device. """ - return self._storage_logging_level - # PROTECTED REGION END # // SKABaseDevice.storageLoggingLevel_read + return [str(handler.name) for handler in self.logger.handlers] + # PROTECTED REGION END # // SKABaseDevice.loggingTargets_read - def write_storageLoggingLevel(self, value): - # PROTECTED REGION ID(SKABaseDevice.storageLoggingLevel_write) ENABLED START # + def write_loggingTargets(self, value): + # PROTECTED REGION ID(SKABaseDevice.loggingTargets_write) ENABLED START # """ - Sets logging level at storage. + Sets logging level for the device. - :param value: Logging Level for storage logger + :param value: Logging targets for logger :return: None. """ - self._storage_logging_level = value - if self._storage_logging_level == int(tango.LogLevel.LOG_FATAL): - self.logger.setLevel(logging.FATAL) - elif self._storage_logging_level == int(tango.LogLevel.LOG_ERROR): - self.logger.setLevel(logging.ERROR) - elif self._storage_logging_level == int(tango.LogLevel.LOG_WARN): - self.logger.setLevel(logging.WARNING) - elif self._storage_logging_level == int(tango.LogLevel.LOG_INFO): - self.logger.setLevel(logging.INFO) - elif self._storage_logging_level == int(tango.LogLevel.LOG_DEBUG): - self.logger.setLevel(logging.DEBUG) - else: - self.logger.setLevel(logging.DEBUG) - # PROTECTED REGION END # // SKABaseDevice.storageLoggingLevel_write + device_name = self.get_name() + valid_targets = _sanitise_logging_targets(value, device_name) + _update_logging_handlers(valid_targets, self.logger, device_name) + # PROTECTED REGION END # // SKABaseDevice.loggingTargets_write def read_healthState(self): # PROTECTED REGION ID(SKABaseDevice.healthState_read) ENABLED START # @@ -723,6 +757,8 @@ def main(args=None, **kwargs): :return: """ + # Do basic logging config before starting any threads + logging.basicConfig() return run((SKABaseDevice,), args=args, **kwargs) # PROTECTED REGION END # // SKABaseDevice.main diff --git a/skabase/SKABaseDevice/SKABaseDevice.xmi b/skabase/SKABaseDevice/SKABaseDevice.xmi index 4cf6513f28adc93a3d623ca3a6354d7d771e6b97..6de185c82eec1f05c2d4f27913344d0e9dcd8c1e 100644 --- a/skabase/SKABaseDevice/SKABaseDevice.xmi +++ b/skabase/SKABaseDevice/SKABaseDevice.xmi @@ -14,18 +14,15 @@ <type xsi:type="pogoDsl:StringVectorType"/> <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> </deviceProperties> - <deviceProperties name="CentralLoggingTarget" description="Pre-configured logging target CentralLogger DS"> - <type xsi:type="pogoDsl:StringType"/> - <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> - </deviceProperties> - <deviceProperties name="ElementLoggingTarget" description="Pre-configured logging target ElementLogger DS"> - <type xsi:type="pogoDsl:StringType"/> + <deviceProperties name="LoggingLevelDefault" description="Default logging level at device startup.
(0=OFF, 1=FATAL, 2=ERROR, 3=WARNING, 4=INFO, 5=DEBUG)"> + <type xsi:type="pogoDsl:UShortType"/> <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> + <DefaultPropValue>4</DefaultPropValue> </deviceProperties> - <deviceProperties name="StorageLoggingTarget" description="Pre-configured logging target for syslog"> - <type xsi:type="pogoDsl:StringType"/> + <deviceProperties name="LoggingTargetsDefault" description="Default logging targets at device startup.
Each item has the format: target_type::target_name.
To log to stdout, use 'console::cout'.
To log to syslog, use 'syslog::<address>',
 where <address> is a file path,
 for example 'syslog::/var/run/rsyslog/dev/log'.
To log to a file, use 'file::<path>',
 where <path> is a file path,
 for example 'file::/tmp/my_dev.log'."> + <type xsi:type="pogoDsl:StringVectorType"/> <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> - <DefaultPropValue>localhost</DefaultPropValue> + <DefaultPropValue>console::cout</DefaultPropValue> </deviceProperties> <commands name="State" description="This command gets the device state (stored in its device_state data member) and returns it to the caller." execMethod="dev_state" displayLevel="OPERATOR" polledPeriod="0" isDynamic="false"> <argin description="none"> @@ -75,23 +72,19 @@ <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> <properties description="Version Id of this device" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> - <attributes name="centralLoggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true" isDynamic="false"> - <dataType xsi:type="pogoDsl:UShortType"/> - <dataReadyEvent fire="false" libCheckCriteria="true"/> - <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> - <properties description="Current logging level to Central logging target for this device - 
initialises to CentralLoggingLevelDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> - </attributes> - <attributes name="elementLoggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true" isDynamic="false"> - <dataType xsi:type="pogoDsl:UShortType"/> - <dataReadyEvent fire="false" libCheckCriteria="true"/> - <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> - <properties description="Current logging level to Element logging target for this device - 
initialises to ElementLoggingLevelDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> - </attributes> - <attributes name="storageLoggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" memorized="true" allocReadMember="true" isDynamic="false"> - <dataType xsi:type="pogoDsl:UShortType"/> + <attributes name="loggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true" isDynamic="false"> + <dataType xsi:type="pogoDsl:EnumType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> <dataReadyEvent fire="false" libCheckCriteria="true"/> <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> - <properties description="Current logging level to Syslog for this device - 
initialises from StorageLoggingLevelDefault on first execution of device.
Needs to be READ_WRITE To make it memorized - but writing this attribute should 
do the same as command SetStorageLoggingLevel to ensure the targets and adjustments
are made correctly" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + <properties description="Current logging level for this device - initialises to LoggingLevelDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + <enumLabels>OFF</enumLabels> + <enumLabels>FATAL</enumLabels> + <enumLabels>ERROR</enumLabels> + <enumLabels>WARNING</enumLabels> + <enumLabels>INFO</enumLabels> + <enumLabels>DEBUG</enumLabels> </attributes> <attributes name="healthState" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true" isDynamic="false"> <dataType xsi:type="pogoDsl:EnumType"/> @@ -134,6 +127,14 @@ <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> <properties description="The test mode of the device. 
Either no test mode (empty string) or an indication of the test mode." label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> + <attributes name="loggingTargets" attType="Spectrum" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="3" maxY="" allocReadMember="true" isDynamic="false"> + <dataType xsi:type="pogoDsl:StringType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <dataReadyEvent fire="false" libCheckCriteria="true"/> + <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> + <properties description="Current logging targets for this device - 
initialises to LoggingTargetsDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> <states name="ON" description="This state could have been called OK or OPERATIONAL. It means that the device is in its operational state. (E.g. the power supply is giving its nominal current, th motor is ON and ready to move, the instrument is operating). This state is modified by the Attribute alarm checking of the DeviceImpl:dev_state method. i.e. if the State is ON and one attribute has its quality factor to ATTR_WARNING or ATTR_ALARM, then the State is modified to ALARM."> <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> </states> diff --git a/skabase/SKABaseDevice/__init__.py b/skabase/SKABaseDevice/__init__.py index 33f676bf79b9d821585b8a3e3fef3842d54dd3df..5267121f247b0331d54e1696165257e6cbe8a23c 100644 --- a/skabase/SKABaseDevice/__init__.py +++ b/skabase/SKABaseDevice/__init__.py @@ -10,9 +10,9 @@ A generic base device for SKA. It exposes the attributes, properties and command a device that are common for all the SKA devices. """ -__all__ = ["SKABaseDevice", "main"] +__all__ = ["SKABaseDevice", "TangoLoggingLevel", "main"] from skabase import release -from .SKABaseDevice import SKABaseDevice, main +from .SKABaseDevice import SKABaseDevice, main, TangoLoggingLevel __version__ = release.version __version_info__ = release.version_info diff --git a/skabase/SKABaseDevice/test/SKABaseDevice_test.py b/skabase/SKABaseDevice/test/SKABaseDevice_test.py index aff6589a1bd20f35a8f2223fa961194adacc7e1c..c4c353dc0d2d66f149966e31476840b64200f32b 100644 --- a/skabase/SKABaseDevice/test/SKABaseDevice_test.py +++ b/skabase/SKABaseDevice/test/SKABaseDevice_test.py @@ -17,17 +17,106 @@ from tango import DevState # Imports from skabase.SKABaseDevice import SKABaseDevice -# PROTECTED REGION ID(SKABaseDevice.test_additional_imports) ENABLED START # -# PROTECTED REGION END # // SKABaseDevice.test_additional_imports # Path path = os.path.join(os.path.dirname(__file__), os.pardir) sys.path.insert(0, os.path.abspath(path)) # PROTECTED REGION ID(SKABaseDevice.test_additional_imports) ENABLED START # +import logging +import mock +from tango import DevFailed +from skabase.SKABaseDevice import TangoLoggingLevel +from skabase.SKABaseDevice.SKABaseDevice import ( + _create_logging_handler, + _sanitise_logging_targets, + _update_logging_handlers, + LoggingTargetError, +) # PROTECTED REGION END # // SKABaseDevice.test_additional_imports # Device test case # PROTECTED REGION ID(SKABaseDevice.test_SKABaseDevice_decorators) ENABLED START # + + +@pytest.fixture(params=[ + (["console"], ["console::cout"]), + (["console::"], ["console::cout"]), + (["console::cout"], ["console::cout"]), + (["console::anything"], ["console::anything"]), + (["file"], ["file::my_dev_name.log"]), + (["file::"], ["file::my_dev_name.log"]), + (["file::/tmp/dummy"], ["file::/tmp/dummy"]), + (["syslog::some/address"], ["syslog::some/address"]), + (["console", "file"], ["console::cout", "file::my_dev_name.log"]), + ]) +def good_logging_targets(request): + targets_in, expected = request.param + dev_name = "my/dev/name" + return targets_in, dev_name, expected + + +@pytest.fixture(params=[ + [""], + ["invalid"], + ["invalid", "console"], + ["invalid::type"], + ["syslog"], + ]) +def bad_logging_targets(request): + targets_in = request.param + dev_name = "my/dev/name" + return targets_in, dev_name + + +def test_sanitise_logging_targets_success(good_logging_targets): + targets_in, dev_name, expected = good_logging_targets + actual = _sanitise_logging_targets(targets_in, dev_name) + assert actual == expected + + +def test_sanitise_logging_targets_fail(bad_logging_targets): + targets_in, dev_name = bad_logging_targets + with pytest.raises(LoggingTargetError): + _sanitise_logging_targets(targets_in, dev_name) + + +def test_update_logging_handlers(): + logger = logging.Logger('testing') + dev_name = "my/dev/name" + + new_targets = ["console::cout"] + _update_logging_handlers(new_targets, logger, dev_name) + assert len(logger.handlers) == 1 + assert isinstance(logger.handlers[0], logging.StreamHandler) + + # test same handler is retained for same request + old_handler = logger.handlers[0] + new_targets = ["console::cout"] + _update_logging_handlers(new_targets, logger, dev_name) + assert len(logger.handlers) == 1 + assert logger.handlers[0] is old_handler + + # test other valid target types + new_targets = ["console::cout", "file::/tmp/dummy", "syslog::some/address"] + _update_logging_handlers(new_targets, logger, dev_name) + assert len(logger.handlers) == 3 + assert isinstance(logger.handlers[0], logging.StreamHandler) + assert isinstance(logger.handlers[1], logging.handlers.RotatingFileHandler) + assert isinstance(logger.handlers[2], logging.handlers.SysLogHandler) + + # test clearing of 1 handler + new_targets = ["console::cout", "syslog::some/address"] + _update_logging_handlers(new_targets, logger, dev_name) + assert len(logger.handlers) == 2 + assert isinstance(logger.handlers[0], logging.StreamHandler) + assert isinstance(logger.handlers[1], logging.handlers.SysLogHandler) + + # test clearing all handlers + new_targets = [] + _update_logging_handlers(new_targets, logger, dev_name) + assert len(logger.handlers) == 0 + + @pytest.mark.usefixtures("tango_context", "initialize_device") # PROTECTED REGION END # // SKABaseDevice.test_SKABaseDevice_decorators class TestSKABaseDevice(object): @@ -36,9 +125,7 @@ class TestSKABaseDevice(object): properties = { 'SkaLevel': '4', 'GroupDefinitions': '', - 'CentralLoggingTarget': '', - 'ElementLoggingTarget': '', - 'StorageLoggingTarget': 'localhost', + 'LoggingTargetsDefault': ['console::cout'] } @classmethod @@ -99,7 +186,6 @@ class TestSKABaseDevice(object): assert tango_context.device.Reset() is None # PROTECTED REGION END # // SKABaseDevice.test_Reset - # PROTECTED REGION ID(SKABaseDevice.test_buildState_decorators) ENABLED START # # PROTECTED REGION END # // SKABaseDevice.test_buildState_decorators def test_buildState(self, tango_context): @@ -120,29 +206,54 @@ class TestSKABaseDevice(object): assert (re.match(versionIdPattern, tango_context.device.versionId)) is not None # PROTECTED REGION END # // SKABaseDevice.test_versionId - # PROTECTED REGION ID(SKABaseDevice.test_centralLoggingLevel_decorators) ENABLED START # - # PROTECTED REGION END # // SKABaseDevice.test_centralLoggingLevel_decorators - def test_centralLoggingLevel(self, tango_context): - """Test for centralLoggingLevel""" - # PROTECTED REGION ID(SKABaseDevice.test_centralLoggingLevel) ENABLED START # - assert tango_context.device.centralLoggingLevel == 0 - # PROTECTED REGION END # // SKABaseDevice.test_centralLoggingLevel - - # PROTECTED REGION ID(SKABaseDevice.test_elementLoggingLevel_decorators) ENABLED START # - # PROTECTED REGION END # // SKABaseDevice.test_elementLoggingLevel_decorators - def test_elementLoggingLevel(self, tango_context): - """Test for elementLoggingLevel""" - # PROTECTED REGION ID(SKABaseDevice.test_elementLoggingLevel) ENABLED START # - assert tango_context.device.elementLoggingLevel == 0 - # PROTECTED REGION END # // SKABaseDevice.test_elementLoggingLevel - - # PROTECTED REGION ID(SKABaseDevice.test_storageLoggingLevel_decorators) ENABLED START # - # PROTECTED REGION END # // SKABaseDevice.test_storageLoggingLevel_decorators - def test_storageLoggingLevel(self, tango_context): - """Test for storageLoggingLevel""" - # PROTECTED REGION ID(SKABaseDevice.test_storageLoggingLevel) ENABLED START # - assert tango_context.device.storageLoggingLevel == 0 - # PROTECTED REGION END # // SKABaseDevice.test_storageLoggingLevel + # PROTECTED REGION ID(SKABaseDevice.test_loggingLevel_decorators) ENABLED START # + # PROTECTED REGION END # // SKABaseDevice.test_loggingLevel_decorators + def test_loggingLevel(self, tango_context): + """Test for loggingLevel""" + # PROTECTED REGION ID(SKABaseDevice.test_loggingLevel) ENABLED START # + assert tango_context.device.loggingLevel == TangoLoggingLevel.INFO + + for level in TangoLoggingLevel: + tango_context.device.loggingLevel = level + assert tango_context.device.loggingLevel == level + + with pytest.raises(DevFailed): + tango_context.device.loggingLevel = TangoLoggingLevel.FATAL + 100 + # PROTECTED REGION END # // SKABaseDevice.test_loggingLevel + + # PROTECTED REGION ID(SKABaseDevice.test_loggingTargets_decorators) ENABLED START # + # PROTECTED REGION END # // SKABaseDevice.test_loggingTargets_decorators + def test_loggingTargets(self, tango_context): + """Test for loggingTargets""" + # PROTECTED REGION ID(SKABaseDevice.test_loggingTargets) ENABLED START # + assert tango_context.device.loggingTargets == ("console::cout",) + + with mock.patch("SKABaseDevice._create_logging_handler") as mocked_creator: + + def null_creator(target, device_name): + handler = logging.NullHandler() + handler.name = target + return handler + + mocked_creator.side_effect = null_creator + device_fqdn = tango_context.get_device_access() + + # test adding file and syslog targets (already have console) + tango_context.device.loggingTargets = [ + "console::cout", "file::/tmp/dummy", "syslog::some/address"] + assert tango_context.device.loggingTargets == ( + "console::cout", "file::/tmp/dummy", "syslog::some/address") + mocked_creator.call_count == 2 + mocked_creator.assert_has_calls( + [mock.call("file::/tmp/dummy", device_fqdn), + mock.call("syslog::some/address", device_fqdn)], + any_order=True) + + mocked_creator.reset_mock() + with pytest.raises(DevFailed): + tango_context.device.loggingTargets = ["invalid::type"] + mocked_creator.assert_not_called() + # PROTECTED REGION END # // SKABaseDevice.test_loggingTargets # PROTECTED REGION ID(SKABaseDevice.test_healthState_decorators) ENABLED START # # PROTECTED REGION END # // SKABaseDevice.test_healthState_decorators @@ -197,8 +308,8 @@ class TestSKABaseDevice(object): # assert attributes == 1 def test__parse_argin(self, tango_context): - SKABaseDevice._init_logging(SKABaseDevice) - result = SKABaseDevice._parse_argin(SKABaseDevice,'{"class":"SKABaseDevice"}') + SKABaseDevice.logger = mock.Mock() + result = SKABaseDevice._parse_argin(SKABaseDevice, '{"class": "SKABaseDevice"}') assert result == {'class': 'SKABaseDevice'} # TODO: Fix this test case when "__DeviceImpl__debug_stream() missing 'msg' argument" is resolved. @@ -209,4 +320,4 @@ class TestSKABaseDevice(object): # result = SKABaseDevice.dev_logging(SKABaseDevice, "test message", int(tango.LogLevel.LOG_DEBUG)) # result = [] # SKABaseDevice.error_stream(SKABaseDevice, "Syslog cannot be initialized") - # assert result == None \ No newline at end of file + # assert result == None diff --git a/skabase/SKACapability/SKACapability.xmi b/skabase/SKACapability/SKACapability.xmi index 3bbcfde5de076f478313c470ac1a713756f46fae..3b89f5c458ef4f63dd372daca3eebe55d1efddac 100644 --- a/skabase/SKACapability/SKACapability.xmi +++ b/skabase/SKACapability/SKACapability.xmi @@ -11,18 +11,15 @@ <status abstract="false" inherited="true" concrete="true"/> <DefaultPropValue>4</DefaultPropValue> </deviceProperties> - <deviceProperties name="CentralLoggingTarget" description="Pre-configured logging target CentralLogger DS"> - <type xsi:type="pogoDsl:StringType"/> - <status abstract="false" inherited="true" concrete="true"/> - </deviceProperties> - <deviceProperties name="ElementLoggingTarget" description="Pre-configured logging target ElementLogger DS"> - <type xsi:type="pogoDsl:StringType"/> + <deviceProperties name="LoggingLevelDefault" description="Default logging level at device startup.
(0=OFF, 1=FATAL, 2=ERROR, 3=WARNING, 4=INFO, 5=DEBUG)"> + <type xsi:type="pogoDsl:UShortType"/> <status abstract="false" inherited="true" concrete="true"/> + <DefaultPropValue>4</DefaultPropValue> </deviceProperties> - <deviceProperties name="StorageLoggingTarget" description="Pre-configured logging target for syslog"> - <type xsi:type="pogoDsl:StringType"/> + <deviceProperties name="LoggingTargetsDefault" description="Default logging targets at device startup.
Each item has the format: target_type::target_name.
To log to stdout, use 'console::cout'.
To log to syslog, use 'syslog::<address>',
 where <address> is a file path,
 for example 'syslog::/var/run/rsyslog/dev/log'.
To log to a file, use 'file::<path>',
 where <path> is a file path,
 for example 'file::/tmp/my_dev.log'."> + <type xsi:type="pogoDsl:StringVectorType"/> <status abstract="false" inherited="true" concrete="true"/> - <DefaultPropValue>localhost</DefaultPropValue> + <DefaultPropValue>console::cout</DefaultPropValue> </deviceProperties> <deviceProperties name="GroupDefinitions" description="Each string in the list is a JSON serialised dict defining the ``group_name``,
``devices`` and ``subgroups`` in the group. A TANGO Group object is created
for each item in the list, according to the hierarchy defined. This provides
easy access to the managed devices in bulk, or individually.

The general format of the list is as follows, with optional ``devices`` and
``subgroups`` keys:
 [ {``group_name``: ``<name>``,
 ``devices``: [``<dev name>``, ...]},
 {``group_name``: ``<name>``,
 ``devices``: [``<dev name>``, ``<dev name>``, ...],
 ``subgroups`` : [{<nested group>},
 {<nested group>}, ...]},
 ...
 ]

For example, a hierarchy of racks, servers and switches:
 [ {``group_name``: ``servers``,
 ``devices``: [``elt/server/1``, ``elt/server/2``,
 ``elt/server/3``, ``elt/server/4``]},
 {``group_name``: ``switches``,
 ``devices``: [``elt/switch/A``, ``elt/switch/B``]},
 {``group_name``: ``pdus``,
 ``devices``: [``elt/pdu/rackA``, ``elt/pdu/rackB``]},
 {``group_name``: ``racks``,
 ``subgroups``: [
 {``group_name``: ``rackA``,
 ``devices``: [``elt/server/1``, ``elt/server/2``,
 ``elt/switch/A``, ``elt/pdu/rackA``]},
 {``group_name``: ``rackB``,
 ``devices``: [``elt/server/3``, ``elt/server/4``,
 ``elt/switch/B``, ``elt/pdu/rackB``],
 ``subgroups``: []}
 ]} ]"> <type xsi:type="pogoDsl:StringVectorType"/> @@ -132,20 +129,12 @@ <status abstract="false" inherited="true" concrete="true"/> <properties description="Build state of this device" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> - <attributes name="centralLoggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true"> - <dataType xsi:type="pogoDsl:UShortType"/> - <status abstract="false" inherited="true" concrete="true"/> - <properties description="Current logging level to Central logging target for this device - 
initialises to CentralLoggingLevelDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> - </attributes> - <attributes name="elementLoggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true"> - <dataType xsi:type="pogoDsl:UShortType"/> - <status abstract="false" inherited="true" concrete="true"/> - <properties description="Current logging level to Element logging target for this device - 
initialises to ElementLoggingLevelDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> - </attributes> - <attributes name="storageLoggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" memorized="true" allocReadMember="true"> - <dataType xsi:type="pogoDsl:UShortType"/> + <attributes name="loggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true"> + <dataType xsi:type="pogoDsl:EnumType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> <status abstract="false" inherited="true" concrete="true"/> - <properties description="Current logging level to Syslog for this device - 
initialises from StorageLoggingLevelDefault on first execution of device.
Needs to be READ_WRITE To make it memorized - but writing this attribute should 
do the same as command SetStorageLoggingLevel to ensure the targets and adjustments
are made correctly" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + <properties description="Current logging level for this device - initialises to LoggingLevelDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> <attributes name="healthState" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true"> <dataType xsi:type="pogoDsl:EnumType"/> @@ -180,6 +169,14 @@ <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> <properties description="Number of instances of this Capability Type currently in use on this subarray." label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> + <attributes name="loggingTargets" attType="Spectrum" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="3" maxY="" allocReadMember="true" isDynamic="false"> + <dataType xsi:type="pogoDsl:StringType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <dataReadyEvent fire="false" libCheckCriteria="true"/> + <status abstract="false" inherited="true" concrete="true"/> + <properties description="Current logging targets for this device - 
initialises to LoggingTargetsDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> <attributes name="usedComponents" attType="Spectrum" rwType="READ" displayLevel="OPERATOR" polledPeriod="1000" maxX="100" maxY="" allocReadMember="true" isDynamic="false"> <dataType xsi:type="pogoDsl:StringType"/> <changeEvent fire="false" libCheckCriteria="false"/> diff --git a/skabase/SKACapability/test/SKACapability_test.py b/skabase/SKACapability/test/SKACapability_test.py index 381c0b17111f4c2c9f91d6435f5dcbf53e75be6b..cf740888f3bf4086e86f22dc11711ab7bf7167d2 100644 --- a/skabase/SKACapability/test/SKACapability_test.py +++ b/skabase/SKACapability/test/SKACapability_test.py @@ -31,9 +31,7 @@ class TestSKACapability(object): properties = { 'SkaLevel': '4', - 'CentralLoggingTarget': '', - 'ElementLoggingTarget': '', - 'StorageLoggingTarget': 'localhost', + 'LoggingTargetsDefault': ['console::cout'], 'GroupDefinitions': '', 'CapType': '', 'CapID': '', diff --git a/skabase/SKALogger/SKALogger.py b/skabase/SKALogger/SKALogger.py index 16034ef7d2b5f1a32cd2ceb599b1658434478f65..a0e9cf88ab8849213411a03a348924c59da98189 100644 --- a/skabase/SKALogger/SKALogger.py +++ b/skabase/SKALogger/SKALogger.py @@ -13,12 +13,9 @@ and to store logs using Python logging. It configures the log levels of remote l # Standard imports import os import sys -import numpy from future.utils import with_metaclass # Tango imports -import tango - from tango import DebugIt, DeviceProxy, DevFailed from tango.server import run, DeviceMeta, command @@ -27,7 +24,7 @@ from skabase import release file_path = os.path.dirname(os.path.abspath(__file__)) basedevice_path = os.path.abspath(os.path.join(file_path, os.pardir)) + "/SKABaseDevice" sys.path.insert(0, basedevice_path) -from SKABaseDevice import SKABaseDevice +from SKABaseDevice import SKABaseDevice, TangoLoggingLevel # PROTECTED REGION END # // SKALogger.additionnal_import __all__ = ["SKALogger", "main"] @@ -58,16 +55,8 @@ class SKALogger(with_metaclass(DeviceMeta, SKABaseDevice)): self._build_state = '{}, {}, {}'.format(release.name, release.version, release.description) self._version_id = release.version - self._storage_logging_level = int(tango.LogLevel.LOG_DEBUG) - self._element_logging_level = int(tango.LogLevel.LOG_DEBUG) - self._central_logging_level = int(tango.LogLevel.LOG_DEBUG) # PROTECTED REGION END # // SKALogger.init_device - def write_storageLoggingLevel(self, value): - # PROTECTED REGION ID(SKALogger.write_storageLoggingLevel) ENABLED START # - self._storage_logging_level = value - # PROTECTED REGION END # // SKALogger.write_storageLoggingLevel - def always_executed_hook(self): # PROTECTED REGION ID(SKALogger.always_executed_hook) ENABLED START # pass @@ -86,201 +75,38 @@ class SKALogger(with_metaclass(DeviceMeta, SKABaseDevice)): # Commands # -------- - @command(dtype_in=('str',), doc_in="Details of timestamp, logging level, source device and message.", - dtype_out='str', doc_out="Returns the logging message.") - @DebugIt() - def Log(self, argin): - # PROTECTED REGION ID(SKALogger.Log) ENABLED START # - """ - A method of LogConsumer Interface, to enable log messages appear in Tango log viewer. - - :parameter: argin: DevVarStringArray - Consists a list of strings. The individual items in the list are as follows: - - argin[0] : the timestamp in millisecond since epoch (01.01.1970) - - argin[1] : the log level - - argin[2] : the log source (i.e. device name) - - argin[3] : the log message - - argin[4] : the log NDC (contextual info) - Not used but reserved - - argin[5] : the thread identifier (i.e. the thread from which the log request comes from) - - :returns: DevString. - Returns the log message when successful. Empty string if fail. - """ - log_level = argin[1] - log_source = argin[2] - log_message = argin[3] - tango_log_level = {"FATAL": int(tango.LogLevel.LOG_FATAL), - "ERROR": int(tango.LogLevel.LOG_ERROR), - "WARN": int(tango.LogLevel.LOG_WARN), - "INFO": int(tango.LogLevel.LOG_INFO), - "DEBUG": int(tango.LogLevel.LOG_DEBUG)} - level_number = tango_log_level[log_level] - - # Check source devices Central and Element logging levellogging - try: - device = DeviceProxy(log_source) - except DevFailed: - self.error_stream("%s : Failed to create device proxy.", __name__) - return "" - - device_log_level = -1 - if self.SkaLevel == 1: - device_log_level = device.centralLoggingLevel - elif self.SkaLevel == 2: - device_log_level = device.elementLoggingLevel - - if log_level == "FATAL" and level_number <= device_log_level: - self.fatal_stream("%s : %s", log_source, log_message) - elif log_level == "ERROR" and level_number <= device_log_level: - self.error_stream("%s : %s", log_source, log_message) - elif log_level == "WARN" and level_number <= device_log_level: - self.warn_stream("%s : %s", log_source, log_message) - elif log_level == "INFO" and level_number <= device_log_level: - self.info_stream("%s : %s", log_source, log_message) - elif log_level == "DEBUG" and level_number <= device_log_level: - self.debug_stream("%s : %s", log_source, log_message) - - return str(log_message) - - # TODO Add dictionary for log sources - # logger = logger_dict.get(logSource) - # if not logger: - # logger = logging.getLogger(logSource) - # logger.setLevel(logging.INFO) - # # Add the log message handler to the logger - # syslog = SysLogHandler(address='/dev/log') - # logger.addHandler(syslog) - # logger.debug('this is debug') - # logger.critical('this is critical') - #logger_dict[logSource] = logger - # This should log at the specified level - #logger.info("{}]\t{}".format(timestamp, logMessage)) - - # PROTECTED REGION END # // SKALogger.Log - - @command(dtype_in='DevVarLongStringArray', doc_in="Central logging level for selected devices",) + @command(dtype_in='DevVarLongStringArray', + doc_in="Logging level for selected devices:" + "(0=OFF, 1=FATAL, 2=ERROR, 3=WARNING, 4=INFO, 5=DEBUG)." + "Example: [[4, 5], ['my/dev/1', 'my/dev/2']].") @DebugIt() - def SetCentralLoggingLevel(self, argin): - # PROTECTED REGION ID(SKALogger.SetCentralLoggingLevel) ENABLED START # + def SetLoggingLevel(self, argin): + # PROTECTED REGION ID(SKALogger.SetLoggingLevel) ENABLED START # """ - Sets Central logging level of the source device. + Sets logging level of the specified devices. - :parameter: argin: DevVarLogStringArray + :parameter: argin: DevVarLongStringArray Array consisting of - argin[0]: DevLong. Desired logging level + argin[0]: list of DevLong. Desired logging level. - argin[1]: DevString. Desired tango device + argin[1]: list of DevString. Desired tango device. :returns: None. """ - central_logging_level = argin[0][:] - #To convert the type of log level from numpy.ndarray to list. Needs to fix in PyTango. - if type(central_logging_level) is numpy.ndarray: - central_logging_level = central_logging_level.tolist() - else: - pass - - central_logging_device = argin[1][:] - i = 0 - while i < len(central_logging_level[:]): - try: - self.info_stream("Central Logging level : %s, Device : %s", - central_logging_level[i], - central_logging_level[i]) - dev_proxy = DeviceProxy(central_logging_device[i]) - dev_proxy.centralLoggingLevel = central_logging_level[i] - except DevFailed as dev_failed: - self.error_stream("Failed to set Central Logging level for [%s]", central_logging_level[i]) - str_exception = "Exception: " + str(dev_failed) - self.error_stream(str_exception) - i += 1 - - # PROTECTED REGION END # // SKALogger.SetCentralLoggingLevel - - @command(dtype_in='DevVarLongStringArray', doc_in="Element logging level for selected devices",) - @DebugIt() - def SetElementLoggingLevel(self, argin): - # PROTECTED REGION ID(SKALogger.SetElementLoggingLevel) ENABLED START # - """ - Set Element logging level of source device. - - :parameter: argin: DevVarLogStringArray - Array consisting of - - argin[0]: DevLong. Desired logging level - - argin[1]: DevString. Desired tango device - - :returns: None. - """ - element_logging_level = argin[0][:] - #To convert the type of log level from numpy.ndarray to list. Needs to fix in PyTango. - if type(element_logging_level) is numpy.ndarray: - element_logging_level = element_logging_level.tolist() - else: - pass - - element_logging_device = argin[1][:] - i = 0 - while i < len(element_logging_level[:]): - try: - self.info_stream("Element Logging level : %s, Device : %s", - element_logging_level[i], - element_logging_device[i]) - dev_proxy = DeviceProxy(element_logging_device[i]) - dev_proxy.elementLoggingLevel = element_logging_level[i] - except DevFailed as dev_failed: - self.error_stream("Failed to set Element Logging level for [%s]", element_logging_device[i]) - str_exception = "Exception: " + str(dev_failed) - self.error_stream(str_exception) - i += 1 - # PROTECTED REGION END # // SKALogger.SetElementLoggingLevel - - @command(dtype_in='DevVarLongStringArray', doc_in="Storage logging level for selected devices",) - @DebugIt() - def SetStorageLoggingLevel(self, argin): - # PROTECTED REGION ID(SKALogger.SetStorageLoggingLevel) ENABLED START # - """ - Sets Storage logging level of source device. - - :parameter: argin: DevVarLogStringArray - Array consisting of - - argin[0]: DevLong. Desired logging level - - argin[1]: DevString. Desired tango device - - :returns: None. - """ - storage_logging_level = argin[0][:] - #To convert the type of log level from numpy.ndarray to list. Needs to fix in PyTango. - if type(storage_logging_level) is numpy.ndarray: - storage_logging_level = storage_logging_level.tolist() - else: - pass - - storage_logging_device = argin[1][:] - i = 0 - while i < len(storage_logging_level[:]): + logging_levels = argin[0][:] + logging_devices = argin[1][:] + for level, device in zip(logging_levels, logging_devices): try: - self.info_stream("Storage logging level : %s, Device : %s", - storage_logging_level[i], - storage_logging_device[i]) - dev_proxy = DeviceProxy(storage_logging_device[i]) - dev_proxy.storageLoggingLevel = storage_logging_level[i] + new_level = TangoLoggingLevel(level) + self.info_stream("Setting logging level %s for %s", new_level, device) + dev_proxy = DeviceProxy(device) + dev_proxy.loggingLevel = new_level except DevFailed as dev_failed: - self.error_stream("Failed to set Storage Logging level for [%s]", storage_logging_device[i]) + self.error_stream("Failed to set logging level %s for %s", level, device) str_exception = "Exception: " + str(dev_failed) self.error_stream(str_exception) - i += 1 - # PROTECTED REGION END # // SKALogger.SetStorageLoggingLevel + # PROTECTED REGION END # // SKALogger.SetLoggingLevel # ---------- # Run server diff --git a/skabase/SKALogger/SKALogger.xmi b/skabase/SKALogger/SKALogger.xmi index 613ed2a0cbacf05f77ec2e26d2ccd56555753342..8cce495b1fb65ebdb20ca67d0d0c77018d3f1790 100644 --- a/skabase/SKALogger/SKALogger.xmi +++ b/skabase/SKALogger/SKALogger.xmi @@ -15,43 +15,16 @@ <type xsi:type="pogoDsl:StringVectorType"/> <status abstract="false" inherited="true" concrete="true"/> </deviceProperties> - <deviceProperties name="CentralLoggingTarget" description="Pre-configured logging target CentralLogger DS"> - <type xsi:type="pogoDsl:StringType"/> - <status abstract="false" inherited="true" concrete="true"/> - </deviceProperties> - <deviceProperties name="ElementLoggingTarget" description="Pre-configured logging target ElementLogger DS"> - <type xsi:type="pogoDsl:StringType"/> + <deviceProperties name="LoggingLevelDefault" description="Default logging level at device startup.
(0=OFF, 1=FATAL, 2=ERROR, 3=WARNING, 4=INFO, 5=DEBUG)"> + <type xsi:type="pogoDsl:UShortType"/> <status abstract="false" inherited="true" concrete="true"/> + <DefaultPropValue>4</DefaultPropValue> </deviceProperties> - <deviceProperties name="StorageLoggingTarget" description="Pre-configured logging target for syslog"> - <type xsi:type="pogoDsl:StringType"/> + <deviceProperties name="LoggingTargetsDefault" description="Default logging targets at device startup.
Each item has the format: target_type::target_name.
To log to stdout, use 'console::cout'.
To log to syslog, use 'syslog::<address>',
 where <address> is a file path,
 for example 'syslog::/var/run/rsyslog/dev/log'.
To log to a file, use 'file::<path>',
 where <path> is a file path,
 for example 'file::/tmp/my_dev.log'."> + <type xsi:type="pogoDsl:StringVectorType"/> <status abstract="false" inherited="true" concrete="true"/> - <DefaultPropValue>localhost</DefaultPropValue> - </deviceProperties> - <deviceProperties name="CentralLoggingLevelDefault" description="Default logging level to Central logging target, populated from Global property
(0=OFF, 1=FATAL, 2=ERROR, 3=WARNING, 4=INFO, 5=DEBUG)

Default: 2"> - <type xsi:type="pogoDsl:UShortType"/> - <status abstract="false" inherited="false" concrete="true"/> - <DefaultPropValue>2</DefaultPropValue> - </deviceProperties> - <deviceProperties name="ElementLoggingLevelDefault" description="Default logging level to Element logging target, populated from Global property
(0=OFF, 1=FATAL, 2=ERROR, 3=WARNING, 4=INFO, 5=DEBUG)

Default: 3"> - <type xsi:type="pogoDsl:UShortType"/> - <status abstract="false" inherited="false" concrete="true"/> - <DefaultPropValue>3</DefaultPropValue> - </deviceProperties> - <deviceProperties name="StorageLoggingLevelDefault" description="Default logging level to Syslog logging target, poulated from Global property
(0=OFF, 1=FATAL, 2=ERROR, 3=WARNING, 4=INFO, 5=DEBUG)

Default: 4"> - <type xsi:type="pogoDsl:UShortType"/> - <status abstract="false" inherited="false" concrete="true"/> - <DefaultPropValue>4</DefaultPropValue> + <DefaultPropValue>console::cout</DefaultPropValue> </deviceProperties> - <commands name="Log" description="LogConsumer interface" execMethod="log" displayLevel="OPERATOR" polledPeriod="0" isDynamic="false"> - <argin description="Details of timestamp, logging level, source device and message."> - <type xsi:type="pogoDsl:StringArrayType"/> - </argin> - <argout description="Returns the logging message."> - <type xsi:type="pogoDsl:StringType"/> - </argout> - <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> - </commands> <commands name="State" description="This command gets the device state (stored in its device_state data member) and returns it to the caller." execMethod="dev_state" displayLevel="OPERATOR" polledPeriod="0"> <argin description="none"> <type xsi:type="pogoDsl:VoidType"/> @@ -70,26 +43,8 @@ </argout> <status abstract="true" inherited="true" concrete="true"/> </commands> - <commands name="SetCentralLoggingLevel" description="Logging level to Central logging target:
(0=OFF, 1=FATAL, 2=ERROR, 3=WARNING, 4=INFO, 5=DEBUG)" execMethod="set_central_logging_level" displayLevel="OPERATOR" polledPeriod="0" isDynamic="false"> - <argin description="Central logging level for selected devices"> - <type xsi:type="pogoDsl:LongStringArrayType"/> - </argin> - <argout description="No output arguments"> - <type xsi:type="pogoDsl:VoidType"/> - </argout> - <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> - </commands> - <commands name="SetElementLoggingLevel" description="Logging level to Element logging target:
(0=OFF, 1=FATAL, 2=ERROR, 3=WARNING, 4=INFO, 5=DEBUG)" execMethod="set_element_logging_level" displayLevel="OPERATOR" polledPeriod="0" isDynamic="false"> - <argin description="Element logging level for selected devices"> - <type xsi:type="pogoDsl:LongStringArrayType"/> - </argin> - <argout description="No output arguments"> - <type xsi:type="pogoDsl:VoidType"/> - </argout> - <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> - </commands> - <commands name="SetStorageLoggingLevel" description="Logging level to Syslog storage logging target:
(0=OFF, 1=FATAL, 2=ERROR, 3=WARNING, 4=INFO, 5=DEBUG)" execMethod="set_storage_logging_level" displayLevel="OPERATOR" polledPeriod="0" isDynamic="false"> - <argin description="Storage logging level for selected devices"> + <commands name="SetLoggingLevel" description="Adjust logging level for multiple devices" execMethod="set_logging_level" displayLevel="OPERATOR" polledPeriod="0" isDynamic="false"> + <argin description="Logging level for selected devices:
(0=OFF, 1=FATAL, 2=ERROR, 3=WARNING, 4=INFO, 5=DEBUG).
Example: [[4, 5], ['my/dev/1', 'my/dev/2']]."> <type xsi:type="pogoDsl:LongStringArrayType"/> </argin> <argout description="No output arguments"> @@ -125,20 +80,12 @@ <status abstract="false" inherited="true" concrete="true"/> <properties description="Build state of this device" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> - <attributes name="centralLoggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true"> - <dataType xsi:type="pogoDsl:UShortType"/> - <status abstract="false" inherited="true" concrete="true"/> - <properties description="Current logging level to Central logging target for this device - 
initialises to CentralLoggingLevelDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> - </attributes> - <attributes name="elementLoggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true"> - <dataType xsi:type="pogoDsl:UShortType"/> - <status abstract="false" inherited="true" concrete="true"/> - <properties description="Current logging level to Element logging target for this device - 
initialises to ElementLoggingLevelDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> - </attributes> - <attributes name="storageLoggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" memorized="true" allocReadMember="true"> - <dataType xsi:type="pogoDsl:UShortType"/> + <attributes name="loggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true"> + <dataType xsi:type="pogoDsl:EnumType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> <status abstract="false" inherited="true" concrete="true"/> - <properties description="Current logging level to Syslog for this device - 
initialises from StorageLoggingLevelDefault on first execution of device.
Needs to be READ_WRITE To make it memorized - but writing this attribute should 
do the same as command SetStorageLoggingLevel to ensure the targets and adjustments
are made correctly" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + <properties description="Current logging level for this device - initialises to LoggingLevelDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> <attributes name="healthState" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true"> <dataType xsi:type="pogoDsl:EnumType"/> @@ -165,6 +112,14 @@ <status abstract="false" inherited="true" concrete="true"/> <properties description="The test mode of the device. 
Either no test mode (empty string) or an indication of the test mode." label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> + <attributes name="loggingTargets" attType="Spectrum" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="3" maxY="" allocReadMember="true" isDynamic="false"> + <dataType xsi:type="pogoDsl:StringType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <dataReadyEvent fire="false" libCheckCriteria="true"/> + <status abstract="false" inherited="true" concrete="true"/> + <properties description="Current logging targets for this device - 
initialises to LoggingTargetsDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> <states name="ON" description="This state could have been called OK or OPERATIONAL. It means that the device is in its operational state. (E.g. the power supply is giving its nominal current, th motor is ON and ready to move, the instrument is operating). This state is modified by the Attribute alarm checking of the DeviceImpl:dev_state method. i.e. if the State is ON and one attribute has its quality factor to ATTR_WARNING or ATTR_ALARM, then the State is modified to ALARM."> <status abstract="false" inherited="true" concrete="true"/> </states> diff --git a/skabase/SKALogger/test/SKALogger_test.py b/skabase/SKALogger/test/SKALogger_test.py index b98e84f9c63e4bdb00af24b03d51013eff5f8bd4..f02575da635d57800ff98af7eb227701651bd103 100644 --- a/skabase/SKALogger/test/SKALogger_test.py +++ b/skabase/SKALogger/test/SKALogger_test.py @@ -33,12 +33,6 @@ class TestSKALogger(object): """Test case for packet generation.""" properties = {'SkaLevel': '1', 'GroupDefinitions': '', - 'CentralLoggingTarget': '', - 'ElementLoggingTarget': '', - 'StorageLoggingTarget': 'localhost', - 'CentralLoggingLevelDefault': int(tango.LogLevel.LOG_ERROR), - 'ElementLoggingLevelDefault': int(tango.LogLevel.LOG_WARN), - 'StorageLoggingLevelDefault': int(tango.LogLevel.LOG_INFO), } @classmethod @@ -55,16 +49,6 @@ class TestSKALogger(object): # PROTECTED REGION END # // SKALogger.test_properties pass - # PROTECTED REGION ID(SKALogger.test_Log_decorators) ENABLED START # - # PROTECTED REGION END # // SKALogger.test_Log_decorators - def test_Log(self, tango_context): - """Test for Log""" - # PROTECTED REGION ID(SKALogger.test_Log) ENABLED START # - log_details = ["123456789", "ERROR", "logger/test/1", - "Error message", "0", "0"] - assert tango_context.device.Log(log_details) == "Error message" - # PROTECTED REGION END # // SKALogger.test_Log - # PROTECTED REGION ID(SKALogger.test_State_decorators) ENABLED START # # PROTECTED REGION END # // SKALogger.test_State_decorators def test_State(self, tango_context): @@ -81,54 +65,19 @@ class TestSKALogger(object): assert tango_context.device.Status() == "The device is in UNKNOWN state." # PROTECTED REGION END # // SKALogger.test_Status - # PROTECTED REGION ID(SKALogger.test_SetCentralLoggingLevel_decorators) ENABLED START # - @pytest.mark.parametrize("logging_level", [int(tango.LogLevel.LOG_INFO)]) - @pytest.mark.parametrize("logging_target", ["logger/test/1"]) - # PROTECTED REGION END # // SKALogger.test_SetCentralLoggingLevel_decorators - def test_SetCentralLoggingLevel(self, tango_context, setup_log_test_device, - logging_level, logging_target): - """Test for SetCentralLoggingLevel""" - # PROTECTED REGION ID(SKALogger.test_SetCentralLoggingLevel) ENABLED START # - levels = [] - levels.append(logging_level) - targets = [] - targets.append(logging_target) - device_details = [] - device_details.append(levels) - device_details.append(targets) - tango_context.device.SetCentralLoggingLevel(device_details) - dev_proxy = DeviceProxy(logging_target) - assert dev_proxy.centralLoggingLevel == logging_level - # PROTECTED REGION END # // SKALogger.test_SetCentralLoggingLevel - - # PROTECTED REGION ID(SKALogger.test_SetElementLoggingLevel_decorators) ENABLED START # + # PROTECTED REGION ID(SKALogger.test_SetLoggingLevel_decorators) ENABLED START # @pytest.mark.parametrize("logging_level", [int(tango.LogLevel.LOG_ERROR)]) @pytest.mark.parametrize("logging_target", ["logger/test/1"]) - # PROTECTED REGION END # // SKALogger.test_SetElementLoggingLevel_decorators - def test_SetElementLoggingLevel(self, tango_context, setup_log_test_device, - logging_level, logging_target): - """Test for SetElementLoggingLevel""" - # PROTECTED REGION ID(SKALogger.test_SetElementLoggingLevel) ENABLED START # - levels = [] - levels.append(logging_level) - targets = [] - targets.append(logging_target) - device_details = [] - device_details.append(levels) - device_details.append(targets) - tango_context.device.SetElementLoggingLevel(device_details) + # PROTECTED REGION END # // SKALogger.test_SetLoggingLevel_decorators + def test_SetLoggingLevel(self, tango_context, setup_log_test_device, + logging_level, logging_target): + """Test for SetLoggingLevel""" + # PROTECTED REGION ID(SKALogger.test_SetLoggingLevel) ENABLED START # + # initial setting must not be same as what it will be set to dev_proxy = DeviceProxy(logging_target) - assert dev_proxy.elementLoggingLevel == logging_level - # PROTECTED REGION END # // SKALogger.test_SetElementLoggingLevel + dev_proxy.loggingLevel = int(tango.LogLevel.LOG_FATAL) + assert dev_proxy.loggingLevel != logging_level - # PROTECTED REGION ID(SKALogger.test_SetStorageLoggingLevel_decorators) ENABLED START # - @pytest.mark.parametrize("logging_level", [int(tango.LogLevel.LOG_WARN)]) - @pytest.mark.parametrize("logging_target", ["logger/test/1"]) - # PROTECTED REGION END # // SKALogger.test_SetStorageLoggingLevel_decorators - def test_SetStorageLoggingLevel(self, tango_context, setup_log_test_device, - logging_level, logging_target): - """Test for SetStorageLoggingLevel""" - # PROTECTED REGION ID(SKALogger.test_SetStorageLoggingLevel) ENABLED START # levels = [] levels.append(logging_level) targets = [] @@ -136,10 +85,9 @@ class TestSKALogger(object): device_details = [] device_details.append(levels) device_details.append(targets) - tango_context.device.SetStorageLoggingLevel(device_details) - dev_proxy = DeviceProxy(logging_target) - assert dev_proxy.storageLoggingLevel == logging_level - # PROTECTED REGION END # // SKALogger.test_SetStorageLoggingLevel + tango_context.device.SetLoggingLevel(device_details) + assert dev_proxy.loggingLevel == logging_level + # PROTECTED REGION END # // SKALogger.test_SetLoggingLevel # PROTECTED REGION ID(SKALogger.test_GetVersionInfo_decorators) ENABLED START # # PROTECTED REGION END # // SKALogger.test_GetVersionInfo_decorators @@ -181,29 +129,13 @@ class TestSKALogger(object): assert (re.match(versionIdPattern, tango_context.device.versionId)) is not None # PROTECTED REGION END # // SKALogger.test_versionId - # PROTECTED REGION ID(SKALogger.test_centralLoggingLevel_decorators) ENABLED START # - # PROTECTED REGION END # // SKALogger.test_centralLoggingLevel_decorators - def test_centralLoggingLevel(self, tango_context): - """Test for centralLoggingLevel""" - # PROTECTED REGION ID(SKALogger.test_centralLoggingLevel) ENABLED START # - assert tango_context.device.centralLoggingLevel == int(tango.LogLevel.LOG_DEBUG) - # PROTECTED REGION END # // SKALogger.test_centralLoggingLevel - - # PROTECTED REGION ID(SKALogger.test_elementLoggingLevel_decorators) ENABLED START # - # PROTECTED REGION END # // SKALogger.test_elementLoggingLevel_decorators - def test_elementLoggingLevel(self, tango_context): - """Test for elementLoggingLevel""" - # PROTECTED REGION ID(SKALogger.test_elementLoggingLevel) ENABLED START # - assert tango_context.device.elementLoggingLevel == int(tango.LogLevel.LOG_DEBUG) - # PROTECTED REGION END # // SKALogger.test_elementLoggingLevel - - # PROTECTED REGION ID(SKALogger.test_storageLoggingLevel_decorators) ENABLED START # - # PROTECTED REGION END # // SKALogger.test_storageLoggingLevel_decorators - def test_storageLoggingLevel(self, tango_context): - """Test for storageLoggingLevel""" - # PROTECTED REGION ID(SKALogger.test_storageLoggingLevel) ENABLED START # - assert tango_context.device.storageLoggingLevel == int(tango.LogLevel.LOG_DEBUG) - # PROTECTED REGION END # // SKALogger.test_storageLoggingLevel + # PROTECTED REGION ID(SKALogger.test_loggingLevel_decorators) ENABLED START # + # PROTECTED REGION END # // SKALogger.test_loggingLevel_decorators + def test_loggingLevel(self, tango_context): + """Test for loggingLevel""" + # PROTECTED REGION ID(SKALogger.test_loggingLevel) ENABLED START # + assert tango_context.device.loggingLevel == tango.LogLevel.LOG_INFO + # PROTECTED REGION END # // SKALogger.test_loggingLevel # PROTECTED REGION ID(SKALogger.test_healthState_decorators) ENABLED START # # PROTECTED REGION END # // SKALogger.test_healthState_decorators diff --git a/skabase/SKAMaster/SKAMaster.xmi b/skabase/SKAMaster/SKAMaster.xmi index b5794342a70d059d8b2cd71c9ddf8c328ce437ec..f7810aa24482cb71138773ae56458fd1408fa899 100644 --- a/skabase/SKAMaster/SKAMaster.xmi +++ b/skabase/SKAMaster/SKAMaster.xmi @@ -11,18 +11,15 @@ <status abstract="false" inherited="true" concrete="true"/> <DefaultPropValue>4</DefaultPropValue> </deviceProperties> - <deviceProperties name="CentralLoggingTarget" description="Pre-configured logging target CentralLogger DS"> - <type xsi:type="pogoDsl:StringType"/> - <status abstract="false" inherited="true" concrete="true"/> - </deviceProperties> - <deviceProperties name="ElementLoggingTarget" description="Pre-configured logging target ElementLogger DS"> - <type xsi:type="pogoDsl:StringType"/> + <deviceProperties name="LoggingLevelDefault" description="Default logging level at device startup.
(0=OFF, 1=FATAL, 2=ERROR, 3=WARNING, 4=INFO, 5=DEBUG)"> + <type xsi:type="pogoDsl:UShortType"/> <status abstract="false" inherited="true" concrete="true"/> + <DefaultPropValue>4</DefaultPropValue> </deviceProperties> - <deviceProperties name="StorageLoggingTarget" description="Pre-configured logging target for syslog"> - <type xsi:type="pogoDsl:StringType"/> + <deviceProperties name="LoggingTargetsDefault" description="Default logging targets at device startup.
Each item has the format: target_type::target_name.
To log to stdout, use 'console::cout'.
To log to syslog, use 'syslog::<address>',
 where <address> is a file path,
 for example 'syslog::/var/run/rsyslog/dev/log'.
To log to a file, use 'file::<path>',
 where <path> is a file path,
 for example 'file::/tmp/my_dev.log'."> + <type xsi:type="pogoDsl:StringVectorType"/> <status abstract="false" inherited="true" concrete="true"/> - <DefaultPropValue>localhost</DefaultPropValue> + <DefaultPropValue>console::cout</DefaultPropValue> </deviceProperties> <deviceProperties name="GroupDefinitions" description="Each string in the list is a JSON serialised dict defining the ``group_name``,
``devices`` and ``subgroups`` in the group. A TANGO Group object is created
for each item in the list, according to the hierarchy defined. This provides
easy access to the managed devices in bulk, or individually.

The general format of the list is as follows, with optional ``devices`` and
``subgroups`` keys:
 [ {``group_name``: ``<name>``,
 ``devices``: [``<dev name>``, ...]},
 {``group_name``: ``<name>``,
 ``devices``: [``<dev name>``, ``<dev name>``, ...],
 ``subgroups`` : [{<nested group>},
 {<nested group>}, ...]},
 ...
 ]

For example, a hierarchy of racks, servers and switches:
 [ {``group_name``: ``servers``,
 ``devices``: [``elt/server/1``, ``elt/server/2``,
 ``elt/server/3``, ``elt/server/4``]},
 {``group_name``: ``switches``,
 ``devices``: [``elt/switch/A``, ``elt/switch/B``]},
 {``group_name``: ``pdus``,
 ``devices``: [``elt/pdu/rackA``, ``elt/pdu/rackB``]},
 {``group_name``: ``racks``,
 ``subgroups``: [
 {``group_name``: ``rackA``,
 ``devices``: [``elt/server/1``, ``elt/server/2``,
 ``elt/switch/A``, ``elt/pdu/rackA``]},
 {``group_name``: ``rackB``,
 ``devices``: [``elt/server/3``, ``elt/server/4``,
 ``elt/switch/B``, ``elt/pdu/rackB``],
 ``subgroups``: []}
 ]} ]"> <type xsi:type="pogoDsl:StringVectorType"/> @@ -132,26 +129,12 @@ <status abstract="false" inherited="true" concrete="true" concreteHere="false"/> <properties description="Build state of this device" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> - <attributes name="centralLoggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true"> - <dataType xsi:type="pogoDsl:UShortType"/> - <changeEvent fire="false" libCheckCriteria="false"/> - <archiveEvent fire="false" libCheckCriteria="false"/> - <status abstract="false" inherited="true" concrete="true" concreteHere="false"/> - <properties description="Current logging level to Central logging target for this device - 
initialises to CentralLoggingLevelDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> - </attributes> - <attributes name="elementLoggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true"> - <dataType xsi:type="pogoDsl:UShortType"/> - <changeEvent fire="false" libCheckCriteria="false"/> - <archiveEvent fire="false" libCheckCriteria="false"/> - <status abstract="false" inherited="true" concrete="true" concreteHere="false"/> - <properties description="Current logging level to Element logging target for this device - 
initialises to ElementLoggingLevelDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> - </attributes> - <attributes name="storageLoggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" memorized="true" allocReadMember="true"> - <dataType xsi:type="pogoDsl:UShortType"/> + <attributes name="loggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true"> + <dataType xsi:type="pogoDsl:EnumType"/> <changeEvent fire="false" libCheckCriteria="false"/> <archiveEvent fire="false" libCheckCriteria="false"/> - <status abstract="false" inherited="true" concrete="true" concreteHere="false"/> - <properties description="Current logging level to Syslog for this device - 
initialises from StorageLoggingLevelDefault on first execution of device.
Needs to be READ_WRITE To make it memorized - but writing this attribute should 
do the same as command SetStorageLoggingLevel to ensure the targets and adjustments
are made correctly" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + <status abstract="false" inherited="true" concrete="true"/> + <properties description="Current logging level for this device - initialises to LoggingLevelDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> <attributes name="healthState" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true"> <dataType xsi:type="pogoDsl:EnumType"/> @@ -204,6 +187,14 @@ <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> <properties description="A list of available number of instances of each capability type, e.g. 'CORRELATOR:512', 'PSS-BEAMS:4'." label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> + <attributes name="loggingTargets" attType="Spectrum" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="3" maxY="" allocReadMember="true" isDynamic="false"> + <dataType xsi:type="pogoDsl:StringType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <dataReadyEvent fire="false" libCheckCriteria="true"/> + <status abstract="false" inherited="true" concrete="true"/> + <properties description="Current logging targets for this device - 
initialises to LoggingTargetsDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> <states name="ON" description="This state could have been called OK or OPERATIONAL. It means that the device is in its operational state. (E.g. the power supply is giving its nominal current, th motor is ON and ready to move, the instrument is operating). This state is modified by the Attribute alarm checking of the DeviceImpl:dev_state method. i.e. if the State is ON and one attribute has its quality factor to ATTR_WARNING or ATTR_ALARM, then the State is modified to ALARM."> <status abstract="false" inherited="true" concrete="true"/> </states> diff --git a/skabase/SKAMaster/test/SKAMaster_test.py b/skabase/SKAMaster/test/SKAMaster_test.py index 865174c72036248e526e3e746ccf0ced73596006..427f5bbadcbcda30a31eeb047b21d91032b4147b 100644 --- a/skabase/SKAMaster/test/SKAMaster_test.py +++ b/skabase/SKAMaster/test/SKAMaster_test.py @@ -33,9 +33,7 @@ class TestSKAMaster(object): capabilities = ['BAND1:1', 'BAND2:1', 'BAND3:0', 'BAND4:0', 'BAND5:0'] properties = { 'SkaLevel': '4', - 'CentralLoggingTarget': '', - 'ElementLoggingTarget': '', - 'StorageLoggingTarget': 'localhost', + 'LoggingTargetsDefault': ['console::cout'], 'GroupDefinitions': '', 'NrSubarrays': '16', 'CapabilityTypes': '', @@ -161,30 +159,6 @@ class TestSKAMaster(object): assert (re.match(versionIdPattern, tango_context.device.versionId)) != None # PROTECTED REGION END # // SKAMaster.test_versionId - # PROTECTED REGION ID(SKAMaster.test_centralLoggingLevel_decorators) ENABLED START # - # PROTECTED REGION END # // SKAMaster.test_centralLoggingLevel_decorators - def test_centralLoggingLevel(self, tango_context): - """Test for centralLoggingLevel""" - # PROTECTED REGION ID(SKAMaster.test_centralLoggingLevel) ENABLED START # - assert tango_context.device.centralLoggingLevel == 0 - # PROTECTED REGION END # // SKAMaster.test_centralLoggingLevel - - # PROTECTED REGION ID(SKAMaster.test_elementLoggingLevel_decorators) ENABLED START # - # PROTECTED REGION END # // SKAMaster.test_elementLoggingLevel_decorators - def test_elementLoggingLevel(self, tango_context): - """Test for elementLoggingLevel""" - # PROTECTED REGION ID(SKAMaster.test_elementLoggingLevel) ENABLED START # - assert tango_context.device.elementLoggingLevel == 0 - # PROTECTED REGION END # // SKAMaster.test_elementLoggingLevel - - # PROTECTED REGION ID(SKAMaster.test_storageLoggingLevel_decorators) ENABLED START # - # PROTECTED REGION END # // SKAMaster.test_storageLoggingLevel_decorators - def test_storageLoggingLevel(self, tango_context): - """Test for storageLoggingLevel""" - # PROTECTED REGION ID(SKAMaster.test_storageLoggingLevel) ENABLED START # - assert tango_context.device.storageLoggingLevel == 0 - # PROTECTED REGION END # // SKAMaster.test_storageLoggingLevel - # PROTECTED REGION ID(SKAMaster.test_healthState_decorators) ENABLED START # # PROTECTED REGION END # // SKAMaster.test_healthState_decorators def test_healthState(self, tango_context): diff --git a/skabase/SKAObsDevice/SKAObsDevice.xmi b/skabase/SKAObsDevice/SKAObsDevice.xmi index 34b06efcee1900978eafa8c2472e8cec515de7fe..99212d435a7307f9fa052605c0ceb36537825154 100644 --- a/skabase/SKAObsDevice/SKAObsDevice.xmi +++ b/skabase/SKAObsDevice/SKAObsDevice.xmi @@ -11,18 +11,15 @@ <status abstract="false" inherited="true" concrete="true"/> <DefaultPropValue>4</DefaultPropValue> </deviceProperties> - <deviceProperties name="CentralLoggingTarget" description="Pre-configured logging target CentralLogger DS"> - <type xsi:type="pogoDsl:StringType"/> - <status abstract="false" inherited="true" concrete="true"/> - </deviceProperties> - <deviceProperties name="ElementLoggingTarget" description="Pre-configured logging target ElementLogger DS"> - <type xsi:type="pogoDsl:StringType"/> + <deviceProperties name="LoggingLevelDefault" description="Default logging level at device startup.
(0=OFF, 1=FATAL, 2=ERROR, 3=WARNING, 4=INFO, 5=DEBUG)"> + <type xsi:type="pogoDsl:UShortType"/> <status abstract="false" inherited="true" concrete="true"/> + <DefaultPropValue>4</DefaultPropValue> </deviceProperties> - <deviceProperties name="StorageLoggingTarget" description="Pre-configured logging target for syslog"> - <type xsi:type="pogoDsl:StringType"/> + <deviceProperties name="LoggingTargetsDefault" description="Default logging targets at device startup.
Each item has the format: target_type::target_name.
To log to stdout, use 'console::cout'.
To log to syslog, use 'syslog::<address>',
 where <address> is a file path,
 for example 'syslog::/var/run/rsyslog/dev/log'.
To log to a file, use 'file::<path>',
 where <path> is a file path,
 for example 'file::/tmp/my_dev.log'."> + <type xsi:type="pogoDsl:StringVectorType"/> <status abstract="false" inherited="true" concrete="true"/> - <DefaultPropValue>localhost</DefaultPropValue> + <DefaultPropValue>console::cout</DefaultPropValue> </deviceProperties> <deviceProperties name="GroupDefinitions" description="Each string in the list is a JSON serialised dict defining the ``group_name``,
``devices`` and ``subgroups`` in the group. A TANGO Group object is created
for each item in the list, according to the hierarchy defined. This provides
easy access to the managed devices in bulk, or individually.

The general format of the list is as follows, with optional ``devices`` and
``subgroups`` keys:
 [ {``group_name``: ``<name>``,
 ``devices``: [``<dev name>``, ...]},
 {``group_name``: ``<name>``,
 ``devices``: [``<dev name>``, ``<dev name>``, ...],
 ``subgroups`` : [{<nested group>},
 {<nested group>}, ...]},
 ...
 ]

For example, a hierarchy of racks, servers and switches:
 [ {``group_name``: ``servers``,
 ``devices``: [``elt/server/1``, ``elt/server/2``,
 ``elt/server/3``, ``elt/server/4``]},
 {``group_name``: ``switches``,
 ``devices``: [``elt/switch/A``, ``elt/switch/B``]},
 {``group_name``: ``pdus``,
 ``devices``: [``elt/pdu/rackA``, ``elt/pdu/rackB``]},
 {``group_name``: ``racks``,
 ``subgroups``: [
 {``group_name``: ``rackA``,
 ``devices``: [``elt/server/1``, ``elt/server/2``,
 ``elt/switch/A``, ``elt/pdu/rackA``]},
 {``group_name``: ``rackB``,
 ``devices``: [``elt/server/3``, ``elt/server/4``,
 ``elt/switch/B``, ``elt/pdu/rackB``],
 ``subgroups``: []}
 ]} ]"> <type xsi:type="pogoDsl:StringVectorType"/> @@ -124,20 +121,12 @@ <status abstract="false" inherited="true" concrete="true" concreteHere="false"/> <properties description="Build state of this device" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> - <attributes name="centralLoggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true"> - <dataType xsi:type="pogoDsl:UShortType"/> - <status abstract="false" inherited="true" concrete="true" concreteHere="false"/> - <properties description="Current logging level to Central logging target for this device - 
initialises to CentralLoggingLevelDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> - </attributes> - <attributes name="elementLoggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true"> - <dataType xsi:type="pogoDsl:UShortType"/> - <status abstract="false" inherited="true" concrete="true" concreteHere="false"/> - <properties description="Current logging level to Element logging target for this device - 
initialises to ElementLoggingLevelDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> - </attributes> - <attributes name="storageLoggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" memorized="true" allocReadMember="true"> - <dataType xsi:type="pogoDsl:UShortType"/> - <status abstract="false" inherited="true" concrete="true" concreteHere="false"/> - <properties description="Current logging level to Syslog for this device - 
initialises from StorageLoggingLevelDefault on first execution of device.
Needs to be READ_WRITE To make it memorized - but writing this attribute should 
do the same as command SetStorageLoggingLevel to ensure the targets and adjustments
are made correctly" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + <attributes name="loggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true"> + <dataType xsi:type="pogoDsl:EnumType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <status abstract="false" inherited="true" concrete="true"/> + <properties description="Current logging level for this device - initialises to LoggingLevelDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> <attributes name="healthState" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true"> <dataType xsi:type="pogoDsl:EnumType"/> @@ -164,6 +153,14 @@ <status abstract="false" inherited="true" concrete="true" concreteHere="false"/> <properties description="The test mode of the device. 
Either no test mode (empty string) or an indication of the test mode." label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> + <attributes name="loggingTargets" attType="Spectrum" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="3" maxY="" allocReadMember="true" isDynamic="false"> + <dataType xsi:type="pogoDsl:StringType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <dataReadyEvent fire="false" libCheckCriteria="true"/> + <status abstract="false" inherited="true" concrete="true"/> + <properties description="Current logging targets for this device - 
initialises to LoggingTargetsDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> <states name="ON" description="This state could have been called OK or OPERATIONAL. It means that the device is in its operational state. (E.g. the power supply is giving its nominal current, th motor is ON and ready to move, the instrument is operating). This state is modified by the Attribute alarm checking of the DeviceImpl:dev_state method. i.e. if the State is ON and one attribute has its quality factor to ATTR_WARNING or ATTR_ALARM, then the State is modified to ALARM."> <status abstract="false" inherited="true" concrete="true"/> </states> diff --git a/skabase/SKAObsDevice/test/SKAObsDevice_test.py b/skabase/SKAObsDevice/test/SKAObsDevice_test.py index 192de1ae61ef08d3b358a5a3dd80f85a0f57ecc7..ff78cd957220ac0e67c42590c55605746f39d631 100644 --- a/skabase/SKAObsDevice/test/SKAObsDevice_test.py +++ b/skabase/SKAObsDevice/test/SKAObsDevice_test.py @@ -32,9 +32,7 @@ class TestSKAObsDevice(object): properties = { 'SkaLevel': '4', - 'CentralLoggingTarget': '', - 'ElementLoggingTarget': '', - 'StorageLoggingTarget': 'localhost', + 'LoggingTargetsDefault': ['console::cout'], 'GroupDefinitions': '', } @@ -148,30 +146,6 @@ class TestSKAObsDevice(object): assert (re.match(versionIdPattern, tango_context.device.versionId)) != None # PROTECTED REGION END # // SKAObsDevice.test_versionId - # PROTECTED REGION ID(SKAObsDevice.test_centralLoggingLevel_decorators) ENABLED START # - # PROTECTED REGION END # // SKAObsDevice.test_centralLoggingLevel_decorators - def test_centralLoggingLevel(self, tango_context): - """Test for centralLoggingLevel""" - # PROTECTED REGION ID(SKAObsDevice.test_centralLoggingLevel) ENABLED START # - assert tango_context.device.centralLoggingLevel == 0 - # PROTECTED REGION END # // SKAObsDevice.test_centralLoggingLevel - - # PROTECTED REGION ID(SKAObsDevice.test_elementLoggingLevel_decorators) ENABLED START # - # PROTECTED REGION END # // SKAObsDevice.test_elementLoggingLevel_decorators - def test_elementLoggingLevel(self, tango_context): - """Test for elementLoggingLevel""" - # PROTECTED REGION ID(SKAObsDevice.test_elementLoggingLevel) ENABLED START # - assert tango_context.device.elementLoggingLevel == 0 - # PROTECTED REGION END # // SKAObsDevice.test_elementLoggingLevel - - # PROTECTED REGION ID(SKAObsDevice.test_storageLoggingLevel_decorators) ENABLED START # - # PROTECTED REGION END # // SKAObsDevice.test_storageLoggingLevel_decorators - def test_storageLoggingLevel(self, tango_context): - """Test for storageLoggingLevel""" - # PROTECTED REGION ID(SKAObsDevice.test_storageLoggingLevel) ENABLED START # - assert tango_context.device.storageLoggingLevel == 0 - # PROTECTED REGION END # // SKAObsDevice.test_storageLoggingLevel - # PROTECTED REGION ID(SKAObsDevice.test_healthState_decorators) ENABLED START # # PROTECTED REGION END # // SKAObsDevice.test_healthState_decorators def test_healthState(self, tango_context): diff --git a/skabase/SKASubarray/SKASubarray.xmi b/skabase/SKASubarray/SKASubarray.xmi index 00da3517ae643f57be8dce43b1683a102853843c..2b3b125484af721ba1a5174a09f90ae923793bb5 100644 --- a/skabase/SKASubarray/SKASubarray.xmi +++ b/skabase/SKASubarray/SKASubarray.xmi @@ -10,13 +10,15 @@ <type xsi:type="pogoDsl:StringVectorType"/> <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> </deviceProperties> - <deviceProperties name="CentralLoggingTarget" description="Pre-configured logging target CentralLogger DS"> - <type xsi:type="pogoDsl:StringType"/> + <deviceProperties name="LoggingLevelDefault" description="Default logging level at device startup.
(0=OFF, 1=FATAL, 2=ERROR, 3=WARNING, 4=INFO, 5=DEBUG)"> + <type xsi:type="pogoDsl:UShortType"/> <status abstract="false" inherited="true" concrete="true"/> + <DefaultPropValue>4</DefaultPropValue> </deviceProperties> - <deviceProperties name="ElementLoggingTarget" description="Pre-configured logging target ElementLogger DS"> - <type xsi:type="pogoDsl:StringType"/> + <deviceProperties name="LoggingTargetsDefault" description="Default logging targets at device startup.
Each item has the format: target_type::target_name.
To log to stdout, use 'console::cout'.
To log to syslog, use 'syslog::<address>',
 where <address> is a file path,
 for example 'syslog::/var/run/rsyslog/dev/log'.
To log to a file, use 'file::<path>',
 where <path> is a file path,
 for example 'file::/tmp/my_dev.log'."> + <type xsi:type="pogoDsl:StringVectorType"/> <status abstract="false" inherited="true" concrete="true"/> + <DefaultPropValue>console::cout</DefaultPropValue> </deviceProperties> <deviceProperties name="GroupDefinitions" description="Each string in the list is a JSON serialised dict defining the ``group_name``,
``devices`` and ``subgroups`` in the group. A TANGO Group object is created
for each item in the list, according to the hierarchy defined. This provides
easy access to the managed devices in bulk, or individually.

The general format of the list is as follows, with optional ``devices`` and
``subgroups`` keys:
 [ {``group_name``: ``<name>``,
 ``devices``: [``<dev name>``, ...]},
 {``group_name``: ``<name>``,
 ``devices``: [``<dev name>``, ``<dev name>``, ...],
 ``subgroups`` : [{<nested group>},
 {<nested group>}, ...]},
 ...
 ]

For example, a hierarchy of racks, servers and switches:
 [ {``group_name``: ``servers``,
 ``devices``: [``elt/server/1``, ``elt/server/2``,
 ``elt/server/3``, ``elt/server/4``]},
 {``group_name``: ``switches``,
 ``devices``: [``elt/switch/A``, ``elt/switch/B``]},
 {``group_name``: ``pdus``,
 ``devices``: [``elt/pdu/rackA``, ``elt/pdu/rackB``]},
 {``group_name``: ``racks``,
 ``subgroups``: [
 {``group_name``: ``rackA``,
 ``devices``: [``elt/server/1``, ``elt/server/2``,
 ``elt/switch/A``, ``elt/pdu/rackA``]},
 {``group_name``: ``rackB``,
 ``devices``: [``elt/server/3``, ``elt/server/4``,
 ``elt/switch/B``, ``elt/pdu/rackB``],
 ``subgroups``: []}
 ]} ]"> <type xsi:type="pogoDsl:StringVectorType"/> @@ -27,11 +29,6 @@ <status abstract="false" inherited="true" concrete="true"/> <DefaultPropValue>4</DefaultPropValue> </deviceProperties> - <deviceProperties name="StorageLoggingTarget" description="Pre-configured logging target for syslog"> - <type xsi:type="pogoDsl:StringType"/> - <status abstract="false" inherited="true" concrete="true"/> - <DefaultPropValue>localhost</DefaultPropValue> - </deviceProperties> <deviceProperties name="SubID" description="Unique identifier of the subarray device."> <type xsi:type="pogoDsl:StringType"/> <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> @@ -207,11 +204,6 @@ <status abstract="false" inherited="true" concrete="true"/> <properties description="Build state of this device" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> - <attributes name="centralLoggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true"> - <dataType xsi:type="pogoDsl:UShortType"/> - <status abstract="false" inherited="true" concrete="true"/> - <properties description="Current logging level to Central logging target for this device - 
initialises to CentralLoggingLevelDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> - </attributes> <attributes name="configurationDelayExpected" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true"> <dataType xsi:type="pogoDsl:UShortType"/> <status abstract="false" inherited="true" concrete="true"/> @@ -227,16 +219,18 @@ <status abstract="false" inherited="true" concrete="true"/> <properties description="The control mode of the device. REMOTE, LOCAL
TANGO Device accepts only from a ‘local’ client and ignores commands and queries received from TM
or any other ‘remote’ clients. The Local clients has to release LOCAL control before REMOTE clients
can take control again." label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> - <attributes name="elementLoggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true"> - <dataType xsi:type="pogoDsl:UShortType"/> - <status abstract="false" inherited="true" concrete="true"/> - <properties description="Current logging level to Element logging target for this device - 
initialises to ElementLoggingLevelDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> - </attributes> <attributes name="healthState" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true"> <dataType xsi:type="pogoDsl:EnumType"/> <status abstract="false" inherited="true" concrete="true"/> <properties description="The health state reported for this device. It interprets the current device condition 
and condition of all managed devices to set this. Most possibly an aggregate attribute." label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> + <attributes name="loggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true"> + <dataType xsi:type="pogoDsl:EnumType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <status abstract="false" inherited="true" concrete="true"/> + <properties description="Current logging level for this device - initialises to LoggingLevelDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> <attributes name="obsMode" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true"> <dataType xsi:type="pogoDsl:EnumType"/> <status abstract="false" inherited="true" concrete="true"/> @@ -252,11 +246,6 @@ <status abstract="false" inherited="true" concrete="true"/> <properties description="Reports the simulation mode of the device. Some devices may implement both modes,
while others will have simulators that set simulationMode to True while the real
devices always set simulationMode to False." label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> - <attributes name="storageLoggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" memorized="true" allocReadMember="true"> - <dataType xsi:type="pogoDsl:UShortType"/> - <status abstract="false" inherited="true" concrete="true"/> - <properties description="Current logging level to Syslog for this device - 
initialises from StorageLoggingLevelDefault on first execution of device.
Needs to be READ_WRITE To make it memorized - but writing this attribute should 
do the same as command SetStorageLoggingLevel to ensure the targets and adjustments
are made correctly" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> - </attributes> <attributes name="testMode" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" memorized="true" allocReadMember="true"> <dataType xsi:type="pogoDsl:StringType"/> <status abstract="false" inherited="true" concrete="true"/> @@ -283,6 +272,14 @@ <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> <properties description="A list of capability types with no. of instances in use on this subarray; e.g.
Correlators:512, PssBeams:4, PstBeams:4, VlbiBeams:0." label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> + <attributes name="loggingTargets" attType="Spectrum" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="3" maxY="" allocReadMember="true" isDynamic="false"> + <dataType xsi:type="pogoDsl:StringType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <dataReadyEvent fire="false" libCheckCriteria="true"/> + <status abstract="false" inherited="true" concrete="true"/> + <properties description="Current logging targets for this device - 
initialises to LoggingTargetsDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> <states name="ON" description="This state could have been called OK or OPERATIONAL. It means that the device is in its operational state. (E.g. the power supply is giving its nominal current, th motor is ON and ready to move, the instrument is operating). This state is modified by the Attribute alarm checking of the DeviceImpl:dev_state method. i.e. if the State is ON and one attribute has its quality factor to ATTR_WARNING or ATTR_ALARM, then the State is modified to ALARM."> <status abstract="false" inherited="true" concrete="true"/> </states> @@ -309,16 +306,13 @@ </states> <preferences docHome="./doc_html" makefileHome="$(TANGO_HOME)"/> <overlodedPollPeriodObject name="adminMode" type="attribute" pollPeriod="0"/> - <overlodedPollPeriodObject name="centralLoggingLevel" type="attribute" pollPeriod="0"/> <overlodedPollPeriodObject name="configurationDelayExpected" type="attribute" pollPeriod="0"/> <overlodedPollPeriodObject name="configurationProgress" type="attribute" pollPeriod="0"/> <overlodedPollPeriodObject name="controlMode" type="attribute" pollPeriod="0"/> - <overlodedPollPeriodObject name="elementLoggingLevel" type="attribute" pollPeriod="0"/> <overlodedPollPeriodObject name="healthState" type="attribute" pollPeriod="0"/> <overlodedPollPeriodObject name="obsMode" type="attribute" pollPeriod="0"/> <overlodedPollPeriodObject name="obsState" type="attribute" pollPeriod="0"/> <overlodedPollPeriodObject name="simulationMode" type="attribute" pollPeriod="0"/> - <overlodedPollPeriodObject name="storageLoggingLevel" type="attribute" pollPeriod="0"/> <overlodedPollPeriodObject name="testMode" type="attribute" pollPeriod="0"/> </classes> </pogoDsl:PogoSystem> diff --git a/skabase/SKASubarray/test/SKASubarray_test.py b/skabase/SKASubarray/test/SKASubarray_test.py index b6a101b61fbd7dd9f9d36d2bf87932bf0038b25d..ff226f0e65df13418cf3983e81edac43a6dbd29c 100644 --- a/skabase/SKASubarray/test/SKASubarray_test.py +++ b/skabase/SKASubarray/test/SKASubarray_test.py @@ -32,11 +32,9 @@ class TestSKASubarray(object): properties = { 'CapabilityTypes': '', - 'CentralLoggingTarget': '', - 'ElementLoggingTarget': '', 'GroupDefinitions': '', 'SkaLevel': '4', - 'StorageLoggingTarget': 'localhost', + 'LoggingTargetsDefault': ['console::cout'], 'SubID': '', } @@ -244,14 +242,6 @@ class TestSKASubarray(object): assert (re.match(buildPattern, tango_context.device.buildState)) is not None # PROTECTED REGION END # // SKASubarray.test_buildState - # PROTECTED REGION ID(SKASubarray.test_centralLoggingLevel_decorators) ENABLED START # - # PROTECTED REGION END # // SKASubarray.test_centralLoggingLevel_decorators - def test_centralLoggingLevel(self, tango_context): - """Test for centralLoggingLevel""" - # PROTECTED REGION ID(SKASubarray.test_centralLoggingLevel) ENABLED START # - assert tango_context.device.centralLoggingLevel == 0 - # PROTECTED REGION END # // SKASubarray.test_centralLoggingLevel - # PROTECTED REGION ID(SKASubarray.test_configurationDelayExpected_decorators) ENABLED START # # PROTECTED REGION END # // SKASubarray.test_configurationDelayExpected_decorators def test_configurationDelayExpected(self, tango_context): @@ -276,14 +266,6 @@ class TestSKASubarray(object): assert tango_context.device.controlMode == 0 # PROTECTED REGION END # // SKASubarray.test_controlMode - # PROTECTED REGION ID(SKASubarray.test_elementLoggingLevel_decorators) ENABLED START # - # PROTECTED REGION END # // SKASubarray.test_elementLoggingLevel_decorators - def test_elementLoggingLevel(self, tango_context): - """Test for elementLoggingLevel""" - # PROTECTED REGION ID(SKASubarray.test_elementLoggingLevel) ENABLED START # - assert tango_context.device.elementLoggingLevel == 0 - # PROTECTED REGION END # // SKASubarray.test_elementLoggingLevel - # PROTECTED REGION ID(SKASubarray.test_healthState_decorators) ENABLED START # # PROTECTED REGION END # // SKASubarray.test_healthState_decorators def test_healthState(self, tango_context): @@ -316,14 +298,6 @@ class TestSKASubarray(object): assert tango_context.device.simulationMode is False # PROTECTED REGION END # // SKASubarray.test_simulationMode - # PROTECTED REGION ID(SKASubarray.test_storageLoggingLevel_decorators) ENABLED START # - # PROTECTED REGION END # // SKASubarray.test_storageLoggingLevel_decorators - def test_storageLoggingLevel(self, tango_context): - """Test for storageLoggingLevel""" - # PROTECTED REGION ID(SKASubarray.test_storageLoggingLevel) ENABLED START # - assert tango_context.device.storageLoggingLevel is 0 - # PROTECTED REGION END # // SKASubarray.test_storageLoggingLevel - # PROTECTED REGION ID(SKASubarray.test_testMode_decorators) ENABLED START # # PROTECTED REGION END # // SKASubarray.test_testMode_decorators def test_testMode(self, tango_context): diff --git a/skabase/SKATelState/SKATelState.xmi b/skabase/SKATelState/SKATelState.xmi index 16610a35db69d36a58294a7ac4d1a7307582569c..af2ea16f532f71c66650cd84493ade1066924446 100644 --- a/skabase/SKATelState/SKATelState.xmi +++ b/skabase/SKATelState/SKATelState.xmi @@ -19,18 +19,15 @@ <type xsi:type="pogoDsl:StringVectorType"/> <status abstract="false" inherited="true" concrete="true"/> </deviceProperties> - <deviceProperties name="CentralLoggingTarget" description="Pre-configured logging target CentralLogger DS"> - <type xsi:type="pogoDsl:StringType"/> - <status abstract="false" inherited="true" concrete="true"/> - </deviceProperties> - <deviceProperties name="ElementLoggingTarget" description="Pre-configured logging target ElementLogger DS"> - <type xsi:type="pogoDsl:StringType"/> + <deviceProperties name="LoggingLevelDefault" description="Default logging level at device startup.
(0=OFF, 1=FATAL, 2=ERROR, 3=WARNING, 4=INFO, 5=DEBUG)"> + <type xsi:type="pogoDsl:UShortType"/> <status abstract="false" inherited="true" concrete="true"/> + <DefaultPropValue>4</DefaultPropValue> </deviceProperties> - <deviceProperties name="StorageLoggingTarget" description="Pre-configured logging target for syslog"> - <type xsi:type="pogoDsl:StringType"/> + <deviceProperties name="LoggingTargetsDefault" description="Default logging targets at device startup.
Each item has the format: target_type::target_name.
To log to stdout, use 'console::cout'.
To log to syslog, use 'syslog::<address>',
 where <address> is a file path,
 for example 'syslog::/var/run/rsyslog/dev/log'.
To log to a file, use 'file::<path>',
 where <path> is a file path,
 for example 'file::/tmp/my_dev.log'."> + <type xsi:type="pogoDsl:StringVectorType"/> <status abstract="false" inherited="true" concrete="true"/> - <DefaultPropValue>localhost</DefaultPropValue> + <DefaultPropValue>console::cout</DefaultPropValue> </deviceProperties> <commands name="State" description="This command gets the device state (stored in its device_state data member) and returns it to the caller." execMethod="dev_state" displayLevel="OPERATOR" polledPeriod="0"> <argin description="none"> @@ -78,20 +75,12 @@ <status abstract="false" inherited="true" concrete="true"/> <properties description="Build state of this device" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> - <attributes name="centralLoggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true"> - <dataType xsi:type="pogoDsl:UShortType"/> - <status abstract="false" inherited="true" concrete="true"/> - <properties description="Current logging level to Central logging target for this device - 
initialises to CentralLoggingLevelDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> - </attributes> - <attributes name="elementLoggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true"> - <dataType xsi:type="pogoDsl:UShortType"/> - <status abstract="false" inherited="true" concrete="true"/> - <properties description="Current logging level to Element logging target for this device - 
initialises to ElementLoggingLevelDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> - </attributes> - <attributes name="storageLoggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" memorized="true" allocReadMember="true"> - <dataType xsi:type="pogoDsl:UShortType"/> + <attributes name="loggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true"> + <dataType xsi:type="pogoDsl:EnumType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> <status abstract="false" inherited="true" concrete="true"/> - <properties description="Current logging level to Syslog for this device - 
initialises from StorageLoggingLevelDefault on first execution of device.
Needs to be READ_WRITE To make it memorized - but writing this attribute should 
do the same as command SetStorageLoggingLevel to ensure the targets and adjustments
are made correctly" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + <properties description="Current logging level for this device - initialises to LoggingLevelDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> <attributes name="healthState" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true"> <dataType xsi:type="pogoDsl:EnumType"/> @@ -118,6 +107,14 @@ <status abstract="false" inherited="true" concrete="true"/> <properties description="The test mode of the device. 
Either no test mode (empty string) or an indication of the test mode." label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> + <attributes name="loggingTargets" attType="Spectrum" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="3" maxY="" allocReadMember="true" isDynamic="false"> + <dataType xsi:type="pogoDsl:StringType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <dataReadyEvent fire="false" libCheckCriteria="true"/> + <status abstract="false" inherited="true" concrete="true"/> + <properties description="Current logging targets for this device - 
initialises to LoggingTargetsDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> <states name="ON" description="This state could have been called OK or OPERATIONAL. It means that the device is in its operational state. (E.g. the power supply is giving its nominal current, th motor is ON and ready to move, the instrument is operating). This state is modified by the Attribute alarm checking of the DeviceImpl:dev_state method. i.e. if the State is ON and one attribute has its quality factor to ATTR_WARNING or ATTR_ALARM, then the State is modified to ALARM."> <status abstract="false" inherited="true" concrete="true"/> </states> diff --git a/skabase/SKATelState/test/SKATelState_test.py b/skabase/SKATelState/test/SKATelState_test.py index 14d3cb040bfdae7f6b41c52066f5e085f345c097..1394193ebef272cb810d71cb3b0277692eff803f 100644 --- a/skabase/SKATelState/test/SKATelState_test.py +++ b/skabase/SKATelState/test/SKATelState_test.py @@ -34,9 +34,7 @@ class TestSKATelState(object): 'TelStateConfigFile': '', 'SkaLevel': '4', 'GroupDefinitions': '', - 'CentralLoggingTarget': '', - 'ElementLoggingTarget': '', - 'StorageLoggingTarget': 'localhost', + 'LoggingTargetsDefault': ['console::cout'], } @classmethod @@ -110,30 +108,6 @@ class TestSKATelState(object): assert (re.match(versionIdPattern, tango_context.device.versionId)) is not None # PROTECTED REGION END # // SKATelState.test_versionId - # PROTECTED REGION ID(SKATelState.test_centralLoggingLevel_decorators) ENABLED START # - # PROTECTED REGION END # // SKATelState.test_centralLoggingLevel_decorators - def test_centralLoggingLevel(self, tango_context): - """Test for centralLoggingLevel""" - # PROTECTED REGION ID(SKATelState.test_centralLoggingLevel) ENABLED START # - assert tango_context.device.centralLoggingLevel == 0 - # PROTECTED REGION END # // SKATelState.test_centralLoggingLevel - - # PROTECTED REGION ID(SKATelState.test_elementLoggingLevel_decorators) ENABLED START # - # PROTECTED REGION END # // SKATelState.test_elementLoggingLevel_decorators - def test_elementLoggingLevel(self, tango_context): - """Test for elementLoggingLevel""" - # PROTECTED REGION ID(SKATelState.test_elementLoggingLevel) ENABLED START # - assert tango_context.device.elementLoggingLevel == 0 - # PROTECTED REGION END # // SKATelState.test_elementLoggingLevel - - # PROTECTED REGION ID(SKATelState.test_storageLoggingLevel_decorators) ENABLED START # - # PROTECTED REGION END # // SKATelState.test_storageLoggingLevel_decorators - def test_storageLoggingLevel(self, tango_context): - """Test for storageLoggingLevel""" - # PROTECTED REGION ID(SKATelState.test_storageLoggingLevel) ENABLED START # - assert tango_context.device.storageLoggingLevel == 0 - # PROTECTED REGION END # // SKATelState.test_storageLoggingLevel - # PROTECTED REGION ID(SKATelState.test_healthState_decorators) ENABLED START # # PROTECTED REGION END # // SKATelState.test_healthState_decorators def test_healthState(self, tango_context): diff --git a/skabase/SKATestDevice/SKATestDevice.py b/skabase/SKATestDevice/SKATestDevice.py index 71ea4ecce5f396709cb4e752749565cc8359e013..efec789e9bf8b71b4cd7c65fc8052a0ae9ca92fb 100644 --- a/skabase/SKATestDevice/SKATestDevice.py +++ b/skabase/SKATestDevice/SKATestDevice.py @@ -89,9 +89,6 @@ class SKATestDevice(with_metaclass(DeviceMeta, SKABaseDevice)): self._build_state = '{}, {}, {}'.format(release.name, release.version, release.description) self._version_id = release.version - self._storage_logging_level = int(tango.LogLevel.LOG_DEBUG) - self._element_logging_level = int(tango.LogLevel.LOG_DEBUG) - self._central_logging_level = int(tango.LogLevel.LOG_DEBUG) # PROTECTED REGION END # // SKATestDevice.init_device def always_executed_hook(self): diff --git a/skabase/SKATestDevice/SKATestDevice.xmi b/skabase/SKATestDevice/SKATestDevice.xmi index 77bde0dac2a4fa4a3b4ae44bee8be942e2b5fdfc..2ace4655c7a57a934f4b6c6bea8fe5de2c26406c 100644 --- a/skabase/SKATestDevice/SKATestDevice.xmi +++ b/skabase/SKATestDevice/SKATestDevice.xmi @@ -11,39 +11,20 @@ <status abstract="false" inherited="true" concrete="true"/> <DefaultPropValue>4</DefaultPropValue> </deviceProperties> - <deviceProperties name="CentralLoggingTarget" description="Pre-configured logging target CentralLogger DS"> - <type xsi:type="pogoDsl:StringType"/> - <status abstract="false" inherited="true" concrete="true"/> - </deviceProperties> - <deviceProperties name="ElementLoggingTarget" description="Pre-configured logging target ElementLogger DS"> - <type xsi:type="pogoDsl:StringType"/> - <status abstract="false" inherited="true" concrete="true"/> - </deviceProperties> - <deviceProperties name="StorageLoggingTarget" description="Pre-configured logging target for syslog"> - <type xsi:type="pogoDsl:StringType"/> - <status abstract="false" inherited="true" concrete="true"/> - <DefaultPropValue>localhost</DefaultPropValue> - </deviceProperties> - <deviceProperties name="CentralLoggingLevelDefault" description="Default logging level to Central logging target
(0=OFF, 1=FATAL, 2=ERROR, 3=WARNING, 4=INFO, 5=DEBUG)

Default: 2"> - <type xsi:type="pogoDsl:UShortType"/> - <status abstract="false" inherited="true" concrete="true"/> - </deviceProperties> - <deviceProperties name="ElementLoggingLevelDefault" description="Default logging level to Element logging target
(0=OFF, 1=FATAL, 2=ERROR, 3=WARNING, 4=INFO, 5=DEBUG)

Default: 3"> + <deviceProperties name="LoggingLevelDefault" description="Default logging level at device startup.
(0=OFF, 1=FATAL, 2=ERROR, 3=WARNING, 4=INFO, 5=DEBUG)"> <type xsi:type="pogoDsl:UShortType"/> <status abstract="false" inherited="true" concrete="true"/> + <DefaultPropValue>4</DefaultPropValue> </deviceProperties> - <deviceProperties name="StorageLoggingLevelStorage" description="Default logging level to Syslog logging target
(0=OFF, 1=FATAL, 2=ERROR, 3=WARNING, 4=INFO, 5=DEBUG)

Default: 4"> - <type xsi:type="pogoDsl:UShortType"/> + <deviceProperties name="LoggingTargetsDefault" description="Default logging targets at device startup.
Each item has the format: target_type::target_name.
To log to stdout, use 'console::cout'.
To log to syslog, use 'syslog::<address>',
 where <address> is a file path,
 for example 'syslog::/var/run/rsyslog/dev/log'.
To log to a file, use 'file::<path>',
 where <path> is a file path,
 for example 'file::/tmp/my_dev.log'."> + <type xsi:type="pogoDsl:StringVectorType"/> <status abstract="false" inherited="true" concrete="true"/> + <DefaultPropValue>console::cout</DefaultPropValue> </deviceProperties> <deviceProperties name="GroupDefinitions" description="Each string in the list is a JSON serialised dict defining the ``group_name``,
``devices`` and ``subgroups`` in the group. A TANGO Group object is created
for each item in the list, according to the hierarchy defined. This provides
easy access to the managed devices in bulk, or individually.

The general format of the list is as follows, with optional ``devices`` and
``subgroups`` keys:
 [ {``group_name``: ``<name>``,
 ``devices``: [``<dev name>``, ...]},
 {``group_name``: ``<name>``,
 ``devices``: [``<dev name>``, ``<dev name>``, ...],
 ``subgroups`` : [{<nested group>},
 {<nested group>}, ...]},
 ...
 ]

For example, a hierarchy of racks, servers and switches:
 [ {``group_name``: ``servers``,
 ``devices``: [``elt/server/1``, ``elt/server/2``,
 ``elt/server/3``, ``elt/server/4``]},
 {``group_name``: ``switches``,
 ``devices``: [``elt/switch/A``, ``elt/switch/B``]},
 {``group_name``: ``pdus``,
 ``devices``: [``elt/pdu/rackA``, ``elt/pdu/rackB``]},
 {``group_name``: ``racks``,
 ``subgroups``: [
 {``group_name``: ``rackA``,
 ``devices``: [``elt/server/1``, ``elt/server/2``,
 ``elt/switch/A``, ``elt/pdu/rackA``]},
 {``group_name``: ``rackB``,
 ``devices``: [``elt/server/3``, ``elt/server/4``,
 ``elt/switch/B``, ``elt/pdu/rackB``],
 ``subgroups``: []}
 ]} ]"> <type xsi:type="pogoDsl:StringVectorType"/> <status abstract="false" inherited="true" concrete="true"/> </deviceProperties> - <deviceProperties name="StorageLoggingLevelDefault" description="Default logging level to Syslog logging target
(0=OFF, 1=FATAL, 2=ERROR, 3=WARNING, 4=INFO, 5=DEBUG)

Default: 4"> - <type xsi:type="pogoDsl:UShortType"/> - <status abstract="false" inherited="true" concrete="true"/> - </deviceProperties> <commands name="GetVersionInfo" description="Array of version strings of all entities modelled by this device. 
(One level down only)
Each string in the array lists the version info for one entity
managed by this device. 
The first entry is version info for this TANGO Device itself.
The entities may be TANGO devices, or hardware LRUs or 
anything else this devices manages/models.
The intention with this command is that it can provide more 
detailed information than can be captured in the versionId 
and buildState attributes, if necessary.
In the minimal case the GetVersionInfo will contain only the 
versionId and buildState attributes of the next lower level
entities." execMethod="get_version_info" displayLevel="OPERATOR" polledPeriod="0"> <argin description=""> <type xsi:type="pogoDsl:VoidType"/> @@ -158,20 +139,12 @@ <status abstract="false" inherited="true" concrete="true"/> <properties description="Build state of this device" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> - <attributes name="centralLoggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true"> - <dataType xsi:type="pogoDsl:UShortType"/> - <status abstract="false" inherited="true" concrete="true"/> - <properties description="Current logging level to Central logging target for this device - 
initialises to CentralLoggingLevelDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> - </attributes> - <attributes name="elementLoggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true"> - <dataType xsi:type="pogoDsl:UShortType"/> - <status abstract="false" inherited="true" concrete="true"/> - <properties description="Current logging level to Element logging target for this device - 
initialises to ElementLoggingLevelDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> - </attributes> - <attributes name="storageLoggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" memorized="true" allocReadMember="true"> - <dataType xsi:type="pogoDsl:UShortType"/> + <attributes name="loggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true"> + <dataType xsi:type="pogoDsl:EnumType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> <status abstract="false" inherited="true" concrete="true"/> - <properties description="Current logging level to Syslog for this device - 
initialises from StorageLoggingLevelDefault on first execution of device.
Needs to be READ_WRITE To make it memorized - but writing this attribute should 
do the same as command SetStorageLoggingLevel to ensure the targets and adjustments
are made correctly" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + <properties description="Current logging level for this device - initialises to LoggingLevelDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> <attributes name="healthState" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true"> <dataType xsi:type="pogoDsl:EnumType"/> @@ -198,6 +171,14 @@ <status abstract="false" inherited="true" concrete="true"/> <properties description="The test mode of the device. 
Either no test mode (empty string) or an indication of the test mode." label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> + <attributes name="loggingTargets" attType="Spectrum" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="3" maxY="" allocReadMember="true" isDynamic="false"> + <dataType xsi:type="pogoDsl:StringType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <dataReadyEvent fire="false" libCheckCriteria="true"/> + <status abstract="false" inherited="true" concrete="true"/> + <properties description="Current logging targets for this device - 
initialises to LoggingTargetsDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> <states name="ON" description="This state could have been called OK or OPERATIONAL. It means that the device is in its operational state. (E.g. the power supply is giving its nominal current, th motor is ON and ready to move, the instrument is operating). This state is modified by the Attribute alarm checking of the DeviceImpl:dev_state method. i.e. if the State is ON and one attribute has its quality factor to ATTR_WARNING or ATTR_ALARM, then the State is modified to ALARM."> <status abstract="false" inherited="true" concrete="true"/> </states> @@ -223,9 +204,6 @@ <status abstract="false" inherited="true" concrete="true"/> </states> <preferences docHome="./doc_html" makefileHome="$(TANGO_HOME)"/> - <overlodedPollPeriodObject name="centralLoggingLevel" type="attribute" pollPeriod="0"/> - <overlodedPollPeriodObject name="elementLoggingLevel" type="attribute" pollPeriod="0"/> - <overlodedPollPeriodObject name="storageLoggingLevel" type="attribute" pollPeriod="0"/> <overlodedPollPeriodObject name="healthState" type="attribute" pollPeriod="0"/> <overlodedPollPeriodObject name="adminMode" type="attribute" pollPeriod="0"/> <overlodedPollPeriodObject name="controlMode" type="attribute" pollPeriod="0"/> diff --git a/skabase/SKATestDevice/test/SKATestDevice_test.py b/skabase/SKATestDevice/test/SKATestDevice_test.py index 966e0c74247d11b60704e84f40555baa456bd65f..52e60f66ec17d3783b9124bd89c429c96192bf64 100644 --- a/skabase/SKATestDevice/test/SKATestDevice_test.py +++ b/skabase/SKATestDevice/test/SKATestDevice_test.py @@ -22,6 +22,7 @@ path = os.path.join(os.path.dirname(__file__), os.pardir) sys.path.insert(0, os.path.abspath(path)) # PROTECTED REGION ID(SKATestDevice.test_additional_imports) ENABLED START # +from skabase.SKABaseDevice import TangoLoggingLevel # PROTECTED REGION END # // SKATestDevice.test_additional_imports # Device test case # PROTECTED REGION ID(SKATestDevice.test_SKATestDevice_decorators) ENABLED START # @@ -32,14 +33,9 @@ class TestSKATestDevice(object): properties = { 'SkaLevel': '4', - 'CentralLoggingTarget': '', - 'ElementLoggingTarget': '', - 'StorageLoggingTarget': 'localhost', - 'CentralLoggingLevelDefault': '', - 'ElementLoggingLevelDefault': '', - 'StorageLoggingLevelStorage': '', - 'GroupDefinitions': '', - 'StorageLoggingLevelDefault': '', + 'LoggingTargetsDefault': ['console::cout'], + 'LoggingLevelDefault': '4', + 'GroupDefinitions': '' } @classmethod @@ -167,30 +163,6 @@ class TestSKATestDevice(object): assert (re.match(versionIdPattern, tango_context.device.versionId)) is not None # PROTECTED REGION END # // SKATestDevice.test_versionId - # PROTECTED REGION ID(SKATestDevice.test_centralLoggingLevel_decorators) ENABLED START # - # PROTECTED REGION END # // SKATestDevice.test_centralLoggingLevel_decorators - def test_centralLoggingLevel(self, tango_context): - """Test for centralLoggingLevel""" - # PROTECTED REGION ID(SKATestDevice.test_centralLoggingLevel) ENABLED START # - assert tango_context.device.centralLoggingLevel == 5 - # PROTECTED REGION END # // SKATestDevice.test_centralLoggingLevel - - # PROTECTED REGION ID(SKATestDevice.test_elementLoggingLevel_decorators) ENABLED START # - # PROTECTED REGION END # // SKATestDevice.test_elementLoggingLevel_decorators - def test_elementLoggingLevel(self, tango_context): - """Test for elementLoggingLevel""" - # PROTECTED REGION ID(SKATestDevice.test_elementLoggingLevel) ENABLED START # - assert tango_context.device.elementLoggingLevel == 5 - # PROTECTED REGION END # // SKATestDevice.test_elementLoggingLevel - - # PROTECTED REGION ID(SKATestDevice.test_storageLoggingLevel_decorators) ENABLED START # - # PROTECTED REGION END # // SKATestDevice.test_storageLoggingLevel_decorators - def test_storageLoggingLevel(self, tango_context): - """Test for storageLoggingLevel""" - # PROTECTED REGION ID(SKATestDevice.test_storageLoggingLevel) ENABLED START # - assert tango_context.device.storageLoggingLevel == 5 - # PROTECTED REGION END # // SKATestDevice.test_storageLoggingLevel - # PROTECTED REGION ID(SKATestDevice.test_healthState_decorators) ENABLED START # # PROTECTED REGION END # // SKATestDevice.test_healthState_decorators def test_healthState(self, tango_context): diff --git a/skabase/auxiliary/faults.py b/skabase/auxiliary/faults.py index 5fb3160d3a2530a100412710f58770b1bed18003..0fb8cf06f5b2aa557fa09e0f00f77251a2b66b62 100644 --- a/skabase/auxiliary/faults.py +++ b/skabase/auxiliary/faults.py @@ -1,7 +1,17 @@ """General SKA Tango Device Exceptions.""" + class SKABaseError(Exception): """Base class for all SKA Tango Device exceptions.""" + class GroupDefinitionsError(SKABaseError): - """Raise if error parsing or creating groups from GroupDefinitions.""" + """Error parsing or creating groups from GroupDefinitions.""" + + +class LoggingLevelError(SKABaseError): + """Error evaluating logging level.""" + + +class LoggingTargetError(SKABaseError): + """Error parsing logging target string.""" diff --git a/skabase/conftest.py b/skabase/conftest.py index 7dffd64e1eadcb7328f529219cc3d1ef686b6b67..d538825a2c3010cf607286ee22811f5c9e71516d 100644 --- a/skabase/conftest.py +++ b/skabase/conftest.py @@ -21,9 +21,7 @@ def tango_context(request): """ ska_master_properties = { 'SkaLevel': '4', - 'CentralLoggingTarget': '', - 'ElementLoggingTarget': '', - 'StorageLoggingTarget': 'localhost', + 'LoggingTargetsDefault': ['console::cout'], 'GroupDefinitions': '', 'NrSubarrays': '16', 'CapabilityTypes': '', @@ -32,11 +30,9 @@ def tango_context(request): ska_subarray_properties = { 'CapabilityTypes': 'BAND1', - 'CentralLoggingTarget': '', - 'ElementLoggingTarget': '', + 'LoggingTargetsDefault': ['console::cout'], 'GroupDefinitions': '', 'SkaLevel': '4', - 'StorageLoggingTarget': 'localhost', 'SubID': '1', } diff --git a/skabase/release.py b/skabase/release.py index d83597bc392b2e512b12312a611da22eb4c81365..a98e77dbfb9abf51d74d0420e5e52dbc5581c46a 100644 --- a/skabase/release.py +++ b/skabase/release.py @@ -7,7 +7,7 @@ """Release information for lmc-base-classes Python Package""" name = """lmcbaseclasses""" -version = "0.1.4" +version = "0.2.0" version_info = version.split(".") description = """A set of generic base devices for SKA Telescope.""" author = "SKA India and SARAO"