Помогите с оптимизацией анализатора логов
Добрый день, товарищи!
Решил таки запилить анализатор логов к нашей системе, делал в лоб. Анализатор состоит из двух частей: фронтэнд на JS, бэкэнд на PHP. Бэкэнд простой - десяток строк, читает заданное количество строк с конца файла лога и выдает во фронтэнд построчно в формате JSON. Там его подбирает скрипт, разбивает строки на интересующие части для последующей подсветки синтаксиса и фильтрации. Поясню на картинке: ![]() т.е. строку разбиваем регулярными выражениями на SPANы, каждому - свой стиль. По производительности особых проблем в этом нету, 200 килобайтный блок обрабатывается пару секунд. Но и это не нужно т.к. лог будет загружаться небольшими порциями в 10..100 строк в процессе работы системы. Проблема в другом. В верхней части видны кнопки, при нажатии на них выключаем или включаем отбражение каких либо SPAN либо строк целиком. Сделано все влоб: function toggleDate() { $('.rgDate').hide(); } function toggleError() { $('.rgError').toggle(''); } function toggleWarning() { $('.rgWarning').toggle(''); } function toggleNotice() { $('.rgNotice').toggle(''); } function toggleDebug() { $('.rgDebug').toggle(''); } function toggleVerbose() { $('.rgVerbose').toggle(''); } Однако даже на 200К файле выключение, например, поля с датой занимает секунд 30. Процессор причем у меня довольно мощный, 2.5 ггц Coreduo и 6 Гб памяти. Посоветуйте, пожалуйста, методы оптимизации чтобы хотя бы 1..2 мегабайтный лог работал с приемлемой скоростью. Я думал может стоит хранить строки в массиве, а при выводе переформатировать и фильтровать все что надо. Изменились условия - снова фильтруем и форматируем. Но это как-то не православно чтоли ;) |
сделайте странички и ограничение скажем в 100 записей на странице и все будет летать. Вы всеравно не сможете смотреть сразу на все строки своего мегобайтного лога.
|
Так не подойдет. Там один звонок может растянуться во времени, за это время насыпется еще стопицот записей. Плюс поиск нужен полнотекстовый, браузерный. В общем 100 строк, даже 1000 это зачастую маловато.
|
Сделал так: сохраняю все строки в массив, перед выводом хелпер очищаю, потом прохожу регэкспами массив и выдаю в DOM уже готовый HTML. так работает в сто раз быстрее. На фильтрацию уходит примерно от одной до трех секунд пот 2500 строк. Но хочется еще больше скорости ;)
|
В смысле, в колонках таблиц либо убираются, либо добавляются элементы SPAN?
|
Уберите регулярку и будет быстрее.
|
Цитата:
Цитата:
Но мне не нравится что приходится читать логи. Хочу напрямую присоединяться к сервису и получать данные. Но как сделать это - ума не приложу. Через stdout|stdin врядли получится. |
Таблиц нет, есть только DIV - строка целиком, и SPAN - элемент строки.
И в тоже время нужно табличное представление данных с управлением по колонкам. Если построить структуру так, что каждая колонка это родитель, то менять стиль нужно будет только у родителя. |
Цитата:
|
Я думал сервер отдает структуру логов (разобранную рег. выражением), то есть согласно кнопкам - Date, Verbose, ... То есть это и есть колонки, тогда это табличные данные в любом случае.
|
switch001,
А жеквери убрать не пробовали? |
switch001,
<html> <head> <style> span{display: block} </style> </head> <body> <button id="rgDate">date</button> <button id="rgError">error</button> <button id="rgWarning">warning</button> <button id="rgNotice">notice</button> <button id="rgDebug">debug</button> <br> <div id="wrapper"> <span class="rgDate">date</span> <span class="rgError">error</span> <span class="rgWarning">warning</span> <span class="rgNotice">notice</span> <span class="rgDebug">debug</span> <span class="rgDate">date</span> <span class="rgError">error</span> <span class="rgWarning">warning</span> <span class="rgNotice">notice</span> <span class="rgDebug">debug</span> <span class="rgDate">date</span> <span class="rgError">error</span> <span class="rgWarning">warning</span> <span class="rgNotice">notice</span> <span class="rgDebug">debug</span> </div> <script> s=wrapper.innerHTML fltr=function(){ var re=new RegExp('<span class="'+this.id+'">[^>]+>', 'g') wrapper.innerHTML=s.match(re).join("") } ;[].forEach.call(document.querySelectorAll("button"), function(b){b.onclick=fltr}) </script> </body> </html> На файле 540кб на слабой машине, скорость менее секунды |
js-js: подход конечно интересный. И, сцуко, элегантный!!! Не сразу понял как работает. (да-да, я принадлежу "поколению Jquery")
Сейчас попробую на своих данных. jscripter: вот и пытаюсь это сделать |
js-js: действительно работает быстро. В моем наборе данных отрабатывает за секунду, в то время как мой подход работает около трех секунд. Но есть минус: данные уничтожаются. Нужно стиль чтоли менять на невидимый.
|
Цитата:
|
Цитата:
<button onclick="fltr('rgDialplan');">Dialplan</button> <script type="text/javascript" charset="utf-8"> function fltr(fld) { var s=document.getElementById('helper').innerHTML; var re=new RegExp('<span class="'+fld+'">[^>]+>', 'g'); document.getElementById('helper').innerHTML=s.replace(re, ""); } |
Цитата:
Странная у Вас "позиция". В переводе на русский: "у меня уничтожаются данные, потому что я их уничтожаю, как бы так сделать, чтобы я их перестал уничтожать?" |
Цитата:
|
Цитата:
document.getElementById('helper').innerHTML а это не работает helper.innerHTML Цитата:
|
Цитата:
var logItems = [{ label: "debug", text: "<span>10:05:00</span><span>some debug message</span>" }, { label: "error", text: "<span>10:05:00</span><span>some error message</span>" }] //.. document.getElementById("wrapper").innerHTML = logItems.filter(function(item) { return checkedLabels.indexOf(item.label) != -1; }.map(function(item) { return "<div class='log-item'>" + item + "</div>"; }).join(); А вообще, такие вещи делаются не вручную, а с помощью движков биндинга вроде реакта. |
Цитата:
А вообще я еще предыдущий метод не внедрил ;) но попробую. Метод с поиском по DOM регэкспами оказался не шибко гибким. UPDATE: метод с массивом тоже оказался муторным. Дело в том что скрывать нужно не только строку целиком, но и ее элементы. Т.е. надо строку разбить на группу элементов со свойствами, потом их собирать... а в строке не все ведь подлежит "разбивке", это тоже нужно хранить. В общем оценил объем возни и забил. К тому же потом понадобится анализировать не одну строку, а группы строк, это планирую делать регэкспом уже по готовому тексту. Короче пока оставил как есть. Может есть какой-то механизм, который привяжет к каждому найденному элементу функцию, которая в свою очередь будет реагировать на какое-то событие скрытия ? |
Цитата:
Цитата:
$(".toggle-log-item").on("click", (checkbox) => { let logItems = doucment.getElementById("wrapper").getElementsByClassName(checkbox.name); for (let item of logItems) { checkbox.display.style = checkbox.checked; } }); Ну и, да, переключатель лучше представлять как <input type=checkbox>, а не <button>. |
Цитата:
Цитата:
|
Цитата:
Цитата:
Но зачем так грубо отвечать? Я, вообще-то, помочь пытаюсь. |
Цитата:
Цитата:
button была. Я марафет еще не наводил, а налепил чтоб было на что нажать, только и всего. Ща вот никак из unix сокета не могу этот лог прочитать, немного подзабил на отображение. |
Цитата:
Цитата:
|
Часовой пояс GMT +3, время: 16:53. |