powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Объединение логов в общий журнал и вывод в хронологическом порядке за интервал
24 сообщений из 24, страница 1 из 1
Объединение логов в общий журнал и вывод в хронологическом порядке за интервал
    #40065982
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть множество (сотни, тысячи) log-файлов, содержащих дату (yyyy-mm-dd), время (hh:mm:ss) и сообщение, все сообщения однострочные.
Нужен скрипт, который выведет все логи за определенный период (например за последние 24 часа или за период с d1 по d2).
Сейчас я сделал все "ленивым" способом: по очереди обрабатываю все файлы, считываю их построчно, добавляю во временный массив строки, дата/время которых соответствуют периоду, а в конце просто сортирую временный массив и вывожу его.
Но напрашивается способ все это оптимизировать.
Поскольку log-файлы заполняются последовательно (то есть уже отсортированы по дате), то можно очень сильно сократить требования к памяти и заодно ускорить обработку.
Алгоритм я вижу следующим. Открываю файл, считываю строку, считываю из нее дату. Если дата меньше нужного периода, то повторяю со следующей строкой. Если дата вошла в нужный интервал — запоминаю в индексном указателе файл, смещение текущей строки и дату, на которую указывает данное смещение, после чего закрываю файл. Затем повторяю то же самое со следующим файлом. При добавлении в индексный указатель новой записи сравниваю с другими индексами, чтобы вставить ее в нужное место (чтобы индексный указатель был упорядочен по дате).
Когда все файлы обработаны, то начинаю обрабатывать индексный указатель, начиная с самого минимального элемента. После считывания строки по указателю определяю следующую дату и перестраиваю индекс.
И так до тех пор, пока дата не превысит заданный период или все файлы не будут выведены полностью. Точность сравнения будет до секунд, в пределах одной секунды записи одного файла будут неразрывны (то есть не будут перемешиваться записи с разных файлов)
В индексном указателе будет высокая интенсивность вставок, поэтому его лучше делать связанным списком.
Тем не менее будет очень много рутинной возни с пересчетом и перестановкой индексов.
Может быть это можно как-то улучшить?
...
Рейтинг: 0 / 0
Объединение логов в общий журнал и вывод в хронологическом порядке за интервал
    #40065986
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По сути тебе не сортировка нужна, а слияние. Выбираешь нужный кусок первого лога в один массив, кусок второго во второй - делаешь слияние (в один проход). Затем также 3 и 4 лог, затем слияние обоих результатов.

Принцип как у сортировки слиянием .

Этот алгоритм можно легко распараллелить.
...
Рейтинг: 0 / 0
Объединение логов в общий журнал и вывод в хронологическом порядке за интервал
    #40065996
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если делать слияние, то это уже будет расход памяти (в которой будет храниться итоговый массив).
А я хочу вообще память на это не расходовать, в памяти будет только индексный указатель на текущие смещения в файлах и соответствующие им даты.
Мне просто нужно реализовать правильную обработку сдвига указателей (в пределах секунды по строкам внутри файла, за пределами секунды по самим файлам).
...
Рейтинг: 0 / 0
Объединение логов в общий журнал и вывод в хронологическом порядке за интервал
    #40066003
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.
в памяти будет только индексный указатель на текущие смещения в файлах и соответствующие им даты.
Мне просто нужно реализовать правильную обработку сдвига указателей (в пределах секунды по строкам внутри файла, за пределами секунды по самим файлам).

Двигать указатели никуда не надо, т.к. сама строка в логе никуда не сдвигается.
В остальном алгоритм это никак не меняет, вместо массивов строк храни массивы структур с полями: {Дата, Номер лога, Смещение}

