Подтвердить что ты не робот

Реализация "механизма правил" в Python

Я пишу приложение для сбора/анализа журналов на Python, и мне нужно написать "механизм правил" для соответствия и действий в сообщениях журнала.

Для этого необходимо:

  • Согласование регулярных выражений для самого сообщения
  • Арифметические сравнения для серьезности сообщения/приоритета
  • Булевы операторы

Я предполагаю, что примерное правило может быть примерно таким:

(message ~ "program\\[\d+\\]: message" and severity >= high) or (severity >= critical)

Я думаю об использовании PyParsing или аналогично анализу правил и построению дерева разбора.

Текущий (еще не реализованный) проект, который я имею в виду, состоит в том, чтобы иметь классы для каждого типа правила, а также строить и связывать их вместе в соответствии с деревом разбора. Тогда каждое правило будет иметь метод "match", который мог бы вернуть объект сообщения независимо от того, соответствует ли оно правилу.

Очень быстро, что-то вроде:

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)

Затем эти классы правил соединяются вместе в соответствии с деревом синтаксиса сообщения, а метод match() вызывается в верхнем правиле, которое будет каскадироваться до тех пор, пока не будут оценены все правила.

Мне просто интересно, разумно ли это, или мой дизайн и идеи полностью из-за ударов? К сожалению, у меня никогда не было возможности взять курс дизайна компилятора или что-то в этом роде в Unviersity, поэтому я довольно часто придумываю этот материал по своему усмотрению.

Может ли кто-нибудь с некоторым опытом в таких вещах прокомментировать и оценить идею?

EDIT: Некоторые хорошие ответы до сих пор здесь немного разъясняются.

Цель программы - собирать сообщения журнала с серверов в сети и сохранять их в базе данных. Помимо сбора сообщений журнала, коллекционер определит набор правил, которые будут либо совпадать, либо проигнорировать сообщения в зависимости от условий, и при необходимости отметьте оповещение.

Я не вижу, чтобы правила были более чем умеренной сложности, и они будут применяться в цепочке (списке) до тех пор, пока не будет применено соответствующее предупреждение или правило игнорирования. Однако эта часть не совсем уместна для вопроса.

Пока синтаксис близок к синтаксису Python, да, это правда, однако я думаю, что было бы сложно отфильтровать Python до такой степени, что пользователь не мог бы непреднамеренно сделать некоторые сумасшедшие вещи с правилами, которые не были предназначен.

4b9b3361

Ответ 1

Не изобретайте еще один язык правил.

Используйте Python или используйте какой-либо другой существующий, уже отлаженный и рабочий язык, например BPEL.

Просто напишите свои правила в Python, импортируйте их и выполните их. Жизнь проще, гораздо легче отлаживать, и вы фактически решили проблему чтения журнала, не создавая еще одну проблему.

Представьте себе этот сценарий. Ваша программа ломается. Теперь это либо разбор правил, выполнение правила, либо само правило. Вы должны отлаживать все три. Если вы написали правило в Python, это будет правило, и это будет так.

"Я думаю, что было бы сложно отфильтровать Python до такой степени, что пользователь не мог бы непреднамеренно сделать некоторые сумасшедшие вещи с правилами, которые не были предназначены".

В основном это аргумент "Я хочу написать компилятор".

1) Вы являетесь основным пользователем. Вы будете писать, отлаживать и поддерживать правила. Есть ли действительно армии сумасшедших программистов, которые будут делать сумасшедшие вещи? В самом деле? Если есть потенциальный сумасшедший пользователь, поговорите с ними. Научить их. Не сражайтесь с ними, изобретая новый язык (который вам тогда придется поддерживать и отлаживать навсегда.)

2) Это просто обработка журнала. Там никакой реальной стоимости для сумасшествия. Никто не сможет подорвать мировую экономическую систему с неправильной обработкой журналов. Не делайте маленькую задачу с несколькими десятками строк Python на интерпретатор 1000 строк, чтобы интерпретировать несколько десятков строк некоторого языка правил. Просто напишите несколько десятков строк Python.

