Регулярные выражения и разбор лога
|Первым делом давайте разберемся, зачем нам регулярные выражения и что с ними делать.
Регулярные выражения призваны упростить нам жизнь при работе с данными — если нам надо что-то найти, определить, заменить, изменить, проверить и так далее, примеров может быть масса. Из самых простых — это актуально при валидации разного рода информации типа дат, IP адресов. Частенько еще это может пригодиться при формировании и/или форматировании логов, как раз наш случай.
У нас в распоряжении будут логи apache/nginx, с разными параметрами даты, их мы и будем разбирать.
Первым выражением мы попробуем полностью разобрать дату не зависимо от формата, примеры наших дат:
- [28/Aug/2016:07:48:33 +0000]
- 2016/08/31
Пример выражения:
((\d{2}|\d{4})/(\d{2}|\w{3})/(\d{2}|\d{4})(?:\:|\s+))
Что к чему? Мы пытаемся подогнать нашу регулярку под используемые форматы даты. В самом начале у нас идет день или год, соответственно мы проверяем из скольких чисел состоит первая часть и в нашем случае это может быть 2 или 4 числа, соответствено мы и добавляем подходящее условие \d{2}|\d{4}.
В случае, если формат даты может принимать значение вида 1/12/2017, то проверку надо будет немного менять и использовать менее жесткое выражение \d{1,2}.
Кроме даты, у нас в логах обычно присутствую такие параметры как время, тип запроса, ip адрес и конечно же полезная нагрузка — событие (payload).
Событие лучше всего парсить универсально и целеком простым выражением «.+» которое захватывает абсолютно все, а вот уже далее отдельно заниматься анализом payload’а и разбирать его отдельными регулярными выражениями.
Из того, что нам еще стоило бы разобрать отдельно и на первом этапе:
- IP
- Дата и время
- Тип запроса
Чтобы сверять IP обойдемся простым регулярным выражением, которое будет проверять количество цифр от 0 до 9:
(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})
С датой и временем мы разобрались уже чуть выше, осталось определить возможные типы запросов и обозначить payload.
Регулярка под типы запросов:
(POST|GET|PUT|OPTION|HEAD)
Теперь давайте еще разберем время:
([0-9]{2}:[0-9]{2}:[0-9]{2}\s+)
Ну и теперьможно собрать из этих небольших регулярных выражений одно целое и посмотреть на результат:
(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(?:\W+)(\d{2}|\d{4})/(\d{2}|\w{3})/(\d{2}|\d{4})(?:\:|\s+)[0-9]{2}:[0-9]{2}:[0-9]{2}(?:.+?)(POST|GET|HEAD|PUT|OPTION))
Данным выражением мы забираем почти все, кроме payload, чтобы забрать и пейлоад, надо добавить лишь «.+» и у вас будет полностью разобранный лог.
После разобра лога, должно получиться что-то похожее:
Может быть интересно: