Envoyer les journaux à RabbitMQ depuis Python/Django

python-logging-rabbitmq

Statut de la construction

Le gestionnaire de journalisation envoie les journaux à RabbitMQ. Compatible avec Django.

Installation

Installer à l'aide de pip.

pip install python_logging_rabbitmq

Versions

Versions Dépendance
>= 2.x Pika == 0,13
<= 1.1.1 Pika <= 0,10

Gestionnaires

Ce package a deux gestionnaires intégrés que vous pouvez importer comme suit :

de python_logging_rabbitmq import RabbitMQHandler

ou (merci à @wallezhang)

de python_logging_rabbitmq import RabbitMQHandlerOneWay

| Gestionnaire | Descriptif |
|-----------------------|------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -----------|
| LapinMQHandler | Gestionnaire de base pour l'envoi de journaux à RabbitMQ. Chaque enregistrement sera livré directement à RabbitMQ à l'aide de l'échange configuré. |
| LapinMQHandlerOneWay | Gestionnaire à haut débit. Initialise une file d'attente interne dans laquelle les journaux sont stockés temporairement. Un thread est utilisé pour livrer les journaux à RabbitMQ à l'aide de l'échange configuré. Votre application n'a pas besoin d'attendre la livraison du journal. Notez que si le thread principal meurt, vous risquez de perdre des journaux. |

Python autonome

Pour l'utiliser avec python, créez d'abord un enregistreur pour votre application, puis créez une instance du gestionnaire et ajoutez-la à l'enregistreur créé.

import logging
from python_logging_rabbitmq import RabbitMQHandler

logger = logging.getLogger('myapp')
logger.setLevel(logging.DEBUG)

rabbit = RabbitMQHandler(host='localhost', port=5672)
logger.addHandler(rabbit)

logger.debug('test debug')

En conséquence, un message similaire au suivant sera envoyé à RabbitMQ :

{
	"relativeCreated":280.61580657958984,
	"process":13105,
	"args":[],
	"module":"test",
	"funcName":"<module>",
	"host":"albertomr86-laptop",
	"exc_text":null,
	"name":"myapp",
	"thread":140032818181888,
	"created":1482290387.454017,
	"threadName":"MainThread",
	"msecs":454.01692390441895,
	"filename":"test.py",
	"levelno":10,
	"processName":"MainProcess",
	"pathname":"test.py",
	"lineno":11,
	"msg":"test debug",
	"exc_info":null,
	"levelname":"DEBUG"
}

Envoi des journaux

Par défaut, les logs seront envoyés à RabbitMQ en utilisant l'échange 'log', cela devrait être de type topic. La clé de routage utilisée est formée par la concaténation du nom du logger et du niveau de log. Par exemple:

import logging
from python_logging_rabbitmq import RabbitMQHandler

logger = logging.getLogger('myapp')
logger.setLevel(logging.DEBUG)
logger.addHandler(RabbitMQHandler(host='localhost', port=5672))

logger.info('test info')
logger.debug('test debug')
logger.warning('test warning')

Les messages seront envoyés à l'aide des clés de routage suivantes :

  • monapplication.INFO
  • monapp.DEBUG
  • myapp.AVERTISSEMENT

Pour une explication sur les sujets et les clés de routage, rendez-vous sur https://www.rabbitmq.com/tutorials/tutorial-five-python.html

Lors de la création du gestionnaire, vous pouvez spécifier différents paramètres pour vous connecter à RabbitMQ ou configurer le comportement du gestionnaire.

Remplacement de la création de la clé de routage

Si vous souhaitez remplacer entièrement le format de la clé de routage, vous pouvez passer
fonction routing_key_formatter qui prend les objets LogRecord et renvoie
clé de routage. Par exemple:

RabbitMQHandler(
	host='localhost',
	port=5672,
	routing_key_formatter=lambda r: (
		'some_exchange_prefix.{}'.format(r.levelname.lower())
	)
)

Configuration

Voici les configurations autorisées :

Parameter Description Default
host RabbitMQ Server hostname or ip address. localhost
port RabbitMQ Server port. 5672
username Username for authentication. None
password Provide a password for the username. None
exchange Name of the exchange to publish the logs. This exchange is considered of type topic. log
declare_exchange Whether or not to declare the exchange. False
routing_key_format Customize how messages are routed to the queues. {name}.{level}
routing_key_formatter Customize how routing-key is constructed. None
connection_params Allow extra params to connect with RabbitMQ. None
formatter Use custom formatter for the logs. python_logging_rabbitmq.JSONFormatter
close_after_emit Close the active connection after send a log. A new connection is open for the next log. False
fields Dict to add as a field in each logs send to RabbitMQ. This is useful when you want fields in each log but without pass them every time. None
fields_under_root When is True, each key in parameter 'fields' will be added as an entry in the log, otherwise they will be logged under the key 'fields'. True
message_headers A dictionary of headers to be published with the message. None
record_fields A set of attributes that should be preserved from the record object. None
exclude_record_fields A set of attributes that should be ignored from the record object. None
heartbeat Lower bound for heartbeat timeout 60

Exemples

Connexion RabbitMQ

rabbit = RabbitMQHandler(
	host='localhost',
	port=5672,
	username='guest',
	password='guest',
	connection_params={
		'virtual_host': '/',
		'connection_attempts': 3,
		'socket_timeout': 5000
	}
)

