diff options
| author | Thomas Mangin <thomas.mangin@exa.net.uk> | 2020-04-20 16:07:59 +0100 | 
|---|---|---|
| committer | Thomas Mangin <thomas.mangin@exa.net.uk> | 2020-04-20 16:07:59 +0100 | 
| commit | b704d0676ab2d623d2eeb1ed4dc1bcf2a2c4a5e2 (patch) | |
| tree | 6d5232d15befa14e77ee7e82f839cdff95867ec9 | |
| parent | 6b8a6619533c7f47a63e041efb516ad91b10b4da (diff) | |
| download | vyos-1x-b704d0676ab2d623d2eeb1ed4dc1bcf2a2c4a5e2.tar.gz vyos-1x-b704d0676ab2d623d2eeb1ed4dc1bcf2a2c4a5e2.zip  | |
airbag: T2186: generic syslog
| -rw-r--r-- | python/vyos/airbag.py | 20 | ||||
| -rw-r--r-- | python/vyos/logger.py | 143 | 
2 files changed, 150 insertions, 13 deletions
diff --git a/python/vyos/airbag.py b/python/vyos/airbag.py index b0565192d..a2e9de491 100644 --- a/python/vyos/airbag.py +++ b/python/vyos/airbag.py @@ -15,15 +15,13 @@  import os  import sys -import logging -import logging.handlers  from datetime import datetime  from vyos import debug  from vyos.config import Config  from vyos.version import get_version  from vyos.util import run - +from vyos.logger import syslog  # we allow to disable the extra logging  DISABLE = False @@ -62,7 +60,7 @@ def bug_report(dtype, value, trace):      information = {          'date': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),          'version': get_version(), -        'trace': format_exception(dtype, value, trace), +        'trace': '\n'.join(format_exception(dtype, value, trace)),          'instructions': COMMUNITY if 'rolling' in get_version() else SUPPORTED,      } @@ -82,19 +80,14 @@ def intercepter(dtype, value, trace):          pdb.pm() -def InterceptingLogger(address, _singleton=[False]): +def InterceptingLogger(_singleton=[False]):      skip = _singleton.pop()      _singleton.append(True)      if skip:          return -    logger = logging.getLogger('VyOS') -    logger.setLevel(logging.DEBUG) -    handler = logging.handlers.SysLogHandler(address='/dev/log', facility='syslog') -    logger.addHandler(handler) -      # log to syslog any message sent to stderr -    sys.stderr = _IO(sys.stderr, logger.critical) +    sys.stderr = _IO(sys.stderr, syslog.critical)  # lists as default arguments in function is normally dangerous @@ -124,14 +117,15 @@ except:  # running testing so we are checking that we are on the router  # as otherwise it prevents dpkg-buildpackage to work  if get_version() and insession: -    InterceptingLogger('/run/systemd/journal/dev-log') +    InterceptingLogger()      InterceptingException(intercepter)  # Messages to print +# if the key before the value has not time, syslog takes that as the source of the message  FAULT = """\ -Date:       {date} +Fault Time: {date}  VyOS image: {version}  {trace} diff --git a/python/vyos/logger.py b/python/vyos/logger.py new file mode 100644 index 000000000..f7cc964d5 --- /dev/null +++ b/python/vyos/logger.py @@ -0,0 +1,143 @@ +# Copyright 2020 VyOS maintainers and contributors <maintainers@vyos.io> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library.  If not, see <http://www.gnu.org/licenses/>. + +# A wrapper class around logging to make it easier to use + +# for a syslog logger: +# from vyos.logger import syslog +# syslog.critical('message') + +# for a stderr logger: +# from vyos.logger import stderr +# stderr.critical('message') + +# for a custom logger (syslog and file): +# from vyos.logger import getLogger +# combined = getLogger(__name__, syslog=True, stream=sys.stdout, filename='/tmp/test') +# combined.critical('message') + +import sys +import logging +import logging.handlers as handlers + +TIMED = '%(asctime)s: %(message)s' +SHORT = '%(filename)s: %(message)s' +CLEAR = '%(levelname) %(asctime)s %(filename)s: %(message)s' + +_levels = { +    'CRITICAL': logging.CRITICAL, +   	'ERROR': logging.CRITICAL, +   	'WARNING': logging.WARNING, +   	'INFO': logging.INFO, +   	'DEBUG': logging.DEBUG, +   	'NOTSET': logging.NOTSET, +} + +# prevent recreation of already created logger +_created = {} + +def getLogger(name=None, **kwargs): +	if name in _created: +		if len(kwargs) == 0: +			return _created[name] +		raise ValueError('a logger with the name "{name} already exists') + +	logger = logging.getLogger(name) +	logger.setLevel(_levels[kwargs.get('level', 'DEBUG')]) + +	if 'address' in kwargs or kwargs.get('syslog', False): +		logger.addHandler(_syslog(**kwargs)) +	if 'stream' in kwargs: +		logger.addHandler(_stream(**kwargs)) +	if 'filename' in kwargs: +		logger.addHandler(_file(**kwargs)) + +	_created[name] = logger +	return logger + + +def _syslog(**kwargs): +	formating = kwargs.get('format', SHORT) +	handler = handlers.SysLogHandler( +		address=kwargs.get('address', '/dev/log'), +		facility=kwargs.get('facility', 'syslog'), +	) +	handler.setFormatter(logging.Formatter(formating)) +	return handler + + +def _stream(**kwargs): +	formating = kwargs.get('format', CLEAR) +	handler = logging.StreamHandler( +		stream=kwargs.get('stream', sys.stderr), +	) +	handler.setFormatter(logging.Formatter(formating)) +	return handler + + +def _file(**kwargs): +	formating = kwargs.get('format', CLEAR) +	handler = handlers.RotatingFileHandler( +		filename=kwargs.get('filename', 1048576), +		maxBytes=kwargs.get('maxBytes', 1048576), +		backupCount=kwargs.get('backupCount', 3), +	) +	handler.setFormatter(logging.Formatter(formating)) +	return handler + + +# exported pre-built logger, please keep in mind that the names +# must be unique otherwise the logger are shared + +# a logger for stderr +stderr = getLogger( +	'VyOS Syslog', +	format=SHORT, +	stream=sys.stderr, +	address='/dev/log' +) + +# a logger to syslog +syslog = getLogger( +	'VyOS StdErr', +	format='%(message)s', +	address='/dev/log' +) + + +# testing +if __name__ == '__main__': +	# from vyos.logger import getLogger +	formating = '%(asctime)s (%(filename)s) %(levelname)s: %(message)s' + +	# syslog logger +	# syslog=True if no 'address' field is provided +	syslog = getLogger(__name__ + '.1', syslog=True, format=formating) +	syslog.info('syslog test') + +	# steam logger +	stream = getLogger(__name__ + '.2', stream=sys.stdout, level='ERROR') +	stream.info('steam test') + +	# file logger +	filelog = getLogger(__name__ + '.3', filename='/tmp/test') +	filelog.info('file test') + +	# create a combined logger +	getLogger('VyOS', syslog=True, stream=sys.stdout, filename='/tmp/test') + +	# recover the created logger from name +	combined = getLogger('VyOS') +	combined.info('combined test')  | 
