Как анализировать логи Apache с помощью регулярных выражений в PHP - PullRequest
6 голосов
/ 08 февраля 2010

Я пытаюсь разбить эту строку в PHP:

11.11.11.11 - - [25/Jan/2000:14:00:01 +0100] "GET /1986.js HTTP/1.1" 200 932 "http://domain.com/index.html" "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 GTB6"

Как можно разделить это на IP, дату, метод HTTP, доменное имя и браузер?

Ответы [ 4 ]

12 голосов
/ 08 февраля 2010

Этот формат журнала выглядит как комбинированный формат журнала Apache . Попробуйте это регулярное выражение:

/^(\S+) \S+ \S+ \[([^\]]+)\] "([A-Z]+)[^"]*" \d+ \d+ "[^"]*" "([^"]*)"$/m

Подходящие группы:

  1. удаленный IP-адрес
  2. дата запроса
  3. запрос HTTP-метода
  4. Пользователь-агент значение

Но домен там не указан. Вторая строка в кавычках имеет значение Referer .

4 голосов
/ 10 августа 2011

Вот немного Perl, а не PHP, но регулярное выражение используется то же самое. Это регулярное выражение работает, чтобы разобрать все, что я видел; клиенты могут отправлять несколько странных запросов:

my ($ip, $date, $method, $url, $protocol, $alt_url, $code, $bytes,
        $referrer, $ua) = (m/
    ^(\S+)\s                    # IP
    \S+\s+                      # remote logname
    (?:\S+\s+)+                 # remote user
    \[([^]]+)\]\s               # date
    "(\S*)\s?                   # method
    (?:((?:[^"]*(?:\\")?)*)\s   # URL
    ([^"]*)"\s|                 # protocol
    ((?:[^"]*(?:\\")?)*)"\s)    # or, possibly URL with no protocol
    (\S+)\s                     # status code
    (\S+)\s                     # bytes
    "((?:[^"]*(?:\\")?)*)"\s    # referrer
    "(.*)"$                     # user agent
/x);
die "Couldn't match $_" unless $ip;
$alt_url ||= '';
$url ||= $alt_url;
4 голосов
/ 08 февраля 2010

Вы должны проверить учебник по регулярным выражениям. Но вот ответ:

if (preg_match('/^(\S+) \S+ \S+ \[(.*?)\] "(\S+).*?" \d+ \d+ "(.*?)" "(.*?)"/', $line, $m)) {
  $ip = $m[1];
  $date = $m[2];
  $method = $m[3];
  $referer = $m[4];
  $browser = $m[5];
}

Будьте осторожны, это не доменное имя в журнале, а реферер HTTP.

2 голосов
/ 01 сентября 2015
// # Parses the NCSA Combined Log Format lines:
$pattern = '/^([^ ]+) ([^ ]+) ([^ ]+) (\[[^\]]+\]) "(.*) (.*) (.*)" ([0-9\-]+) ([0-9\-]+) "(.*)" "(.*)"$/';

Использование:

if (preg_match($pattern,$yourstuff,$matches)) {

    //# puts each part of the match in a named variable

    list($whole_match, $remote_host, $logname, $user, $date_time, $method, $request, $protocol, $status, $bytes, $referer, $user_agent) = $matches;

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...