Запись в файл Apache access_log с помощью php

Мне нужно записать статистические данные в живой файл Apache access_log (у меня есть другой процесс, который подсчитывает определенные строки в файле access_log, который периодически отчитывается перед другим процессом).

В настоящее время я просто заставляю запись в файле access_log, выполнив в php следующее:

file("http://127.0.0.1/logme.php?stuff_that_I_can_watch_here");

logme.php ничего не делает и возвращается пустым с 200 успехами.

Проблема с описанным выше методом заключается в том, что для каждого запроса к серверу Apache создается другой запрос для записи в журнал, что приводит к удвоению требуемых серверов Apache.

Когда серверы накапливаются, простой и обычно быстрый локальный вызов сервера Apache занимает более 5 секунд.

Могу ли я писать в файл access_log напрямую, не вызывая проблем, или, может быть, даже есть способ записи в файл apache_log с помощью php, аналогичного syslog() или error_log()?


person Chris Denman    schedule 17.12.2010    source источник
comment
Это пахнет плохим дизайном. Почему вы хотите регистрировать в журнале доступа то, что на самом деле не является доступом? Не лучше ли использовать для этих целей отдельный файл журнала?   -  person tdammers    schedule 17.12.2010
comment
Первоначально статистика собиралась из лог-файла Apache практически в режиме реального времени. По мере роста наших проектов требовалось больше статистики, причем на условном уровне. Например, хотя загрузка страницы, как обычно, поместит простую запись в access_log, иногда что-то может происходить при определенных обстоятельствах, и только тогда это нужно регистрировать. Существует процесс, который прослушивает файл access_log на наличие сигналов, и эта информация отправляется на внешние серверы. Это может стать очень грязным, если нужно обработать несколько файлов журналов.   -  person Chris Denman    schedule 17.12.2010
comment
@ Крис, это может быть каким-то образом возможно - если PHP работает как модуль Apache, кажется возможным, например, регистрировать ошибки в error_log, но об использовании отдельного файла журнала совершенно не может быть и речи? Похоже, это было бы намного проще. (Обновление: Ах, вы расширили свой комментарий, отвечая на мой вопрос)   -  person Pekka    schedule 17.12.2010
comment
Полагаю, я усложняю ситуацию, объясняя обстоятельства. На самом деле вопрос в том, можно ли напрямую писать в access_log или есть простой способ добиться того же эффекта с помощью php?   -  person Chris Denman    schedule 17.12.2010
comment
Справедливо. Хм, может быть, virtual() может работать быстрее, чем явный запрос? php.net/manual/en/function.virtual.php I понятия не имею, регистрируются ли эти звонки, хотя   -  person Pekka    schedule 17.12.2010
comment
На данный момент я придумал решение. Теперь я пишу во второй файл, и наша проприетарная система прослушивания прослушивает ДВА файла вместо одного. Это работает и может быть окончательным решением, но было хорошо, что выложили это!   -  person Chris Denman    schedule 17.12.2010
comment
Существуют и другие методы, если вы нужна одна переменная, например имя пользователя, в журнале Apache.   -  person Jan Fabry    schedule 21.07.2011


Ответы (3)


Вы можете использовать apache_note (http://php.net/apache_note), чтобы записать свои значения в заметку, а затем использовать CustomLog с LogFormat (%{NOTE_NAME}n) (http://httpd.apache.org/docs/2.2/mod/mod_log_config.html), чтобы регистрировать новые ключи. Ваши программы, анализирующие журнал доступа, также могут считывать новые параметры журналирования.

person Aswin Anand    schedule 27.08.2012

можно ли напрямую писать в access_log

Вы можете писать напрямую в access_log, но делать это НЕ НУЖНО.
Работающий apache может порождать несколько процессов,
и блокировать файл для записи с использованием более медленного процесса, такого как PHP, просто еще больше замедляет скорость регистрации.

или есть простой способ добиться того же эффекта с помощью php

Не используйте PHP, добавьте дополнительный пользовательский журнал, если запрос полностью заполните ваше требование.
Это более правильный способ, и этот пользовательский журнал должен содержать меньшую строку, так как доступ к статическому файлу не регистрируется. Которые напрямую улучшают парсинг лога позже.

person ajreal    schedule 17.12.2010
comment
Мы не фильтруем конкретные запросы страниц, а вставляем дополнительную статистику в зависимости от обстоятельств. т.е. один запрос страницы может привести к нескольким вещам, которые нам нужно увидеть. - person Chris Denman; 17.12.2010
comment
в php есть функция apache_note, помогает ли это? - person ajreal; 17.12.2010

<?php
  $h = fopen('/path/to/access_log', 'a');
  fwrite($h, 'Message');
  fclose($h);
?>

Другие уже прокомментировали дизайн. Apache access_log предназначен для того, чтобы Apache регистрировал доступы, и точка.

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

person Community    schedule 17.12.2010
comment
Проблема заключается не в разделении журналов Apache, а в возможности добавлять данные в файл access_log, который извлекается с помощью нашего проприетарного программного обеспечения для прослушивания. - person Chris Denman; 17.12.2010
comment
Например, нажатие на index.html приведет к тому, что access_log получит еще одну строку. Но в некоторых случаях мне нужно записать БОЛЬШЕ информации в файл журнала, например dummy.php?user_is_chris, поэтому один запрос приводит к появлению двух строк в access_log. Наша система прослушивания каждые 60 секунд подсчитывает статистику по отчетам о летучих станциях на внешний сервер. - person Chris Denman; 17.12.2010
comment
Например, я мог бы CURL локальное изображение и передавать параметры таким образом, но моя проблема не в этом - моя проблема в том, что вызов локального сервера в запросе удваивает количество открытых запросов. Записывая дополнительную информацию непосредственно в access_log, вы предотвращаете напрасную трату ожидающего обработчика сервера Apache. - person Chris Denman; 17.12.2010
comment
Иногда вам просто нужно сделать то, что вы должны сделать: fwrite() в access_log. - person ; 17.12.2010