Как посчитать количество вхождений определенной строки в последнем лог-файле для чтения данных за последние 5 минут в Linux

Вопрос или проблема

Я хочу зафиксировать код ошибки, например:502 из файла журнала. Файл журнала обновляется, когда достигает 100 МБ, например access.log_126427, access.log_197455 и т.д. Конкретного паттерна для названия журнала нет. Мы хотим посчитать количество вхождений кода ошибки 502 из самого последнего файла журнала и хотим количество вхождений только за последние 5 минут, а не за весь последний файл журнала. Пожалуйста, кто-нибудь, помогите..

Вот имя файла журнала.

access_log.1733745600
access_log.1733752774
access_log.1733761132
access_log.1733793455
access_log.1733805955
access_log.1733813194
access_log.1733820432
access_log.1733828261
access_log.1733835435
access_log.1733843126
access_log.1733854306

А внутри файла журнала данные будут выглядеть так

2409:40d1:8a:b2e1:68fe:5cff:fe6d:ec1c, 23.64.1.206, 104.124.54.45 172.27.76.22 – – [12/Dec/2024:20:01:06 +0530] “POST /api/midas/service/beneficiary/v1/banklogo
HTTP/1.1” 502 40190 223709
2401:4900:5dea:1400:ec30:5908:d658:7894, 23.64.1.206, 23.45.91.41 172.27.76.22- – [12/Dec/2024:20:01:06 +0530] “POST /api/midas/service/accounts/v1/accountDetails
HTTP/1.1” 200 1082 199338
2401:4900:7c63:b831:fd24:83c5:ad7c:cf90, 104.90.5.244, 104.124.54.45 172.27.76.22 – – [12/Dec/2024:20:01:06 +0530] “GET /minio/etb-top
banners/UPI_Credit_Card_New.png?1734813866141 HTTP/1.1” 502 246932 22834

Это:

perl -MTime::Piece -snle '
    BEGIN{
        my $t = localtime;
        our $now = $t->epoch;
        our $monthsRe = join "|", $t->mon_list;
        our $count = 0;
    }
    m!\[(\d{2}/(?:$monthsRe)/\d{4}:\d{2}:\d{2}:\d{2})\s.*\sHTTP/\d+\.\d+"?\s+${http_code}\s!;
    my $d = Time::Piece->strptime("$1", "%d/%b/%Y:%H:%M:%S");
    my $old = $d->strftime("%s");
    my $diff = (($now - $old) + $gap);
    if ($diff > $min and $diff < $max) {$count++}
    END{print $count}
' -- -gap=$({ printf "%s" "0"; date "+%:::z*3600"; } | bc) \
     -min=0 \
     -max=300 \
     -http_code=502 access.log

Некоторые объяснения: https://stackoverflow.com/a/75483421/465183

Ответ или решение

Для подсчета количества вхождений кода ошибки, например, 502, в последнем журнале за последние 5 минут на Linux, можно использовать комбинацию команд оболочки и утилиты perl.

Шаги по выполнению задачи

  1. Определите последний файл журнала. Вам нужно найти самый новый файл из списка, который вы предоставили, например, access_log.1733854306.

  2. Проверьте формат времени в журналах. Убедитесь, что формат даты и времени в ваших журналах соответствует образцу, указанному в вашем вопросе. В этом случае, запись времени выглядит так: [12/Dec/2024:20:01:06 +0530].

  3. Используйте Perl для анализа файла журнала. С помощью программистского языка Perl можно извлечь необходимые данные и подсчитать количество вхождений кода ошибки 502 за последние 5 минут.

Пример команды

Вот команда, которую можно использовать в терминале:

perl -MTime::Piece -snle '
    BEGIN{
        my $t = localtime;
        our $now = $t->epoch;
        our $monthsRe = join "|", $t->mon_list;
        our $count = 0;
    }
    m!\[(\d{2}/(?:$monthsRe)/\d{4}:\d{2}:\d{2}:\d{2})\s.*\sHTTP/\d+\.\d+"?\s+${http_code}\s!;
    my $d = Time::Piece->strptime("$1", "%d/%b/%Y:%H:%M:%S");
    my $old = $d->strftime("%s");
    my $diff = ($now - $old);
    if ($diff < 300) {$count++}
    END{print $count}
' -- -http_code=502 /path/to/your/logs/access_log.*

Объяснение команды

  • perl -MTime::Piece -snle: Запускает Perl с модулем Time::Piece для работы с временем.
  • BEGIN { ... }: Блок инициализации, где определяется текущее время в секундах.
  • m!\[(\d{2}/(?:$monthsRe)/\d{4}:\d{2}:\d{2}:\d{2})\s.*\sHTTP/\d+\.\d+"?\s+${http_code}\s!: Шаблон регулярного выражения, который ищет строки с кодом ошибки, проверяя дату/время.
  • my $d = Time::Piece->strptime("$1", "%d/%b/%Y:%H:%M:%S"): Преобразует строку даты/времени в объект времени.
  • my $diff = ($now - $old): Вычисляет разницу во времени между текущим временем и временем из журнала.
  • if ($diff < 300) {$count++}: Увеличивает счетчик на 1, если разница во времени меньше 300 секунд (5 минут).
  • END{print $count}: В конце выводит общее количество найденных вхождений.

Рекомендации

Обязательно замените /path/to/your/logs/access_log.* на фактический путь к вашим файлам журналов, чтобы скрипт мог корректно обнаружить и проанализировать файлы.

Эта команда агрономически эффективна и позволяет точно подсчитывать нужные вхождения за заданный промежуток времени, используя мощь языка Perl.

Оцените материал
Добавить комментарий

Капча загружается...