PS Это как часто надо делать? Если часто, то может есть смысл в БД переливать постоянно, например раз в минуту, а как потребуется - быстро выбрать.
...
Рейтинг: 0 / 0
Объединение логов в общий журнал и вывод в хронологическом порядке за интервал
    #40066007
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
То есть примерно так.
Например мне нужно вывести логи за период с 2021-04-26 01:02:03 по 2021-04-26 08:00:00.
Делаю инициализацию, открываю все файлы, считываю в индексный указатель смещения с датой 2021-04-26 01:02:03 и более, но не больше 2021-04-26 08:00:00. По итогам инициализации у меня есть упорядоченный по дате индекс.
Нахожу в индексе минимальный файл, у которого смещение указывает на 2021-04-26 01:02:03, вывожу все строки с этой датой (одновременно с этим обновляя смещение и дату в индексе). Затем повторяю со всеми файлами индекса, у которых смещение указывает на 2021-04-26 01:02:03. По завершению выведены все записи на момент 2021-04-26 01:02:03.
Затем нахожу в индексе следующую дату, которая будет старше 2021-04-26 01:02:03 — например это будет 2021-04-26 01:02:05.
А повторяю до тех пор, пока не дойду до 2021-04-26 08:00:00.
...
Рейтинг: 0 / 0
Объединение логов в общий журнал и вывод в хронологическом порядке за интервал
    #40066008
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T
PS Это как часто надо делать? Если часто, то может есть смысл в БД переливать постоянно, например раз в минуту, а как потребуется - быстро выбрать.

Эпизодически. Это не постоянная потребность, а скорее инструмент траблшутинга, будет необходим от случая к случаю.
Отдельные лог-файлы как раз удобны (у каждого объекта свой лог), но иногда нужно делать "сквозной" просмотр или поиск.
...
Рейтинг: 0 / 0
Объединение логов в общий журнал и вывод в хронологическом порядке за интервал
    #40066093
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.
То есть примерно так.
Например мне нужно вывести логи за период с 2021-04-26 01:02:03 по 2021-04-26 08:00:00.
Делаю инициализацию, открываю все файлы, считываю в индексный указатель смещения с датой 2021-04-26 01:02:03 и более, но не больше 2021-04-26 08:00:00. По итогам инициализации у меня есть упорядоченный по дате индекс.
Нахожу в индексе минимальный файл, у которого смещение указывает на 2021-04-26 01:02:03, вывожу все строки с этой датой (одновременно с этим обновляя смещение и дату в индексе). Затем повторяю со всеми файлами индекса, у которых смещение указывает на 2021-04-26 01:02:03. По завершению выведены все записи на момент 2021-04-26 01:02:03.
Затем нахожу в индексе следующую дату, которая будет старше 2021-04-26 01:02:03 — например это будет 2021-04-26 01:02:05.
А повторяю до тех пор, пока не дойду до 2021-04-26 08:00:00.

По сути это тоже слияние, но не из двух источников, а больше.
Можно делать слияние любого количества источников, в твоем случае открыть N файлов с логами, в каждом встать на первую подходящую запись и затем найти файл с наименьшим временем, записать из него, затем снова найти с наименьшим временем и т.д.
Так расход памяти минимальный, но возрастает нагрузка на проц, т.к. каждый раз надо искать минимум среди всех логов. Попробуй, может эти тормоза окажуться незначительными.
...
Рейтинг: 0 / 0
Объединение логов в общий журнал и вывод в хронологическом порядке за интервал
    #40066095
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.

Алгоритм я вижу следующим. Открываю файл, считываю строку, считываю из нее дату. Если дата меньше нужного периода, то повторяю со следующей строкой. Если дата вошла в нужный интервал — запоминаю в индексном указателе файл, смещение текущей строки и дату, на которую указывает данное смещение, после чего закрываю файл. Затем повторяю то же самое со следующим файлом. При добавлении в индексный указатель новой записи сравниваю с другими индексами, чтобы вставить ее в нужное место (чтобы индексный указатель был упорядочен по дате).
Когда все файлы обработаны, то начинаю обрабатывать индексный указатель, начиная с самого минимального элемента. После считывания строки по указателю определяю следующую дату и перестраиваю индекс.
И так до тех пор, пока дата не превысит заданный период или все файлы не будут выведены полностью. Точность сравнения будет до секунд, в пределах одной секунды записи одного файла будут неразрывны (то есть не будут перемешиваться записи с разных файлов)
В индексном указателе будет высокая интенсивность вставок, поэтому его лучше делать связанным списком.
Тем не менее будет очень много рутинной возни с пересчетом и перестановкой индексов.
Может быть это можно как-то улучшить?

Мне кажется в топике есть как-бы 2 пути решения.

1) Это следовать твоим указаниям по реализации. Я думаю вряд-ли читатели форума захотят это делать. Это похоже на ТЗ.
Не стиль форума. Да и не захотят все делать так. Вот если ты напишешь макет и предложишь улучшить или пофиксить баг -
то пожалуй да.

