diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000000000000000000000000000000000000..5adb2b83cf466768d3165102fcdc58db524e6e4e --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1 @@ +include brian_polling_manager/logging_default_config.json diff --git a/brian_polling_manager/cli.py b/brian_polling_manager/cli.py index 6711ed41ade9b6cb233016a94b562a2cafbb1ab7..f09828671d643231e864b861ad176c5c6616764c 100644 --- a/brian_polling_manager/cli.py +++ b/brian_polling_manager/cli.py @@ -30,7 +30,7 @@ from typing import Union import click import jsonschema -from brian_polling_manager import inventory, interfaces +from brian_polling_manager import inventory, interfaces, environment logger = logging.getLogger(__name__) @@ -59,7 +59,8 @@ _DEFAULT_CONFIG = { '{interface} {ifIndex}'), } }, - 'statedir': '/tmp/' + 'statedir': '/tmp/', + 'logging': environment.DEFAULT_LOGGING_FILENAME } CONFIG_SCHEMA = { @@ -111,7 +112,8 @@ CONFIG_SCHEMA = { 'minItems': 1 }, 'sensu': {'$ref': '#/definitions/sensu'}, - 'statedir': {'type': 'string'} + 'statedir': {'type': 'string'}, + 'logging': {'type': 'string'} }, 'required': ['inventory', 'sensu', 'statedir'], 'additionalProperties': False @@ -186,7 +188,7 @@ class State(object): f.write(json.dumps(new_interfaces)) -def _validate_config(ctx, param, value): +def _validate_config(ctx, param, file): """ loads, validates and returns configuration parameters @@ -195,12 +197,11 @@ def _validate_config(ctx, param, value): :param value: filename (string) :return: a dict containing configuration parameters """ - if value is None: + if file is None: config = _DEFAULT_CONFIG else: try: - with open(value) as f: - config = json.loads(f.read()) + config = json.loads(file.read()) except (json.JSONDecodeError, jsonschema.ValidationError) as e: raise click.BadParameter(str(e)) @@ -209,6 +210,8 @@ def _validate_config(ctx, param, value): except jsonschema.ValidationError as e: raise click.BadParameter(str(e)) + environment.setup_logging(config.get('logging', None)) + return config @@ -216,13 +219,13 @@ def _validate_config(ctx, param, value): @click.option( '--config', default=None, - type=click.STRING, + type=click.File('r'), callback=_validate_config, help='configuration filename') @click.option( '--force/--no-force', default=False, - help="update even if inventory hasn't been updated") + help="refresh inventory data even if it hasn't been updated") def main(config, force): """ Update BRIAN snmp checks based on Inventory Provider data. @@ -238,5 +241,4 @@ def main(config, force): if __name__ == '__main__': - logging.basicConfig(level=logging.DEBUG) main() diff --git a/brian_polling_manager/environment.py b/brian_polling_manager/environment.py new file mode 100644 index 0000000000000000000000000000000000000000..966284950140afbaf72e84ffc53a91f84f8795b8 --- /dev/null +++ b/brian_polling_manager/environment.py @@ -0,0 +1,24 @@ +import json +import logging.config +import os + +DEFAULT_LOGGING_FILENAME = os.path.join( + os.path.dirname(__file__), + 'logging_default_config.json') + + +def setup_logging(filename=None): + """ + set up logging using the configured filename + """ + if not filename: + filename = DEFAULT_LOGGING_FILENAME + + with open(filename) as f: + # TODO: this mac workaround should be removed ... + d = json.loads(f.read()) + import platform + if platform.system() == 'Darwin': + d['handlers']['syslog_handler']['address'] = '/var/run/syslog' + logging.config.dictConfig(d) + # logging.config.dictConfig(json.loads(f.read())) diff --git a/brian_polling_manager/interfaces.py b/brian_polling_manager/interfaces.py index 4c47e5969b38bc578c27d1a5b6be7e3688fa0026..cde5cef82dfc2ce39ae3a150661f9dfbf806a861 100644 --- a/brian_polling_manager/interfaces.py +++ b/brian_polling_manager/interfaces.py @@ -46,8 +46,8 @@ def _make_check(check_params, interface): def _checks_match(a, b) -> bool: - # if a['command'] != b['command']: - # return False + if a['command'] != b['command']: + return False if a['interval'] != b['interval']: return False if a['proxy_entity_name'] != b['proxy_entity_name']: diff --git a/brian_polling_manager/logging_default_config.json b/brian_polling_manager/logging_default_config.json new file mode 100644 index 0000000000000000000000000000000000000000..bfab907634c09de48cbd2f0bd29c28bf292753dd --- /dev/null +++ b/brian_polling_manager/logging_default_config.json @@ -0,0 +1,59 @@ +{ + "version": 1, + "disable_existing_loggers": false, + "formatters": { + "simple": { + "format": "%(asctime)s - %(name)s (%(lineno)d) - %(levelname)s - %(message)s" + } + }, + + "handlers": { + "console": { + "class": "logging.StreamHandler", + "level": "DEBUG", + "formatter": "simple", + "stream": "ext://sys.stdout" + }, + + "syslog_handler": { + "class": "logging.handlers.SysLogHandler", + "level": "DEBUG", + "address": "/dev/log", + "facility": "user", + "formatter": "simple" + }, + + "info_file_handler": { + "class": "logging.handlers.RotatingFileHandler", + "level": "INFO", + "formatter": "simple", + "filename": "info.log", + "maxBytes": 10485760, + "backupCount": 20, + "encoding": "utf8" + }, + + "error_file_handler": { + "class": "logging.handlers.RotatingFileHandler", + "level": "ERROR", + "formatter": "simple", + "filename": "errors.log", + "maxBytes": 10485760, + "backupCount": 20, + "encoding": "utf8" + } + }, + + "loggers": { + "brian_polling_manager": { + "level": "DEBUG", + "handlers": ["console", "syslog_handler"], + "propagate": false + } + }, + + "root": { + "level": "DEBUG", + "handlers": ["console", "syslog_handler"] + } +} diff --git a/brian_polling_manager/sensu.py b/brian_polling_manager/sensu.py index 300f620d5c259e651aa248b8377fc1ef4409d3a6..18c6b9831604b5596661bc4cc13762889e1f9756 100644 --- a/brian_polling_manager/sensu.py +++ b/brian_polling_manager/sensu.py @@ -23,7 +23,7 @@ def load_all_checks(params, namespace='default'): def create_check(params, check, namespace='default'): - logger.debug(f'creating missing check: {check["metadata"]["name"]}') + logger.info(f'creating missing check: {check["metadata"]["name"]}') url = random.choice(params['api-base']) r = requests.post( f'{url}/api/core/v2/namespaces/{namespace}/checks', @@ -37,7 +37,7 @@ def create_check(params, check, namespace='default'): def update_check(params, check, namespace='default'): name = check["metadata"]["name"] - logger.debug(f'updating existing check: {name}') + logger.info(f'updating existing check: {name}') url = random.choice(params['api-base']) r = requests.put( f'{url}/api/core/v2/namespaces/{namespace}/checks/{name}', @@ -54,7 +54,7 @@ def delete_check(params, check, namespace='default'): name = check else: name = check["metadata"]["name"] - logger.debug(f'deleting unwanted check: {name}') + logger.info(f'deleting unwanted check: {name}') url = random.choice(params['api-base']) r = requests.delete( f'{url}/api/core/v2/namespaces/{namespace}/checks/{name}', diff --git a/setup.py b/setup.py index 39f8d84e528dc3435a53b9d5121efedc8824a140..05a2c7fe59e4194b93bc0674a74e406ac20c57db 100644 --- a/setup.py +++ b/setup.py @@ -18,4 +18,5 @@ setup( 'brian-polling-manager=brian_polling_manager.cli:main' ] }, + include_package_data=True, )