From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on sa.local.altlinux.org X-Spam-Level: X-Spam-Status: No, score=-3.4 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,RP_MATCHES_RCVD,UNPARSEABLE_RELAY autolearn=ham autolearn_force=no version=3.4.1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=imath.kiev.ua; s=hydra; t=1537552165; bh=l4I//kBDWeIMV8k61jVnl60k/tyE56H7hioiMCawKSY=; h=Date:From:To:Subject; b=QXT8CNE/R2xhUwrjdwE6PYqNDzLOIKYUR0fiKAdwp5+giQztQ9gCfw5p3DkLwgRJr ZxgvMDbBiEkCvgcQT0P/bgLMEeQHXVmCW5BzLgDvmNZD2YrPtlEO6Ibknliaz7V3NE 2VCBDTEX2ms/YxBBL6EgdqPvBkH00hTlBj4my3e0= Date: Fri, 21 Sep 2018 20:49:25 +0300 From: Igor Vlasenko To: devel@lists.altlinux.org Message-ID: <20180921174924.GA29314@dad.imath.kiev.ua> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit User-Agent: Mutt/1.9.1 (2017-09-22) Subject: [devel] =?utf-8?b?STog0YPRgtC40LvQuNGC0LAgbG9nb3ZlZC1yZXBvcnQg?= =?utf-8?b?0LTQu9GPINC+0LHRgNCw0LHQvtGC0LrQuCDQu9C+0LPQvtCyLiAzLdCf0YA=?= =?utf-8?b?0LDQstC40LvQsCDQm9C+0LPQvtCy0LXQtC4=?= X-BeenThere: devel@lists.altlinux.org X-Mailman-Version: 2.1.12 Precedence: list Reply-To: ALT Linux Team development discussions List-Id: ALT Linux Team development discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 21 Sep 2018 17:49:29 -0000 Archived-At: List-Archive: List-Post: 3. Создание своих правил Логовед. Работая с утилитой logoved-report, вы наверняка столкнетесь с ошибками, которые хотелось бы распознать, но logoved-report о них не знает. Нет проблем - просто создаем свое правило .logoved в ./db/. 3.1 Синтаксис правил Логовед. Для начала посмотрим, как выглядит какое-то простое правило Логовед. $ cat db/sisyphus_check/summary.logoved PATTERN=^sisyphus_check: check-summary ERROR: invalid package summary Мы видим однострочный файл с PATTERN=..., аргумент для PATTERN без кавычек. Легко догадаться, что с таким правилом логовед выполнит некий аналог запуска утилиты pcregrep "$PATTERN" /path/to/logs. Синтаксис текущей версии достаточно прост. #============================================== # допускаются комментарии; # записи имеют вид KEY=VAL # где VAL не берется в кавычки и может содержать пробелы, # где KEY могут повторяться, а допустимые KEY это TYPE= SCOPE= PATTERN= PATTERN_SEQ= MULTILINE_PATTERN_BEGIN= MULTILINE_PATTERN_BODY= MULTILINE_PATTERN_END= DESCRIPTION= STATISTICS= STATISTICS_HEADER= FIX= # после ключевого слова __END__ все остальное игнорируется. __END__ после ключевого слова __END__ может быть фрагмент лог файла для примера. #============================================== Однако с правилом db/sisyphus_check/summary.logoved не все так просто. В каждом правиле Логовед должны присутствовать TYPE= и SCOPE=. Тем не менее, в summary.logoved эти значения явно не указаны. Откуда они берутся? При загрузке базы Логовед используются файлы 00default для установки значений по умолчанию. Для db/sisyphus_check/summary.logoved это файл db/00default, откуда берутся TYPE=error SCOPE=run и файл db/sisyphus_check/00default где SCOPE переопределяется в SCOPE=hasher::sisyphus_check Таким образом, после загрузки, с учетом файлов 00default, внутри программы правило db/sisyphus_check/summary.logoved выглядит как TYPE=error SCOPE=hasher::sisyphus_check PATTERN=^sisyphus_check: check-summary ERROR: invalid package summary но при наличии файлов 00default мы можем писать только PATTERN=^sisyphus_check: check-summary ERROR: invalid package summary остальное придет от файлов 00default как значения по умолчанию. 3.2 Параметры правил Логовед. 3.2.1 Параметр SCOPE. Поговорим сначала о параметре SCOPE. Поиск по всему лог файлу -- плохая идея. Подходящий аналог -- искать макрос в спек-файле и найти его в %changelog. Для лог-файла тоже есть ряд примеров, когда поиск находит совсем не то, что нужно. библиотека Logoved-Stream разбивает на секции hasher::chroot::users hasher::chroot::install hasher::chroot::srpm::repack hasher::chroot::srpm rpmbuild::prep rpmbuild::build rpmbuild::install rpmbuild::install::brp rpmbuild::check rpmbuild::files rpmbuild::files::processing rpmbuild::files::find_requires rpmbuild::files::requires rpmbuild::files::listed_twice rpmbuild::write hasher::time hasher::sisyphus_check beehive::time а в случае ошибок еще возникают секции hasher::chroot::error hasher::chroot::apt hasher::chroot::file_conflict rpmbuild::error Чтобы указать нужную нам область поиска, используется параметр SCOPE. Просто перечислим нужные нам секции с помощью SCOPE. Например, для сообщений в процессе сборки (не для сообщений от от скриптов, входящих в rpmbuild) нам понадобится SCOPE=rpmbuild::prep SCOPE=rpmbuild::build SCOPE=rpmbuild::install SCOPE=rpmbuild::check SCOPE=rpmbuild::error Конечно, такая запись довольно громоздка, даже если ее указывать только в файлах 00default. В Логовед БД в модуле lib/Logoved/DB/Stream/Listener/Factory.pm определены следующие сокращения для наборов секций: apt hasher::chroot::apt hasher::chroot::file_conflict run rpmbuild::prep rpmbuild::build rpmbuild::install rpmbuild::check rpmbuild::error conf rpmbuild::prep rpmbuild::build rpmbuild::error build rpmbuild::prep rpmbuild::build rpmbuild::install rpmbuild::error check rpmbuild::build rpmbuild::install rpmbuild::check rpmbuild::error Также в базе логовед этим сокращениям соответствуют наборы правил (подкаталоги), для которых файл 00default содержит соответствующий SCOPE. db/run - сообщения об ошибке при запуске db/conf - сообщения при конфигурировании, от configure, cmake. db/build - сообщения от компилятора, линковщика, других сборочных утилит db/check - сообщения о неудаче тестирования в db/sisyphus_check/ как мы видели, по умолчанию указан SCOPE=hasher::sisyphus_check Параметры SCOPE= можно себе представить как команды редактирования. Мы удаляем из лог файла все лишнее, оставляя только те секции, которые указаны в SCOPE, и производим поиск в полученном урезанном файле. 3.2.1 Параметры PATTERN* и связанные с ними FIX и STATISTICS. Параметры PATTERN* позволяют указать нам шаблоны поиска. значение - регулярное выражение perl, что значит, что надо экранировать @$%(){}*+, если они используются как простые символы: \@, \$ \%, \(, \), \{, \}, \*, \+ Чтобы упростить регулярные выражения perl, из входящих строк лог файла перед применением регулярных выражений удаляется конец - символ перевода строки "\n". 3.2.1.1 однострочный PATTERN= Самый простой вариант -- однострочный PATTERN= Пример: $ cat db/run/command-not-found/perldoc.logoved PATTERN=perldoc: command not found FIX=buildrequires --add /usr/bin/perldoc В одном правиле можно указать несколько PATTERN, достаточно, чтобы сработал только один из них: $ cat db/apt/E-package-not-found.logoved # E: Couldn't find package libtau-common PATTERN=^E: Couldn't find package (\S+) PATTERN=^E: Невозможно найти пакет (\S+) STATISTICS=%{GROUP:1} STATISTICS_HEADER=E: Невозможно найти пакет: 3.2.1.2 многострочный PATTERN_SEQ= Более сложный - многострочный шаблон PATTERN_SEQ= фиксированной длинны. последовательность PATTERN_SEQ= PATTERN_SEQ= PATTERN_SEQ= совпадает, если 1я строка совпадет с 1м паттерном, 2-я со вторым и т.д. Пример1: $ cat db/conf/automake-version/1.logoved PATTERN_SEQ=you need automake version \S+ or later PATTERN_SEQ=^error: Bad exit status from /\S+ \(\% __END__ ./bootstrap: you need automake version 1.5 or later error: Bad exit status from /usr/src/tmp/rpm-tmp.3287 (%build) Пример2: $ cat db/conf/automake-version/2.logoved PATTERN_SEQ=You must have automake \S+ installed to compile PATTERN_SEQ=Install the appropriate package for your distribution, PATTERN_SEQ=or get the source tarball PATTERN_SEQ=^error: Bad exit status from /\S+ \(\% __END__ You must have automake 1.7.x installed to compile . Install the appropriate package for your distribution, or get the source tarball at http://ftp.gnu.org/gnu/automake/ error: Bad exit status from /usr/src/tmp/rpm-tmp.64887 (%prep) В отличие от PATTERN, в правиле логовед из-за ограничений синтаксиса может быть только одна последовательность PATTERN_SEQ=. Но есть синтаксический сахар. Во flat режиме подпути, состоящие из одних цифр, отбрасываются. Поэтому лог файлы, подпадающие под правила conf/automake-version/1.logoved conf/automake-version/2.logoved в отчете попадут в одну и ту же папку LOGS/conf-automake-version . 3.2.1.3 шаблон MULTILINE_PATTERN_* переменной длинны. многострочный шаблон MULTILINE_PATTERN_BEGIN= MULTILINE_PATTERN_BODY= [...] MULTILINE_PATTERN_BODY= MULTILINE_PATTERN_END= применяется, когда образец может иметь переменное число строк. Начало сопоставления задается шаблоном MULTILINE_PATTERN_BEGIN, затем может идти что угодно, лишь бы оно подпадало хотя бы под один из шаблонов вида MULTILINE_PATTERN_BODY=, окончание сопоставления задается шаблоном MULTILINE_PATTERN_END. Пример 1: # python2/import-error.logoved MULTILINE_PATTERN_BEGIN=^Traceback \(most recent call last\): MULTILINE_PATTERN_BODY=^\s\s MULTILINE_PATTERN_END=^ImportError: No module named (\S+) FIX=buildrequires --add python2.7(%{MULTILINE_END_GROUP:1}) __END__ Traceback (most recent call last): File "/usr/lib/python2.7/site-packages/nose/suite.py", line 207, in run self.setUp() File "/usr/lib/python2.7/site-packages/nose/suite.py", line 290, in setUp self.setupContext(ancestor) File "/usr/lib/python2.7/site-packages/nose/suite.py", line 313, in setupContext try_run(context, names) File "/usr/lib/python2.7/site-packages/nose/util.py", line 471, in try_run return func() File "/usr/src/RPM/BUILD/python-module-fs-2.0.17/tests/test_ftpfs.py", line 90, in setUpClass from pyftpdlib.test import ThreadedTestFTPd File "/usr/lib/python2.7/site-packages/pyftpdlib/test/__init__.py", line 40, in import sendfile ImportError: No module named sendfile Пример 2: # python3/import-error-module.logoved MULTILINE_PATTERN_BEGIN=^Traceback \(most recent call last\): MULTILINE_PATTERN_BODY=^\s\s MULTILINE_PATTERN_END=^ModuleNotFoundError: No module named '(\S+)' FIX=buildrequires --add python3(%{MULTILINE_END_GROUP:1}) __END__ cd /usr/src/RPM/BUILD/ibus-table-chinese-1.8.2-Source/tables/array && /usr/bin/ibus-table-createdb -n array30-big.db -s /usr/src/RPM/BUILD/ibus-table-chinese-1.8.2-Source/tables/array/array30-big.tab Traceback (most recent call last): File "/usr/share/ibus-table/engine/tabcreatedb.py", line 29, in import tabsqlitedb File "/usr/share/ibus-table/engine/tabsqlitedb.py", line 32, in import sqlite3 ModuleNotFoundError: No module named 'sqlite3' make[2]: *** [tables/array/CMakeFiles/convert_array.dir/build.make:69: tables/array/array30-big.db] Error 1 make[2]: Leaving directory '/usr/src/RPM/BUILD/ibus-table-chinese-1.8.2-Source' make[1]: *** [CMakeFiles/Makefile2:897: tables/array/CMakeFiles/convert_array.dir/all] Error 2 make: *** [Makefile:154: all] Error 2 error: Bad exit status from /usr/src/tmp/rpm-tmp.11890 (%build) 3.2.2 Параметры FIX и STATISTICS. Раз у нас есть регулярное выражение, то мы можем выделить в образце нужный нам фрагмент текста как ГРУППУ, просто взяв его в регулярном выражении в простые круглые скобки. Вернемся к правилу apt/E-package-not-found.logoved там есть PATTERN=^E: Couldn't find package (\S+) PATTERN=^E: Невозможно найти пакет (\S+) в которых выделена одна группа (группа №1, к ней можно обращаться как %{GROUP:1}). к примеру, для образца E: Couldn't find package libtau-common значением группы №1 станет libtau-common. Что мы можем сделать со значением группы? можем сосчитать частоту (статистка по умолчанию) добавим в правило параметр STATISTICS=%{GROUP:1} и для красоты заголовок - строку перед статистикой STATISTICS_HEADER=E: Невозможно найти пакет: получим в LOGS/apt-E-package-not-found файл статистики, и сразу станет ясно, что чинить в первую очередь. $ cat apt-E-package-not-found/00statistics E: Невозможно найти пакет: 5: gnustep-Etoile-DocGenerator 5: gdk-pixbuf-devel 4: python-module-setuptools-tests [...] 1: kdepim-devel Пример2: db/conf/pkgconfig.logoved содержит набор PATTERN=^Package (\S+) was not found in the pkg-config search path PATTERN=^configure: error: Package requirements \((\S+)\) were not met: PATTERN=^No package '(\S+)' found ругани на отсутствующий .pc файл. В каждом из шаблонов выделена группа №1. Простую статистику по частоте для нее считать не имеет смысла. Имело бы смысл разделить .pc файлы на отсутствующие в Сизифе и присутствующие в Сизифе, затем уже отдельно в каждой группе статистику по частоте. Но это пока не реализовано. Зато легко указать правило, как улучшить (а то и починить) пакет. Имя .pc файла -- готовый компонент для добавления в BuildRequires пакета. Соответствующая опция FIX имеет вид FIX=buildrequires --add pkgconfig(%{GROUP:1}) В случае набора PATTERN_SEQ все группы в наборе получают сплошную нумерацию. Набор PATTERN_SEQ=bla (\S+) was (\S+) PATTERN_SEQ=error: PATTERN_SEQ=foo '(\S+)' содержит группы %{GROUP:1} %{GROUP:2} %{GROUP:3} В случае MULTILINE_PATTERN_*, %{GROUP:xx} нет, а есть отдельно %{MULTILINE_BEGIN_GROUP:хх} %{MULTILINE_END_GROUP:хх} в python3/import-error-module.logoved, к примеру, будет для MULTILINE_PATTERN_BEGIN=^Traceback \(most recent call last\): MULTILINE_PATTERN_BODY=^\s\s MULTILINE_PATTERN_END=^ModuleNotFoundError: No module named '(\S+)' FIX=buildrequires --add python3(%{MULTILINE_END_GROUP:1}) 3.2.3 Параметр DESCRIPTION. DESCRIPTION=В каких-то случаях сообщения об ошибках DESCRIPTION=могут быть недостаточно информативными. DESCRIPTION=В таких случаях хорошо бы составить описание DESCRIPTION=ошибки для пользователя. DESCRIPTION= DESCRIPTION=Для этого просто добавим DESCRIPTION= DESCRIPTION=перед каждой строкой. DESCRIPTION= DESCRIPTION=Исходное сообщение будет сохранено в файл DESCRIPTION=00description в каталоге отчета. 3.2.4 Ключевое слово __END__ После ключевого слова __END__ обработка файла .logoved прекращается, и все остальное его содержимое игнорируется. Поэтому после __END__ удобно хранить образцы сообщений, для поиска которых создавался логовед, чтобы можно было проверить, не сломали ли мы часом регулярное выражение. 4. За пределами правил Логовед. В некоторых случаях возможностей правил Логовед может не хватить. В таком случае можно спуститься на уровень ниже, в библиотеку Logoved-Stream. Там можно зарегистрировать обработчик (Listener) для указанного SCOPE= с нужным кодом, что занимается программным анализом поступающего потока. в интерфейсе 4 метода: write (<линия лог файла>) commit () - вызывается после окончания данных success() - когда секция завершилась успешно. error() - когда секция завершилась неуспешно. Успешной работы! -- I V