Ad Widget

Collapse

Регулярное выражение - Модификатор "s" не срабатывает

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • vebmasterHtml
    Junior Member
    • Apr 2019
    • 15

    #1

    Регулярное выражение - Модификатор "s" не срабатывает

    Здравствуйте.

    Не могу понять или заставить работать модификатор s (чтобы текст воспринимался как 1 строка и чтобы точка соответствовала переводу строки). В php модификаторы ставил после разделителя например /регулярка/si
    а тут не пойму куда и как, (?si) перед регуляркой не срабатывает. Подскажите пожалуйста как правильно

    Пример текста
    Code:
    2019-04-16 14:46:12 Текст после даты key1: 105
    вторая строка с текстом
    и последняя третья строка 20 key2
    Задача вытащить цифру перед key2, при условии что key1 присутствует тоже.

    Следующие 2 регулярки не срабатывают, не вытаскивают число
    Code:
    (?si)\d{4}-\d{2}-\d{2} .+? key1.+? (\d+) key2
    Code:
    \d{4}-\d{2}-\d{2} .+? key1(?s).+? (\d+) key2
    Тип выражения: Результат ИСТИНА


    Если вытаскивать цифру после key1, то срабатывает, но оно и понятно, это 1 строка:
    Code:
    (?si)\d{4}-\d{2}-\d{2} .+? key1: (\d+)
    Last edited by vebmasterHtml; 17-04-2019, 14:18.
  • Kos
    Senior Member
    Zabbix Certified SpecialistZabbix Certified Professional
    • Aug 2015
    • 3404

    #2
    Да, вроде, он-лайн отладчик регулярных выражений показывает, что выражение
    Code:
    (?si)\d{4}-\d{2}-\d{2} .+? key1.+? (\d+) key2
    вполне выполняет свою задачу.
    Опишите подробнее, пожалуйста, где именно у вас используется это регулярное выражение, а также какой версией Zabbix пользуетесь.

    Comment

    • vebmasterHtml
      Junior Member
      • Apr 2019
      • 15

      #3
      Originally posted by Kos
      Опишите подробнее, пожалуйста, где именно у вас используется это регулярное выражение, а также какой версией Zabbix пользуетесь.
      Zabbix 4.2.0
      Регулярное выражение создаю в Общие - Регулярные выражения
      Использую в элементе данных:
      Если регулярное выражение называется "Test1", то Элемент данных:
      Тип: Zabbix агент (Активный)
      Ключ: logrt[/tmp/logerror4.txt,@Test1,,,,\1]
      Тип информации: Числовой (целое положительное)

      Пример /tmp/logerror4.txt:
      Code:
      2019-04-16 14:47:12 Текст после даты key1: 101
      вторая строка с текстом
      и последняя третья строка 21 key2
      
      2019-04-16 14:48:12 Текст после даты key1: 102
      вторая строка с текстом
      и последняя третья строка 22 key2
      
      2019-04-16 14:49:12 Текст после даты key1: 103
      вторая строка с текстом
      и последняя третья строка 23 key2
      В результате в последних данных пусто.

      Comment

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

        #4
        Т.е. в данном случае регулярное выражение, несмотря на то, что определяется на сервере (и даже как глобальное), реально обрабатывается на агенте (поскольку метрика logrt[...] собирается агентом).
        Тут важна версия агента - до версии 3.4 использовались другие библиотеки регулярных выражений, не PCRE.

        Comment

        • vebmasterHtml
          Junior Member
          • Apr 2019
          • 15

          #5
          Originally posted by Kos
          Тут важна версия агента
          Агент 4.0.2

          Comment

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

            #6
            Не знаю, дальше могу только гадать. Я бы поставил на агенте DebugLevel побольше (4 или 5) и смотрел бы по логам, что там происходит (обычно он довольно подробно протоколирует свои действия). Или обратился бы в техподдержку, если есть саппорт-контракт.

            Comment

            • vebmasterHtml
              Junior Member
              • Apr 2019
              • 15

              #7
              Спасибо большое, поставил дебаг 5, Нашёл вот такие строки

              29452:20190416:165810.520 In need_meta_update() key:logrt[/tmp/logerror4.txt,@LogErrorOmitted6,,,,\1]
              29452:20190416:165810.520 End of need_meta_update():SUCCEED
              29452:20190416:165810.520 In process_value() key:'server1:logrt[/tmp/logerror4.txt,@LogErrorOmitted6,,,,\1]' value:'(null)'


              29452:20190416:165820.534 In need_meta_update() key:logrt[/tmp/logerror4.txt,@LogErrorOmitted6,,,,\1]
              29452:20190416:165820.534 End of need_meta_update():FAIL

              Comment

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

                #8
                Надо смотреть исходники. Мне кажется, что эта часть, как раз, не страшная - вполне может быть, что это проверка, не менялось ли что-нибудь в ключе logrt[...] или в глобальном регулярном выражении @LogErrorOmitted6 (которое определяется на сервере и должно пересылаться на агент вместе со списком активных проверок).
                Интереснее посмотреть, что происходит при обработке изменений файла (при дописывании в него ещё одной записи из трёх строк).

                Блин. Агент же по определению считает каждую новую строку отдельной записью :-(
                Он не умеет работать иначе, я ж об этом даже добавлял когда-то свой комментарий с предложениями в их ZBXNEXT.

                Comment

                • vebmasterHtml
                  Junior Member
                  • Apr 2019
                  • 15

                  #9
                  Originally posted by Kos
                  Агент же по определению считает каждую новую строку отдельной записью :-(
                  Он не умеет работать иначе
                  Огромное спасибо.

                  А можете подсказать, возможно ли как то иначе в заббиксе вытащить это число перед key2? Видел в Элементе данных есть ещё предобработка, с ними возможно что то схитрить?

                  Comment

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

                    #10
                    Originally posted by vebmasterHtml
                    Огромное спасибо.

                    А можете подсказать, возможно ли как то иначе в заббиксе вытащить это число перед key2? Видел в Элементе данных есть ещё предобработка, с ними возможно что то схитрить?
                    Ну, если надо искать только число перед "key2" - то это, как раз, несложно: игорируем все остальные записи, да и всё.
                    Но, насколько я помню, изначально задача ставилась немного иначе:
                    Задача вытащить цифру 20 перед key2, при условии что key1 присутствует тоже.
                    Тогда уже надо немного извращаться: нужно, чтобы агент пересылал на сервер и строки, содержащие "key1", и строки, содержащие "key2", а в триггере пытаться сформулировать условие "присутствует число 20 перед key2, но перед этим была строка, содержавшая key1".
                    Или вам надо не для триггера, а просто извлекать само число (например, чтобы затем рисовать по нему график)?

                    Comment

                    • vebmasterHtml
                      Junior Member
                      • Apr 2019
                      • 15

                      #11
                      Да, условие чтобы key1 тоже был.

                      Originally posted by Kos
                      Или вам надо не для триггера, а просто извлекать само число (например, чтобы затем рисовать по нему график)?
                      Тригер и/или график, любой вариант. Уведомление (с числом перед key2) планируется при каждом нахождении числа перед key2. Но может быть, что строка с key1 будет, а c key2 нет.

                      нужно, чтобы агент пересылал на сервер и строки, содержащие "key1", и строки, содержащие "key2", а в триггере пытаться сформулировать условие
                      Не совсем представляю как это будет реализовано. Как по мне это только log/logrt, правильно? или есть ещё чтото

                      Comment

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

                        #12
                        Изначально я предполагал, что интересует сам факт получения строки "20 key2" при условии, что перед ней есть строка с "key1". В таком случае, если конкретные числовые значения (например, для рисования графиков) не нужны, то можно сделать элемент данных вида:
                        Code:
                        logrt[/tmp/logerror4.txt,"key1|key2"]
                        Он будет пересылать на сервер Zabbix только строки, содержащие "key1" или "key2". Тогда триггер можно сделать с условием вида
                        Code:
                        {host:logrt[/tmp/logerror4.txt,"key1|key2"].str("20 key2")}=1 and {host:logrt[/tmp/logerror4.txt,"key1|key2"].str("key1",2)}=1
                        Но для рисования графиков такой вариант не подойдёт, т.к. пересылаться будут строки, а не числа (и тип элемента данных должен быть "Log").

                        Уведомление (с числом перед key2) планируется при каждом нахождении числа перед key2. Но может быть, что строка с key1 будет, а c key2 нет.
                        Если может быть так, что "строка с key1 будет, а c key2 нет", но не может быть наоборот (т.е. перед каждой строкой с key2 всегда будет строка с key1), то наличие строки с key1 проверять не надо и она нас вообще не интересует. Тогда задача сильно упрощается, т.к. надо смотреть только внутрь одной строки: если есть key2, то по регулярному выражению доставать число перед ней. И тут ничего изобретать не надо, всё решается штатными средствами.

                        Comment

                        • vebmasterHtml
                          Junior Member
                          • Apr 2019
                          • 15

                          #13
                          Может быть и наоборот, key1 будет, а key2 нет, поэтому идёт зависимость на чтение всех строк записываемого лога, чтобы убедиться, что мы именно поймали ту запись, что искали.
                          Поидее это решалось бы модификатором s (читать как 1 строку), но заббикс работает чуть иначе

                          Code:
                          {host:logrt[/tmp/logerror4.txt,"key1|key2"].str("20 key2")}=1 and {host:logrt[/tmp/logerror4.txt,"key1|key2"].str("key1",2)}=1
                          Но это опять же построчное чтение, и одна строка ничего не знает про другую, если я правильно понял.

                          Допустим за 10 секунд (между проверками) в лог поступило несколько записей,

                          Code:
                          2019-04-16 14:47:12 Текст после даты [COLOR=#FF0000]key333[/COLOR]: 101
                          вторая строка с текстом
                          и последняя третья строка 21 [COLOR=#008000][B]key2[/B][/COLOR]  
                          
                          2019-04-16 14:48:12 Текст после даты [COLOR=#008000][B]key1[/B][/COLOR]: 102
                          вторая строка с текстом
                          и последняя третья строка 22 [COLOR=#FF0000]key444[/COLOR]  
                          
                          2019-04-16 14:49:12 Текст после даты [B][COLOR=#008000]key1[/COLOR][/B]: 103
                          вторая строка с текстом
                          и последняя третья строка 23 [B][COLOR=#008000]key2[/COLOR][/B]
                          В данном случае мы должны поймать только третью последнюю запись, но по такому ключу и тригеру будет две записи, что будет не верно
                          Last edited by vebmasterHtml; 17-04-2019, 13:33.

                          Comment

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

                            #14
                            Но это опять же построчное чтение, и одна строка ничего не знает про другую, если я правильно понял.
                            Да, чтение - построчное. И агент будет пересылать на сервер только часть строк, каждую - как отдельное значение. В данном примере на сервер попадут строки:
                            Code:
                            и последняя третья строка 21 [COLOR=#008000][B]key2[/B][/COLOR]
                            2019-04-16 14:48:12 Текст после даты [COLOR=#008000][B]key1[/B][/COLOR]: 102
                            2019-04-16 14:49:12 Текст после даты [B][COLOR=#008000]key1[/COLOR][/B]: 103
                            и последняя третья строка 23 [B][COLOR=#008000]key2[/COLOR][/B]
                            (в остальных строках нет подстрок "key1" и "key2").
                            Предлагаемое условие триггера гласит: в последней строке есть подстрока "20 key2", при этом в ней либо в предпоследней строке есть подстрока "key1".
                            Как видим, в данном случае этот триггер вообще не сработает, т.к. перед "key2" числа "20" нет ни в одной из строк. Но если бы перед "key2" в первой и последней строках стояло бы число "20", то триггер бы сработал только один раз: при получении последней строки.

                            Comment

                            • vebmasterHtml
                              Junior Member
                              • Apr 2019
                              • 15

                              #15
                              Originally posted by Kos
                              т.к. перед "key2" числа "20" нет ни в одной из строк.
                              я может где то не так описал, вместо 20 будет любое число, поэтому я его и вытаскиваю, т.к. оно неизвестно.



                              Comment

                              Working...