Ad Widget

Collapse

Препроцессинг & regex

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Anth(0)ny
    Member
    • Jul 2015
    • 42

    #1

    Препроцессинг & regex

    Коллеги, добрый день.

    Короткий вопрос: если в Элементе используется препроцессинг, в препроцессинг поступает многострочный текст (к примеру, плохо форматированный xml), в котором несколько раз встречается строка с ключевым для меня словом, можно ли забрать ВСЕ строки с ключевым словом в данные Элемента?

    Пример текста:

    Code:
    set cli-parameters base 10 api brief enabled pager disabled
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <RESPONSE VERSION="L100">
    <COMP G="0" P="1"/><OBJECT basetype="status" name="status" oid="1">
      <PROPERTY name="response-type" type="string">Success</PROPERTY>
      <PROPERTY name="response-type-numeric" type="string">0</PROPERTY>
      <PROPERTY name="response" type="string">Command completed successfully. - The settings were changed successfully.</PROPERTY>
      <PROPERTY name="return-code" type="sint32">0</PROPERTY>
      <PROPERTY name="component-id" type="string"></PROPERTY>
      <PROPERTY name="time-stamp" type="string">2018-03-26 16:12:23</PROPERTY>
      <PROPERTY name="time-stamp-numeric" type="string">1522080743</PROPERTY>
    </OBJECT>
    </RESPONSE>
    # show hosts
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <RESPONSE VERSION="L100">
    <COMP G="0" P="1"/>  <OBJECT basetype="hosts" name="hosts" oid="1" format="rows">
      <PROPERTY name="host-id" key="true" type="string">50014380242348fc</PROPERTY>
      <PROPERTY name="host-name" type="string">MSKBS5</PROPERTY>
      <PROPERTY name="host-discovered" type="string">Yes</PROPERTY>
      <PROPERTY name="host-mapped" type="string">Yes</PROPERTY>
      <PROPERTY name="host-profile" type="string">Standard</PROPERTY>
      <PROPERTY name="host-bus-type" type="string">FC</PROPERTY>
      <PROPERTY name="host-port-bits-a" type="uint32">2</PROPERTY>
      <PROPERTY name="host-port-bits-b" type="uint32">0</PROPERTY>
    </OBJECT>
    <COMP G="0" P="2"/>  <OBJECT basetype="hosts" name="hosts" oid="2" format="rows">
      <PROPERTY name="host-id" key="true" type="string">5001438024234534</PROPERTY>
      <PROPERTY name="host-name" type="string">MSKBS3</PROPERTY>
      <PROPERTY name="host-discovered" type="string">No</PROPERTY>
      <PROPERTY name="host-mapped" type="string">No</PROPERTY>
      <PROPERTY name="host-profile" type="string">Standard</PROPERTY>
      <PROPERTY name="host-bus-type" type="string">Undefined</PROPERTY>
      <PROPERTY name="host-port-bits-a" type="uint32">0</PROPERTY>
      <PROPERTY name="host-port-bits-b" type="uint32">0</PROPERTY>
    </OBJECT>
    <COMP G="0" P="3"/><OBJECT basetype="status" name="status" oid="3">
      <PROPERTY name="response-type" type="string">Success</PROPERTY>
      <PROPERTY name="response-type-numeric" type="string">0</PROPERTY>
      <PROPERTY name="response" type="string">Command completed successfully.</PROPERTY>
      <PROPERTY name="return-code" type="sint32">0</PROPERTY>
      <PROPERTY name="component-id" type="string"></PROPERTY>
      <PROPERTY name="time-stamp" type="string">2018-03-26 16:12:23</PROPERTY>
      <PROPERTY name="time-stamp-numeric" type="string">1522080743</PROPERTY>
    </OBJECT>
    </RESPONSE>
    Одну строку, первое вхождение, забрать не проблема:
    Code:
    (.*host-id.*(?s))
    А нужно извлечь в данные Элемента все (может быть до 10) строки с host-id, чтобы получилось так:

    Code:
    <PROPERTY name="host-id" key="true" type="string">50014380242348fc</PROPERTY>
    <PROPERTY name="host-id" key="true" type="string">5001438024234534</PROPERTY>
    Не подскажете, это вообще возможно?
    Прошу помочь.
  • Kos
    Senior Member
    Zabbix Certified SpecialistZabbix Certified Professional
    • Aug 2015
    • 3404

    #2
    Я был уверен, что препроцессинг через XML XPath именно так и делает. Но точно не знаю - у нас пока версия 3.0, которая LTS, но без этих возможностей.

    Comment

    • Anth(0)ny
      Member
      • Jul 2015
      • 42

      #3
      Я про регулярки.

      Проблема в том, что я пока не получил официальный комментарий на эту тему. Но есть устойчивое ощущение, что Zabbix не умеет оперировать несколькими результатами запроса, т.е. не умеет суммировать результат. Нельзя делать поиск по полученному raw-тексту и в результате получать все вхождения. Обрабатывается только одно, первое встреченное. Это касается всех regex'ов. Да, можно получить что называется "от сих - до сих", но только в случае, если текст, подпадающий под регулярку, идёт подряд. Я таким образом спокойно извлекаю блоки для постобработки именно при помощи xPath. Я не понимаю, почему Zabbix не использует флаг Global. Или не понимаю, как его задействовать, если он поддерживается.

      Как пример можно привести вышеуказанный текст. Это уже предобработанный текст, из него 1 регуляркой удалена одна первая лишняя строка (эхо введённой команды), идущая мимо xml'я. Иначе натравить на него xPath невозможно, поскольку с точки зрения libxml текст, в котором встречается хоть одна лишняя строка, автоматом считается malformed. Поэтому я сначала или отрезаю всё ненужное ДО xml-кода, или забираю на последующий разбор только нужные форматированные куски.

      Сейчас я хочу при помощи регулярки извлечь все строки, в которых есть host-name и вывести результат как список. Но - не получается. Обработка встаёт сразу поле обнаружения 1 вхождения. Потому, что не Global.

      Вот я и пытаюсь понять, нужное мне вообще возможно реализовать?

      Я не пытался обрабатывать текст сразу при помощи xPath, сейчас попробую. Но чтото мне подсказывает, что результат будет тем же, что и при регулярках.
      Last edited by Anth(0)ny; 27-03-2018, 11:02.

      Comment

      • Anth(0)ny
        Member
        • Jul 2015
        • 42

        #4
        Всё, вопрос закрыт.


        • Anth(0)ny 26-03-2018, 17:41

          Раздел документации: https://www.zabbix.com/documentation..._preprocessing

          Собственно вопрос: возможно ли при использовании "Regular expression" забрать в данные Элемента не только 1 вхождение искомого текста (всю его строку), но и все его вхождения (все содержащие его строки)? Или модуль препроцессинга ограничен только 1 результатом? Можно ли каким-то образом в регулярном выражении использовать переключатель Global?

          Спасибо.


        • glebs.ivanovskis Today, 13:51

          Извиняюсь за задержку.

          Нет, сейчас такой возможности не предусмотрено. Отчасти это ограничение формата output строки, где возможны только \0 и \1, ..., \9. Подозреваю, что истоки этого ограничения в том, что ранее использовались POSIX Extended Regular Expressions, в которых нет такого понятия как Global match.

          Из необходимости сохранить обратную совместимость с POSIX ERE вытекает и то, что пользователь не может передавать свои модификаторы на манер /.../m, только inline, вроде (?m). Global нельзя указать inline. Кстати, об этом недавно была добавлена документация: https://www.zabbix.com/documentation...regex_modifier

          Ну и наконец сам конвейер препроцессинга не предусматривает подобных разветвлений. Можно разве что создавать несколько зависимых элементов данных и вытаскивать первые, второе, третее вхождение и т.д. Будет не очень эффективно, но всё же...


        Comment

        • Kos
          Senior Member
          Zabbix Certified SpecialistZabbix Certified Professional
          • Aug 2015
          • 3404

          #5
          Спасибо, с регулярными выражениями понятно.
          Тем не менее, для меня остался открытым вопрос об использовании XPath. Всё же, выражение XPath, в общем случае, возвращает nodeset - т.е. некий набор элементов.
          Как это обрабатывается препроцессором Zabbix-а - возвращается весь набор или же только какое-то одно значение (первое/последнее) из этого набора? Или же происходит ошибка?
          Может, Глеб (@glebs.ivanovskis) сможет пояснить?

          Comment

          Working...