Форум dkLab и Denwer
Здесь общаются Web-разработчики.
Генеральный спонсор:
Хостинг «Джино»

Логирование отдельных событий внутри приложения (Severus)
Author Message
Severus
Заглянувший



Joined: 06 Feb 2006
Posts: 8
Карма: 0
   поощрить/наказать


PostPosted: Mon Jul 20, 2009 2:15 pm (написано за 12 минут 24 секунды)
   Post subject: Логирование отдельных событий внутри приложения
Reply with quote

Здравствуйте!
Есть здоровое web-приложение на php. Сейчас возникла необходимость периодически, в целях диагностики, вести несколько логов событий внутри приложения.
Необходимо логировать вызовы и коды возвратов ряда функций, частично данные.
Т.е. сейчас приходится в приложении в ряде методов прописать вызовы простенького класса логгера что бы получить N-логов.
Проблема в том, что количество необходимых логов может меняться. Как и точки откуда этот класс будет вызываться.
Создавать россыпть объектов $Event1Log, $Event2Log, итд не очень хочется.

Как можно удобно локализровать ведение нескольких логов внутри одного объекта? Интересует так же реализация интерфейса вызова события записи в конкретный лог.
Т.е. что бы можно было писать что то вроде $logManager->SaveEvent_1('hello'); и эта запись легла в лог для типа событий 1.

Я смотрел в сторону Magic Methods но может есть более правильное решение?
Back to top
View user's profile Send private message
Ivan1986
Участник форума
Warnings: 2


Joined: 09 Oct 2007
Posts: 807
Карма: 38
   поощрить/наказать


PostPosted: Mon Jul 20, 2009 2:36 pm (спустя 20 минут; написано за 3 минуты 55 секунд)
   Post subject:
Reply with quote

я пока обхожусь вот этим
Code (php): скопировать код в буфер обмена
class Log (www.php.net/log)
{
        public static (www.php.net/static) function l($str,$file='general')
        {
                file_put_contents(QFW::$config['host']['logpath'].'/'.$file.'.log', date (www.php.net/date)('Y-m-d H:i:s').': '.$str."\n", FILE_APPEND | LOCK_EX);
        }
}
когда извращений захотелось и появилось php 5.3 - начал извращаться
Code (php): скопировать код в буфер обмена
class Log (www.php.net/log)
{
        private static (www.php.net/static) $l=null;
        private static (www.php.net/static) $messages=array (www.php.net/array)();

