Вопрос или проблема
Я бы хотел разобрать файл журнала доступа и получить количество запросов за последние 7 дней. У меня есть такая команда
cut -d'"' -f3 /var/log/apache/access.log | cut -d' ' -f2 | sort | uniq -c | sort -rg
К сожалению, эта команда возвращает количество запросов с момента создания файла и сортирует их по категориям HTTP-кодов. Я хотел бы только число, без категорий, и только за последние 7 дней.
Я бы настроил ротацию журналов ежедневно (как это сделать, будет зависеть от вашей ОС), а затем применил ту же команду к 7 самым последним журналам. Что касается вашего существующего журнала, вы можете использовать инструмент вроде grep, чтобы извлечь только те дни, которые вам нужны, или разделить этот журнал на журналы за каждый день.
Если вы хотите что-то более элегантное, я бы просто посмотрел на одно из множества инструментов для разбора журналов, которые уже существуют.
Вот пример, как разделить ваш существующий журнал:
Разделить файл access.log по датам с помощью командной строки
Это утилита Microsoft, так что, вероятно, это не то, что вам нужно, но есть утилита под названием LogParser (ссылка), которая анализирует файлы журналов Apache и позволяет использовать синтаксис в стиле SQL для фильтрации, агрегации и т.д.
Вам нужно будет указать параметр формата ввода как NCSA.
Это должно быть возможно, но я застрял в вложенности команд Bash, которая не работает, и я не понимаю, почему.
Концептуально, сделайте это:
- Найдите дату 7 дней назад в формате, который есть в вашем журнале Apache
date -d "-7 days" +%d\/%b\/%Y
-> 10/Oct/2013
- Удалите от первой строки до первого упоминания этой даты
sed '1,/~pattern~/d' access_log
- Пустите результат в wc, чтобы получить подсчет.
| wc -l
Таким образом, должен быть способ объединить вышеописанное в одну команду:
$ sed '1,/10\Oct\/2013/d' access_log | wc -l
29
$ sed '1,/$(date -d "-7 days" +%d\/%b\/%Y)/d' access_log | wc -l
$
Где-то во вложенности моя команда date и sed не работают вместе. И все, что я пробую с различными комбинациями кавычек и экранированием, не имеет значения.
Что я упускаю?
Как насчет анализа инструментов, таких как Splunk или Loggly? Loggly имеет бесплатный пробный период, Splunk Storm (http://splunkstorm.com) является бесплатной подпиской, и если ваши журналы не превышают их лимиты, то индексировать ваши журналы и выполнять различные статистики по запросам за последние 7 дней (или в различных других временных рамках) должно быть тривиально.
Я предлагаю изменить вашу ротацию журналов syslog на ежедневную, тогда ниже приведенный скрипт будет работать
#!/bin/bash
ZCAT=$(cat access.log.1 | egrep "GET|POST" | awk '{ print $11 }' ; zcat access.log.[2-7].gz | egrep "GET|POST" | awk '{ print
$11 }')
#echo подсчет загрузок страниц за неделю. это может занять некоторое время
for path in `echo "$ZCAT" | sort -u`
do
echo "$path" >&2
echo `echo "$ZCAT" | egrep "^$path$" | wc -l` " :: $path"
done | sort -n > "stats.log"
Ответ или решение
Чтобы подсчитать количество запросов из файла доступа за последние 7 дней, можно использовать команду на bash, которая включает несколько утилит UNIX. Мы рассмотрим три основных шага: получение даты за 7 дней назад, фильтрация лог-файла по этой дате и подсчет числа запросов. Давайте проанализируем каждый шаг подробно.
1. Определение даты 7 дней назад
Для начала, необходимо получить дату, соответствующую 7 дням назад в том формате, который используется в ваших логах Apache (обычно это ДД/МММ/ГГГГ
, например, 10/Oct/2023
). Мы можем использовать команду date
для этого:
date_seven_days_ago=$(date -d "-7 days" "+%d/%b/%Y")
Эта команда создаст переменную date_seven_days_ago
, которая будет содержать дату в нужном формате.
2. Фильтрация логов
Теперь, когда у нас есть дата, мы можем отфильтровать лог-файл, чтобы оставить только строки, относящиеся к последним 7 дням. Это можно сделать с помощью команды sed
. Добавим фильтрацию в команду:
grep -A1000 "$date_seven_days_ago" /var/log/apache/access.log | grep -v "^[^ ]* [^ ]* [^ ]*"
Этот код использует grep
для получения всех строк после первой строки с датой 7 дней назад и исключает ненужные строки, если они есть.
3. Подсчет количества запросов
После того как мы отфильтровали лог-файл, можно подсчитать общее количество запросов, используя wc
:
total_requests=$(grep -A1000 "$date_seven_days_ago" /var/log/apache/access.log | grep -v "^[^ ]* [^ ]* [^ ]*" | wc -l)
Объединенный скрипт
Чтобы объединить все шаги в один исполняемый скрипт, можно использовать следующее:
#!/bin/bash
date_seven_days_ago=$(date -d "-7 days" "+%d/%b/%Y")
total_requests=$(grep -A1000 "$date_seven_days_ago" /var/log/apache/access.log | grep -v "^[^ ]* [^ ]* [^ ]*" | wc -l)
echo "Total requests in the last 7 days: $total_requests"
Дополнительные рекомендации
Если у вас есть настроенная ротация логов, это значительно упростит задачу. Вы можете использовать zcat
для сжатых логов и повторить процесс для нескольких файлов. Например, если ваши логи сжимаются до access.log.1.gz
, access.log.2.gz
, и так далее, можно создать цикл, который будет их обрабатывать.
Альтернативные инструменты
Если вам не очень удобно работать с командной строкой и bash, вы можете рассмотреть возможность использования сторонних инструментов, таких как Splunk или Loggly. Эти инструменты предлагают мощные функции для анализа логов, могут просто индексировать записи и позволят вам выполнять запросы за определенные временные промежутки с помощью SQL-подобного синтаксиса.
Таким образом, используя данные подходы, вы сможете эффективно анализировать логи доступа и получать необходимые метрики.