Implémentation d'un "moteur de règles" en Python
Je suis en train d'écrire un journal de collecte et de l'analyse de l'application en Python et j'ai besoin d'écrire un "moteur de règles" pour correspondre et de la loi sur l'enregistrement des messages.
Il doit fonctionnalité:
- Expression régulière correspondant pour le message lui-même
- Comparaisons arithmétiques pour la gravité du message/priorité
- Opérateurs booléens
J'ai la vision d'Un exemple, la règle serait probablement quelque chose comme:
(message ~ "program\\[\d+\\]: message" and severity >= high) or (severity >= critical)
Je suis en train de réfléchir à l'aide de PyParsing ou similaires à fait d'analyser les règles et construire l'arbre d'analyse.
Le courant (pas encore implémenté) conception que j'ai à l'esprit est d'avoir des classes pour chaque type de règle, et de la construction et de la chaîne d'ensemble selon l'arbre d'analyse. Ensuite, chaque règle aurait une "correspond à la" méthode qui pourrait prendre un objet de message de retour si oui ou non il correspond à la règle.
Très rapidement, quelque chose comme:
class RegexRule(Rule):
def __init__(self, regex):
self.regex = regex
def match(self, message):
return self.regex.match(message.contents)
class SeverityRule(Rule):
def __init__(self, operator, severity):
self.operator = operator
def match(self, message):
if operator == ">=":
return message.severity >= severity
# more conditions here...
class BooleanAndRule(Rule):
def __init__(self, rule1, rule2):
self.rule1 = rule1
self.rule2 = rule2
def match(self, message):
return self.rule1.match(message) and self.rule2.match(message)
Ces règle des classes serait alors enchaînés selon l'arbre d'analyse du message, et la méthode match() appelée sur le dessus de la règle, qui serait en cascade vers le bas jusqu'à ce que toutes les règles ont été évalués.
Je me demande simplement si cette approche est raisonnable, ou si mon design et idées sont totalement hors de contrôle? Malheureusement, je n'ai jamais eu la chance de prendre un compilateur cours de conception ou de quoi que ce soit en Université, donc je suis assez bien venir avec ce genre de choses de moi-même.
Quelqu'un pourrait-il avec une certaine expérience dans ces sortes de choses, s'il vous plaît carillon et d'évaluer l'idée?
EDIT:
Quelques bonnes réponses jusqu'à présent, voici un peu de précisions.
L'objectif du programme est de recueillir des messages de journal à partir de serveurs sur le réseau et de les stocker dans la base de données. Outre l'ensemble des messages de journal, le collecteur de définir un ensemble de règles qui vont correspondre ou ignorer les messages selon les conditions et le pavillon, un message d'alerte si nécessaire.
Je ne vois pas les règles en cours de plus d'une complexité moyenne, et ils seront appliqués dans une chaîne (list) jusqu'à ce qu'une correspondance d'alerte ou d'ignorer la règle est touché. Cependant, cette partie n'est pas tout à fait comme l'intérêt pour la question.
Autant la syntaxe étant proche de la syntaxe de Python, oui, c'est vrai, mais je pense qu'il serait difficile pour filtre Python, jusqu'au point où l'utilisateur ne pouvait pas, par inadvertance, faire un truc de dingue avec les règles qui n'était pas prévu.
source d'informationauteur Kamil Kisiel | 2009-01-22
Vous devez vous connecter pour publier un commentaire.
Ne pas inventer une autre des règles de la langue.
Utiliser Python ou d'utiliser certains autres, déjà débogué et la langue de travail comme BPEL.
Il suffit d'écrire vos règles en Python, les importer et de les exécuter. La vie est plus simple, beaucoup plus facile à déboguer, et vous avez effectivement résolu le journal réel-le problème de lecture sans créer un autre problème.
Imaginer ce scénario. Votre programme de pauses. C'est maintenant la règle de l'analyse, l'exécution de la règle, ou la règle elle-même. Vous devez déboguer tous les trois. Si vous avez écrit la règle en Python, il serait la règle, et qui serait la.
"Je pense qu'il serait difficile pour filtre Python, jusqu'au point où l'utilisateur ne pouvait pas, par inadvertance, faire un truc de dingue avec les règles qui n'était pas prévu."
C'est en grande partie le "je veux écrire un compilateur" argument.
1) Vous êtes l'utilisateur principal. Vous allez écrire, de débogage et de maintenir les règles. Y a t il vraiment des armées de fou programmeurs qui vont faire des choses folles? Vraiment? Si il y a un risque fou de l'utilisateur, parler. Leur Enseigner. Ne pas se battre contre eux en inventant un nouveau langage (qui vous sera alors de maintenir et de débogage pour toujours.)
2) C'est juste le traitement des journaux. Il n'y a pas de coût réel pour le folie. Personne ne va renverser le système économique mondial à une mauvaise manipulation connexion. Ne font pas un petit groupe de quelques dizaines de lignes de Python sur un 1000 ligne interprète quelques dizaines de lignes de certaines règles de la langue. Il suffit d'écrire les quelques dizaines de lignes de Python.
Il suffit de l'écrire en Python le plus rapidement et clairement que vous le pouvez et de les déplacer sur le prochain projet.
Vous pouvez également regarder PyKE.
Avez-vous envisagé de NebriOS? Nous venons de publier cet outil après la construction pour nos propres fins. C'est un pur Python/Django moteur de règles. Nous avons fait l'utiliser pour des tâches de flux de travail, mais il est suffisamment générique pour aider votre dans votre situation. Vous devez vous connecter à distance DB et exécuter les règles contre elle.
Le Python que vous avez écrit est plus qu'une règle dans le système. En voici un par exemple:
Vérifier à http://nebrios.com. Je ne savais pas combien il y avait de la construction d'un moteur de règles d'application comme Nebri qu'après mon équipe. C'est une tâche ÉNORME qui va beaucoup plus loin qu'il semble. ACL, les files d'attente, les formes, KVPS, contrôles efficaces, utiles erreurs, e-mail de l'analyse, des formes dynamiques, et la liste continue.
C'est un peu dur de répondre à la question sans savoir quel est le champ d'application de la demande est.
Sur une extrémité du spectre est une simple approche de non-comme vous l'avez proposé. C'est très bien si les règles sont peu nombreux, relativement simple, et vous ne faites rien de plus compliqué que de l'agrégation des messages qui correspondent aux règles établies.
De l'autre côté du spectre est un poids lourd de raisonnement du système, quelque chose comme CLIPS qui a un Python interface. C'est un véritable moteur de règles avec l'inférence et offre la possibilité de faire sophistiqué raisonnement. Si vous êtes en train de construire quelque chose comme un diagnostic moteur qui fonctionne à l'arrêt d'un programme de journal de ce qui pourrait être plus approprié.
EDIT:
Je dirais que la mise en œuvre actuelle idée est très bien pour ce que vous faites. Quelque chose de beaucoup plus et je pense que vous avez probablement courir le risque de sur-le génie de la solution. Il semble capturer ce que vous voulez, de la correspondance sur le journal des messages basés sur différents critères.
Le seul endroit qui est différente de la syntaxe de Python est lui-même le
message ~ "program\\[\d+\\]: message"
partie, donc je me demande si vous avez vraiment besoin d'une nouvelle syntaxe.Mise à jour: OK, vous avez de la convivialité ou de problèmes de sécurité -- c'est raisonnable. Quelques suggestions:
Prendre un soupçon de Awk et de rationaliser la mise en correspondance de modèle de la syntaxe, par exemple
/program\[\d+\]: message/
au lieu demessage ~ "program\\[\d+\\]: message"
.J'aimerais la mettre en œuvre par la traduction d'une expression Python que l'entrée est analysé, au lieu de construire un arbre d'objets à évaluer, à moins que vous vous attendez à faire plus d'opérations sur ces choses que l'évaluation. Ce devrait besoin de moins de code et l'exécuter plus rapidement. Le haut niveau pourrait aller quelque chose comme:
Une autre idée, plus loin: écrivez votre application en Lua. Il est conçu pour des non-programmeurs d'étendre les programmes raisonnables de sécurité sans avoir besoin d'apprendre beaucoup de choses. (Il a été utilisé de cette façon, avec succès, et vous pouvez sandbox de l'évaluation de l'utilisateur de code ne pouvez pas obtenir toutes les fonctionnalités que vous ne passez pas explicite, je me suis dit.)
Je vais la fermer maintenant. 🙂 Bonne chance!