2) Решить задачу так как ее решают админы и девопсы.

Как-то так

Код: plaintext
1.
2.
3.
$ cat log_2021-01-01.log log_2021-01-02.log ... | sort > full.log

$ grep -F "2021-04-26 16:45:" < full.log


Будет медленно. Нудно. Но сработает. Далее можно кешировать или автоматизировать и скриптовать бесконечно.
Можно резать логи на месячные. Сутошные. Часовые партишены и раскладывать по фолдерам для пущей скорости.
И тогда выборка сводится просто к навигации в файловой системе. Это дешево. Почти нулевые расходы.

Строить индексные структуры для данной задачи - это конечно интересно но мне кажется подобная задача уже
была решена например в Elastic Search. Есть смысл поднять эластик хотя-бы в докере и попробовать натравить его
на логи. Будет быстро + текстовые возможности поиска.
...
Рейтинг: 0 / 0
Объединение логов в общий журнал и вывод в хронологическом порядке за интервал
    #40066401
Фотография tchingiz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

эта, может ему это все во что нибудь типа sqlite загрузить?
//
...
Рейтинг: 0 / 0
Объединение логов в общий журнал и вывод в хронологическом порядке за интервал
    #40066404
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно. Если ему не жалко в памяти держать свои драгоценные пета-байты логов.
...
Рейтинг: 0 / 0
Объединение логов в общий журнал и вывод в хронологическом порядке за интервал
    #40066406
Фотография tchingiz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Можно. Если ему не жалко в памяти держать свои драгоценные пета-байты логов.

а шо там в памяти держится?

была какая то штука логпарсер

https://en.wikipedia.org/wiki/Logparser
я ей както в сайбез все сгружал, щас почитаю как
...
Рейтинг: 0 / 0
Объединение логов в общий журнал и вывод в хронологическом порядке за интервал
    #40066407
Фотография tchingiz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ааа, делал из логов csv файл и интерактив скл-ем cгружал в бд.
...
Рейтинг: 0 / 0
Объединение логов в общий журнал и вывод в хронологическом порядке за интервал
    #40066411
Фотография tchingiz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чем больше читаю, тем меньше мне эта идея нравится )))
греп там еще шото делает.
окончательно передумал

Код: python
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
#!/bin/zsh.exe 
nm=LPLoad

path=$1
query=$2
day=$3
msk=$4
fidelity=$5
rep=$6
dFlag=$7