        /*
        public static (www.php.net/static) function __callStatic($method, $params)
        {
                $str = $params[0];
                $to = $method=='log' ? (isset (www.php.net/isset)($params[1])?$params[1]:'general') : $method;
                if (isset (www.php.net/isset)(QFW::$config['log'][$to]))
                        $to = QFW::$config['log'][$to];
                if (self::$l === null)
                                self::$l = new Log (www.php.net/log)();
                if ($to == 'error')
                        error_log (www.php.net/error_log)($str);
                elseif(strpos (www.php.net/strpos)($to,'mailto:')===0)
                        self::$l->email($str,substr (www.php.net/substr)($to,7));
                elseif(strpos (www.php.net/strpos)($to,'xmpp://')===0)
                        self::$l->jabber($str,substr (www.php.net/substr)($to,7));
                else
                        self::f($str, $to);
        }

        private function jabber($str, $to) { self::$messages['jabber'][$to][]=$str; }
        private function email($str, $to) { self::$messages['email'][$to][]=$str; }
        private static (www.php.net/static) function f($str, $to)
        {
                error_log (www.php.net/error_log)(date (www.php.net/date)('Y-m-d H:i:s').': '.$str."\n", 3, QFW::$config['host']['logpath'].'/'.$to.'.log');
        }

        public function __destruct()
        {
                if (isset (www.php.net/isset)(self::$messages['email']))
                        foreach (self::$messages['email'] as $k=>$msg)
                                error_log (www.php.net/error_log)(join (www.php.net/join)("\n",$msg), 1, $k);
                if (isset (www.php.net/isset)(self::$messages['jabber']))
                {
                        if (!isset (www.php.net/isset)(QFW::$config['jabber']))
                                error_log (www.php.net/error_log)('Jabber   '.join("\n",$msg));
                        else
                        {
                                require_once LIBPATH.'/jabber/XMPPHP/XMPP.php';
                                $J = new XMPPHP_XMPP(QFW::$config['jabber']['host'], QFW::$config['jabber']['port'],
                                        QFW::$config['jabber']['user'], QFW::$config['jabber']['pass'],
                                        QFW::$config['jabber']['resource'], QFW::$config['jabber']['server'],
                                        !QFW::$config['QFW']['release'], XMPPHP_Log::LEVEL_ERROR);
                                $J->connect();
                                $J->processUntil('session_start',10);
                                $J->presence();
                                foreach (self::$messages['jabber'] as $k=>$msg)
                                        $J->message($k, join (www.php.net/join)("\n",$msg));
                                $J->disconnect();
                        }
                }
        }

}
и конфиг к нему:
Code (php): скопировать код в буфер обмена
$config['log'] = array (www.php.net/array)(
        'log' => 'error',
        'critical' => 'xmpp://ivan1986@jabber.ru',
        'error' => 'mailto:ivan1986@list.ru',
);
собственно можно и без callStatic, но тогда нельзя красиво вызвать Log::log() в php 5.3 так как изначально было вот так:
Code (php): скопировать код в буфер обмена
class Log (www.php.net/log)
{
        public static (www.php.net/static) function log (www.php.net/log)($str,$file='general')
        {
                file_put_contents(QFW::$config['host']['logpath'].'/'.$file.'.log', date (www.php.net/date)('Y-m-d H:i:s').': '.$str."\n", FILE_APPEND | LOCK_EX);
        }
        public function __construct() {}
}
но в php 5.3 это сломалось
Back to top
View user's profile Send private message Send e-mail
Severus
Заглянувший



Joined: 06 Feb 2006
Posts: 8
Карма: 0
   поощрить/наказать


PostPosted: Tue Jul 21, 2009 10:44 am (спустя 20 часов 8 минут; написано за 31 секунду)
   Post subject:
Reply with quote

Спасибо, видимо адаптирую для себя первый вариант.
Back to top
View user's profile Send private message
Severus
Заглянувший



Joined: 06 Feb 2006
Posts: 8
Карма: 0
   поощрить/наказать


PostPosted: Tue Jul 28, 2009 5:11 pm (спустя 7 дней 6 часов 27 минут; написано за 29 секунд)
   Post subject:
Reply with quote

а чем file_put_contents принчипиально лучше чем fopen и fwrite?
Back to top
View user's profile Send private message
dimagolov
Участник форума



Joined: 04 Feb 2007
Posts: 1664
Карма: 96
   поощрить/наказать

Location: Christ Church, Barbados

PostPosted: Tue Jul 28, 2009 5:34 pm (спустя 22 минуты; написано за 1 минуту 42 секунды)
   Post subject:
Reply with quote

Quote:
а чем file_put_contents принчипиально лучше чем fopen и fwrite?
тем что это одна библиотечная ф-я, которая делает ровно то, что 3 других. Кроме того к fopen надо как минимум проверку делать, а 3 вызова и проверка будет на интерпретируемом php, когда в file_put_contents все то же самое уже скомпилено в ядре.
Back to top
View user's profile Send private message
bæv
Модератор «Дзена»



Joined: 27 Aug 2003
Posts: 7275
Карма: 9986
   поощрить/наказать


PostPosted: Tue Jul 28, 2009 7:08 pm (спустя 1 час 34 минуты; написано за 1 минуту 8 секунд)
   Post subject:
Reply with quote

Severus wrote:
чем fopen и fwrite?
— там ещё и fclose()

ru2.php.net/manual/en/function.file-put-contents.php wrote:
This function is identical to calling fopen(), fwrite() and fclose() successively to write data to a file.
Back to top
View user's profile Send private message
Severus
Заглянувший



Joined: 06 Feb 2006
Posts: 8
Карма: 0
   поощрить/наказать


PostPosted: Fri Jul 31, 2009 4:25 pm (спустя 2 дня 21 час 16 минут; написано за 6 минут 14 секунд)
   Post subject:
Reply with quote

Т.е. при использовании file_put_contents если в N местах будут вызовы логирования, то файл будет лочится при добавлении данных именно не с начала жизни объекта, а аккурат в тот момент времени когда отрабатывает функция file_put_contents?

Страницы где используется логинг вызываются несколькими клиентами одновременно и получаешь мешанину из сообщений. Придётся либо разделять логи - одна сессия - один лог, либо для каждого созданного объекта на время его жизни создавать GUID и при каждой записи этого объекта в лог добавлять к ней GUID что бы можно было группировать с последующей сортировкой по времени.
Back to top
View user's profile Send private message
dimagolov
Участник форума



Joined: 04 Feb 2007
Posts: 1664
Карма: 96
   поощрить/наказать

Location: Christ Church, Barbados

PostPosted: Sun Aug 02, 2009 5:59 pm (спустя 2 дня 1 час 33 минуты; написано за 3 минуты 3 секунды)
   Post subject:
Reply with quote

Severus, при логировании можно писать SID в лог и потом делать grep по sid, получишь все события, которые относятся к определенному сеансу. можно еще всякую полезную инфу на автомате добавлять, там IP, логин и прочее по вкусу для удобства. можно делать несколько логов, например параметры приходящих запросов в один лог, SQL запросы, которые исполняются в другой, запросы, которые трактуются как некорректные в третий и т.п. как автору удобно так и можно сделать.
Back to top
View user's profile Send private message
XaHyMaH
Участник форума



Joined: 04 Mar 2004
Posts: 41
Карма: 2
   поощрить/наказать

Location: Алматы

PostPosted: Thu Dec 09, 2010 12:55 pm (спустя 1 год 4 месяца 6 дней 18 часов 55 минут; написано за 1 минуту 18 секунд)
   Post subject:
Reply with quote

А насколько надёжна у file_put_contents блокировка (LOCK_EX)?
У меня как-то был глюк при использовании раздельно fopen(), fwrite() и fclose(). Что-то вроде этого: spectator.ru/technology/php/flock_workaround
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic All times are GMT + 3 Hours
Page 1 of 1    Email to a Friend.
You cannot post new topics in this forum. You cannot reply to topics in this forum. You cannot edit your posts in this forum. You cannot delete your posts in this forum. You cannot vote in polls in this forum. You cannot attach files in this forum. You can download files in this forum.
XML