Les champs personnalisés

import logging
from python_logging_rabbitmq import RabbitMQHandler

FORMAT = '%(asctime)-15s %(message)s'
formatter = logging.Formatter(fmt=FORMAT)
rabbit = RabbitMQHandler(formatter=formatter)

Formateur personnalisé

Par défaut, python_logging_rabbitmq implémente un JSONFormatter personnalisé ; mais si vous préférez formater votre propre message, vous pouvez le faire comme suit :

LOGGING = {
	'version': 1,
	'disable_existing_loggers': False,
	'handlers': {
		'rabbit': {
			'level': 'DEBUG',
			'class': 'python_logging_rabbitmq.RabbitMQHandler',
			'host': 'localhost'
		}
	},
	'loggers': {
		'myapp': {
			'handlers': ['rabbit'],
			'level': 'DEBUG',
			'propagate': False
		}
	}
}

Pour un formateur JSON personnalisé, consultez https://github.com/madzak/python-json-logger

Django

Pour l'utiliser avec Django, ajoutez le gestionnaire dans la configuration de journalisation.

ENREGISTREMENT = {
	'version 1,
	'disable_existing_loggers' : Faux,
	'gestionnaires' : {
		'lapin': {
			'niveau': 'DEBUG',
			'class' : 'python_logging_rabbitmq.RabbitMQHandler',
			'hôte': 'localhost'
		}
	},
	'enregistreurs' : {
		'monapplication' : {
			'manipulateurs' : ['lapin'],
			'niveau': 'DEBUG',
			'propager' : Faux
		}
	}
}

Configuration

Comme lorsque vous l'utilisez avec python autonome, vous pouvez configurer le handle directement lors de sa déclaration dans la configuration :

LOGGING = {
	'version': 1,
	'disable_existing_loggers': False,
	'handlers': {
		'rabbit': {
			'level': 'DEBUG',
			'class': 'python_logging_rabbitmq.RabbitMQHandler',
			'host': 'localhost',
			'port': 5672,
			'username': 'guest',
			'password': 'guest',
			'exchange': 'log',
			'declare_exchange': False,
			'connection_params': {
				'virtual_host': '/',
				'connection_attempts': 3,
				'socket_timeout': 5000
			},
			'fields': {
				'source': 'MainAPI',
				'env': 'production'
			},
			'fields_under_root': True
		}
	},
	'loggers': {
		'myapp': {
			'handlers': ['rabbit'],
			'level': 'DEBUG',
			'propagate': False
		}
	}
}

Formateur personnalisé

LOGGING = {
	'version': 1,
	'disable_existing_loggers': False,
	'formatters': {
		'standard': {
			'format': '%(levelname)-8s [%(asctime)s]: %(message)s'
		}
	},
	'handlers': {
		'rabbit': {
			'level': 'DEBUG',
			'class': 'python_logging_rabbitmq.RabbitMQHandler',
			'host': 'localhost',
			'formatter': 'standard'
		}
	},
	'loggers': {
		'myapp': {
			'handlers': ['rabbit'],
			'level': 'DEBUG',
			'propagate': False
		}
	}
}

Formateur JSON

pip install python-json-logger
LOGGING = {
	'version': 1,
	'disable_existing_loggers': False,
	'formatters': {
		'json': {
			'()': 'pythonjsonlogger.jsonlogger.JsonFormatter',
			'fmt': '%(name)s %(levelname) %(asctime)s %(message)s'
		}
	},
	'handlers': {
		'rabbit': {
			'level': 'DEBUG',
			'class': 'python_logging_rabbitmq.RabbitMQHandler',
			'host': 'localhost',
			'formatter': 'json'
		}
	},
	'loggers': {
		'myapp': {
			'handlers': ['rabbit'],
			'level': 'DEBUG',
			'propagate': False
		}
	}
}

Communiqués

| Date | Versions | Remarques |
|---------------|---------|------------------------ ----------------------------------|
| 10 mars 2019 | 1.1.1 | Suppression de la dépendance directe avec Django. Intégration avec Travis CI. Configuration pour les tests. En utilisant pipenv. |
| 04 mai 2018 | 1.0.9 | Correction du paramètre exchange_type dans channel.exchange_declare (Merci à @cklos). |
| 21 mars 2018 | 1.0.8 | Autoriser les en-têtes de message (Merci à @merretbuurman). |
| 15 mai 2017 | 1.0.7 | Ajout du support pour personnaliser le routing_key (Merci à @hansyulian). |
| 30 mars 2017 | 1.0.6 | Correction de la compatibilité avec python3 dans RabbitMQHandlerOneWay (par @sactre). |
| 28 mars 2017 | 1.0.5 | Importations locales explicites. |
| 16 mars 2017 | 1.0.4 | Ajout du nouveau gestionnaire RabbitMQHandlerOneWay (par @wallezhang). |
| 14 mars 2017 | 1.0.3 | Ajout du paramètre de configuration close_after_emit. |
| 21 déc. 2016 | 1.0.2 | Corrections mineures. |
| 21 déc. 2016 | 1.0.1 | Corrections mineures. |
| 21 déc. 2016 | 1.0.0 | Première version. |

Et après?

  • Parlons des tests.
  • Les problèmes, les demandes de tirage, les suggestions sont les bienvenues.
  • Fourche et améliore-le. Gratuit pour tous.

Des efforts similaires