if  [  $# -eq 7  ]
then
  started=`$DATE +"%s"`   ;  started=${started%[^0-9]}     
  stopped=0               
  printf "..%s  for '%s' is here\n" $nm  $query        >>$rep
  $LS  $path/$msk   >$THIS/.$nm.ls
  if [   -s $THIS/.$nm.ls   ] ; then
    $GREP  -v \# $path/$msk   >$THIS/.$nm.grep
    if [   -s $THIS/.$nm.grep   ] ; then
      if [  $dFlag -ge 0   ] ; then
        printf "..%s: >%s %s %s %s %s<\n" $nm  $PARSER $PARSER_SEP -i:$PARSER_PAR \
                       -o:CSV file:$query\?from=$path/$msk+dt=$day+int=$fidelity
      fi
      $RM -rf $THIS/.$nm.csv
      $PARSER $PARSER_SEP -stats:OFF -e:0 -i:$PARSER_PAR -o:CSV -headers:OFF \
                      file:$query\?from=$path/$msk+dt=$day+int=$fidelity >$THIS/.$nm.csv
      RC=$?
      printf "..%s:  parser RC is %s\n" $nm    $RC           >>$rep
      if [ $dFlag -eq 0   ] ; then
        if [    $RC -ne 0  ] ; then
          printf "%s"  $RC  >$THIS/.rcg.save
          if [ -f  $THIS/.rcg.save  ] ; then
            printf "..%s: there was error: %s"  $nm $RC  >>$rep
          fi
          RC=0
        fi
      fi
      if [ -s  $THIS/.$nm.csv -a $RC -eq  0  ] ; then
        printf "input into ar.udua from '%s' format ASCII delimited by ','(ip,dt,prj,fl,isDld,isLv,c2s,s2c,src,drt,nt);"\
                                                    $THIS/.$nm.csv  >$THIS/.$nm.sql
        printf " commit; "  $THIS/.$nm.csv  >>$THIS/.$nm.sql
        $ISQL -c "$DB_CNCT" $THIS/.$nm.sql
        RC=$?
        printf "..%s:  db load RC is %s\n" $nm   $RC         >>$rep
      fi
    else
      RC=0
      printf "..%s:  log is empty. query/msk: '%s'/'%s'\n" $nm     $query $msk        >>$rep
    fi
  else
    RC=0
    printf "..%s: no  log files \n" $nm            >>$rep
  fi
  if [   $dFlag -eq 0   ] ; then
    $RM -rf $THIS/.\*.
  fi

  stopped=`$DATE +"%s"`        ; stopped=${stopped%[^0-9]}
  let "stopped = $stopped -  $started"     

  ls=`$GREP -c .  $THIS/.$nm.csv`  ;   ls=${ls%[^0-9]}
  printf "..%s  for '%s' is finished. lines/secs: %s/%s\n" $nm $query $ls $stopped    >>$rep
  printf "\n %s is finished. RC is %s\n"  $nm $RC

else
  printf "\n $nm: wrong number of params: $#\n\n"
  exit 3
fi

exit $RC      

...
Рейтинг: 0 / 0
Объединение логов в общий журнал и вывод в хронологическом порядке за интервал
    #40066455
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На слуху у меня такое ключевое слово как Splunk. Я с ним лично не работал, но вроде как в ентерпрайзе - его любят

https://www.splunk.com/

Считается морально устаревшим. Ему на замену рекомендуют связку Elastic + Kibana.

https://www.elastic.co/elastic-stack

В Кибане - роскошные средста визуализации. Можно временные диаграммы ошибок строить.
Также стек содержит готовые шаблоны для захватывания логов nginx, apache http e.t.c.
...
Рейтинг: 0 / 0
Объединение логов в общий журнал и вывод в хронологическом порядке за интервал
    #40066496
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как-то это все не то.
Если бы это был кровавый энтерпрайз, то да, я бы уже давно грузил бы логи в базу данных или в Elastic.
Но это небольшая вспомогательная хотелка, нынешний формат (текстовый лог на объект) устраивает в 99% случаев и лишь изредка нужен "сквозной поиск" или "сквозной просмотр". И мне интересно это сделать минимальными ресурсами, мне кажется красивым сделать алгоритм, который не требует для своей работы больших вспомогательных буферов памяти.
И пока что я не вижу дефектов в описанном мной выше алгоритме. То есть вначале находим во всех файлах самую раннюю запись, подходящую под критерии вывода (причем это можно делать как последовательно, так и параллельно). Затем по найденным результатам находим самую раннюю запись, выводим ее и ищем следующую раннюю запись. Поскольку во всех файлах записи упорядочены, то после первого сканирования повторные сканирования больше не нужны, достаточно правильно обновлять указатели в файлах (чтобы они всегда были упорядочены по возрастанию).
Если кто-то укажет на ошибки в алгоритме или более оптимальный алгоритм, то буду рад. Но как натравить на подобную задачу современные инструменты, я и сам знаю.
...
Рейтинг: 0 / 0
Объединение логов в общий журнал и вывод в хронологическом порядке за интервал
    #40066503
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Покажи имена твоих файлов. Есть-ли в имени намёк на искомые данные?
...
Рейтинг: 0 / 0
Объединение логов в общий журнал и вывод в хронологическом порядке за интервал
    #40066508
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имена файлов это просто целое число.
(это логи телеграм-бота, для каждого пользователя отдельный лог)
...
Рейтинг: 0 / 0
Объединение логов в общий журнал и вывод в хронологическом порядке за интервал
    #40066517
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Жаль. Ну тогда их надо всех перелопатить и проиндексировать.

Можно следовать твоему алгоритму. Строить BRIN-подобные индексы для текста.
Но возникает вопрос структуры данных. Где это хранить и как обновлять этот индекс.
Если у тебя с телеграм бота сливаются сведенья по разным потокам и в одно время - то надо
как-то усложнять этот индекс чтобы он объединял данные.

И можно просто сделать как я предложил. Обрабатывать все файлы и переливать их в структуру
каталогов типа yyyy/mm/dd/hh/mm/ss. Файлы можно даже не объединять. Пускай в одной секунде
будет несколько разных источников. Парсинг и grep этой секунды пройдет очень быстро. Тоесть
моя задача сводится к сплиту всех файлов на такие короткие секундные фрагменты. Внешний
вид CLI может выглядеть как-то так:

Код: sql
1.
$ split --input /bot-logs --output /output --date-format "yyyy-mm-dd hh:MM:ss" --precision 1sec
...
Рейтинг: 0 / 0
Объединение логов в общий журнал и вывод в хронологическом порядке за интервал
    #40066551
H5N1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
все же просто и шаблонно. запустить spark, вычитать файлы в spark датафрейм, сохранить в parquet табличку с датой-время (yyy-mm-dd-hh24) в качестве партиции. на ноутбуке с ssd это в пределах часа-двух на 100 гб логах. после этого кверить из колончатой структуры паркета, указывая четкую партицию, будет очень быстро. причем кверить можно будет прямо в sql языке.
новые логи также превращать в parquet и докидывать в папку с новой датой (в новую партицию).
как вариант скачать докер с zeppeline и записать все это в notebook и настроить в нем же шедулинг, визуализацию с бэкджеком.
...
Рейтинг: 0 / 0
Объединение логов в общий журнал и вывод в хронологическом порядке за интервал
    #40066573
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Обрабатывать все файлы и переливать их в структуру каталогов типа yyyy/mm/dd/hh/mm/ss.

Нет. Поиск логов в конкретном файле (для конкретного пользователя) — гораздо более частая и нужная задача, поэтому логи и партицируются по айди пользователя. В дальнейшем может быть добавлю ротацию логов по годам или месяцам, но пока такой необходимости нет.
Сквозной поиск по всем логам нужен намного реже, чтобы под него менять структуру логов.
У простого текстового последовательного лога есть свои преимущества, поэтому грузить их в реляционную или документную базу данных я пока не планирую.
...
Рейтинг: 0 / 0
Объединение логов в общий журнал и вывод в хронологическом порядке за интервал
    #40066594
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.
mayton
Обрабатывать все файлы и переливать их в структуру каталогов типа yyyy/mm/dd/hh/mm/ss.

Нет. Поиск логов в конкретном файле (для конкретного пользователя) — гораздо более частая и нужная задача, поэтому логи и партицируются по айди пользователя. В дальнейшем может быть добавлю ротацию логов по годам или месяцам, но пока такой необходимости нет.
Сквозной поиск по всем логам нужен намного реже, чтобы под него менять структуру логов.
У простого текстового последовательного лога есть свои преимущества, поэтому грузить их в реляционную или документную базу данных я пока не планирую.

А мы можем обогатить логи, добавив к дате ID пользователя?

Например.

Код: sql
1.
2.
2021-04-28 16:48:00 :: id=555 :: [Info] User log in
2021-04-28 16:48:01 :: id=777 :: [Error] Runtime Exception during ....



Ничего не меняется в остальном и мой алгоритм слияния остается в силе.
...
Рейтинг: 0 / 0
Объединение логов в общий журнал и вывод в хронологическом порядке за интервал
    #40066685
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можем.
Но я имею ввиду другое, мне как раз удобно иметь раздельные логи по каждому пользователю.
(к тому же идентификаторы далеко не трехзначные и съедают ширину экрана)
(а также имеют переменную длину и нарушают колонки при просмотре)
...
Рейтинг: 0 / 0
Объединение логов в общий журнал и вывод в хронологическом порядке за интервал
    #40066768
H5N1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.,

колхозить однопоточную обработку глупо. то о чем ты говоришь делается ровно двумя командами
val df = spark.read().format("csv").option("delimiter", " ").option("header", "false").load(dir_path)
ds.filter("user='shit'").show();

и это будет многпоточное чтение. если надо по папкам (партициям) разложить, тоже простенькая конструкция. и сохранить разложенное, хоть в json, хоть в xml. хотя смысла перекладывать в формат отличный от parquet/orc нет никакого.
...
Рейтинг: 0 / 0
Объединение логов в общий журнал и вывод в хронологическом порядке за интервал
    #40066943
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тема топика могла бы сойти за пятничную задачу.
...
Рейтинг: 0 / 0
24 сообщений из 24, страница 1 из 1
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Объединение логов в общий журнал и вывод в хронологическом порядке за интервал
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]