Просто напишите на Python так быстро и четко, как можете, и перейдите к следующему проекту.

Ответ 2

Вы также можете посмотреть PyKE.

Ответ 3

Вы считали Небриоса? Мы только что выпустили этот инструмент после его создания в наших собственных целях. Это чистый механизм правил Python/Django. Мы фактически используем его для задач рабочего процесса, но он достаточно общий, чтобы помочь вам в вашей ситуации. Вам нужно будет подключиться к удаленной БД и запустить против нее правила.

Питон, который вы написали, в конечном итоге станет более чем одним правилом в системе. Здесь один пример:

class SeverityRule(NebriOS):
    # add listener or timer here

check(self):
    if operator == ">="
    return message.severity >= severity
    # any number of checks here


action(self):
    csv.append(message.severity, datetime.now)
    send_email([email protected], """Severity level alert: {{message.severity}}""")

Проверьте это на http://nebrios.com. Я не понимал, сколько нужно для создания приложения с двигателем правил, такого как Nebri, до тех пор, пока не начнется моя команда. Это была ОГРОМНАЯ задача, которая намного глубже, чем кажется. ACL, очереди, формы, KVPS, эффективные проверки, полезные ошибки, парсинг электронной почты, динамические формы и список.

Ответ 4

Единственное место, которое отличается от синтаксиса Python, это часть message ~ "program\\[\d+\\]: message", поэтому я задаюсь вопросом, действительно ли вам нужен новый синтаксис.

Обновление: Хорошо, у вас есть удобство использования или проблемы безопасности - это разумно. Несколько советов:

  • Возьмите подсказку из Awk и оптимизируйте синтаксис соответствия шаблону, например. /program\[\d+\]: message/ вместо message ~ "program\\[\d+\\]: message".

  • Я бы выполнил его, переведя в выражение Python, когда вход анализируется, вместо того, чтобы строить дерево объектов для оценки, если только вы не планируете делать больше операций над этими вещами, кроме оценки. Это должно быть меньше кода и работать быстрее. Верхний уровень может выглядеть примерно так:

    def compile(input):
        return eval('lambda message, severity: %s' % parse(input))
    

Еще одна идея, еще одна: напишите свое приложение в Lua. Он предназначен для непрограммистов для расширения программ достаточно безопасно, без необходимости многому учиться. (Он был использован таким образом успешно, и вы можете оценить песочницу, чтобы код пользователя не мог получить какие-либо возможности, которые вы не передаете ему явно, мне сказали.)

Я закрою сейчас.:-) Удачи!

Ответ 5

Немного сложно ответить на вопрос, не зная, в чем область приложения.

  • О чем вы пытаетесь рассуждать?
  • О каком уровне анализа вы говорите?
  • Насколько сложно вы видите, что правила становятся?
  • Насколько сложным является взаимодействие между различными правилами?

На одном конце спектра есть простой одноразовый подход, как вы предлагали. Это нормально, если правил немного, относительно просто, и вы не делаете ничего более сложного, чем объединение сообщений журнала, соответствующих указанным правилам.

С другой стороны спектра используется система весовых рассуждений, например CLIPS, которая имеет Интерфейс Python. Это настоящий механизм правил с выводами и дает возможность делать сложные рассуждения. Если вы создаете нечто вроде механизма диагностики, который работает с журналом программы, это может быть более подходящим.

EDIT:

Я бы сказал, что текущая идея реализации прекрасна для того, что вы делаете. Что-то гораздо больше, и я думаю, что вы, вероятно, рискуете чрезмерно разработать решение. Кажется, он захватывает то, что вы хотите, сопоставляя сообщения журнала только по нескольким различным критериям.

Ответ 6

Я пишу простой механизм правил на Python. Вы можете хранить свои правила в строке json или yaml и использовать этот механизм правил, чтобы сопоставить правило с контекстом.

https://github.com/tclh123/rule