Інтернет Windows Android

Налаштування логів в php. Ведення лог файлу відвідувачів Log файл php

На сер'езних сайтах дивно бачити, коли помилки виводяться користувачеві в браузер в найнесподіваніших місцях. Чому вони з'являються - це окрема розмова. Але чому вони виводяться? Адже текст помилок є інформацією для дебага і призначена для розробника, а не для клієнта.

Крім того, саме ця службова інформація зазвичай допомагає злим хакерам ламати сайт. Як класичний приклад можна привести варіант з висновком запиту при помилці: "you have an error in query near WHERE id \u003d" ... Велике спасибі. Підставляємо після "WHERE id \u003d ..." рядок "0 OR 1\u003e 0" і запит виконується по всій таблиці. Якщо запит на видалення, то ... самі розумієте, весело \u003d). Тому я завжди змінні в запитах роблю висновок в лапки. На всякий випадок...

Але я захопився. Сьогодні не про це. Сьогодні поговоримо про те, як уникнути виведення помилок клієнту, зберігши при цьому всі повідомлення вебмайстру на пам'ять.

Почнемо, мабуть, з короткого огляду видів помилок в РНР.

Таблиця 1. Описи помилок в PHP4 (Оригінальний список)
числове
значення
Константа опис Ловиться / немає
1 E_ERROR Фатальні помилки. Наприклад, помилка при зверненні до пам'яті. Виконання скрипта при цьому переривається. немає
2 E_WARNING Попередження (не фатальними помилки). Виконання скрипта не переривається. да
4 E_PARSE Помилки під час аналізу синтаксису. Генеруються парсером. немає
8 E_NOTICE Зауваження (менш серйозні помилки, ніж попередження). Вказують на ситуацію, яка може стати причиною більш серйозної помилки, але можуть траплятися і в процесі нормальної роботи скрипта. да
16 E_CORE_ERROR Помилки під час завантаження РНР. Аналог E_ERROR, генерується ядром РНР. немає
32 E_CORE_WARNING Попередження під час завантаження РНР Аналог E_WARNING, генерується ядром РНР. немає
64 E_COMPILE_ERROR Фатальні помилки під час компіляції коду. Аналог E_ERROR, генерується зендовскім движком. немає
128 E_COMPILE_WARNING Попередження під час компіляції коду. Аналог E_WARNING, генерується зендовскім движком. немає
256 E_USER_ERROR Призначена для користувача помилка. да
512 E_USER_WARNING Користувача попередження. да
1024 E_USER_NOTICE користувача зауваження да

Нас цікавлять ті помилки, які ми можемо перехопити. До них відносяться: E_WARNING, E_NOTICE і E_USER_ *. Решта види помилок перехоплення не піддаються або через те, що відбуваються вони ще до закінчення завантаження самого ядра РНР, або через те, що відбуваються на етапі синтаксичного аналізу і компілювання РНР-коду, тому їх висновок доведеться просто відключити:

ini_set ( "display_errors", 0);

Але я припускаю, що наші скрипти досить налагоджені, щоб в них не було елементарних синтаксичних помилок, тому втратити ми нічого не повинні.

За замовчуванням рівень помилок в РНР має значення E_ALL & ~ E_NOTICE (або 2039 в числовій формі), що означає, що ми пропускаємо повз вуха зауваження, але повідомляємо про всіх інших помилках.

Тому змінимо рівень виведення помилок на E_ALL:

error_reporting (E_ALL);

Тепер перевизначити Хендлер помилок і підставимо замість нього нашу функцію, яка і займатиметься тепер обробкою помилок:

set_error_handler ( "user_log");

Розглянемо цю функцію детальніше. Їй передаються 5 параметрів:

  • код помилки
  • текст помилки
  • ім'я файлу, в якому сталася помилка
  • рядок в файлі
  • масив змінних

Повертати ця функція нічого не зобов'язана. Так як ми збираємося переглядати потім лог помилок, то треба зробити запис логу, наприклад, в файл так, щоб нам потім було зручно з ним працювати.

\u003d (LOG_FILE_MAXSIZE * 1024)) (// перевіряємо настройки, якщо встановлено лог_ротейт, // то "зрушує" старі файли на один вниз і створюємо порожній лог // якщо немає - чистимо і пишемо замість старого балки if (LOG_ROTATE \u003d\u003d\u003d true ) ($ i \u003d 1; // вважаємо старі логи в каталозі while (is_file (LOG_FILE_NAME. ".". $ i)) ($ i ++;) $ i--; // у кожного з них по черзі збільшуємо номер на 1 while ($ i\u003e 0) (rename (LOG_FILE_NAME. "..". $ i, LOG_FILE_NAME. ".". (1 + $ i--));) rename (LOG_FILE_NAME, LOG_FILE_NAME. ". 1"); touch (LOG_FILE_NAME);) elseif (is_file (LOG_FILE_NAME)) (// якщо пишемо логи зверху, то видалимо // і створимо заново порожній файл unlink (LOG_FILE_NAME); touch (LOG_FILE_NAME);)) / * перевіряємо чи є такий файл якщо немає - чи можемо ми його створити якщо є - чи можемо ми писати в нього * / if (! is_file (LOG_FILE_NAME)) (if (! touch (LOG_FILE_NAME)) (return "can \\" t create log file ";)) elseif ( ! is_writable (LOG_FILE_NAME)) (return "can \\" t write to log file ";) // зверніть увагу на функцію , Якої ми пишемо лог. error_log ($ err_str, 3, LOG_FILE_NAME); )?\u003e

Можна було б, звичайно, використовувати більш логічне для таких цілей сховище - базу, але ж помилки, в більшості своїй, виникають саме при роботі з базою, тому я б на неї не покладався.

Власне, це все. Усе інше, я думаю, не складе для вас праці, особливо, якщо користуватися функціями file (); & Explode (); . А якщо все-таки складе, то ви можете скористатися [ось цим кодом].

Передбачаючи питання "чому я не використовував CSV, який, здавалося б, логічно використовувати в цій ситуації?", Відповідаю: повідомлення про помилки можуть містити невідому кількість службових символів (ака ком і крапок з комою), що явно ускладнило б розбір CSV. Та й не збираюся я переглядати лог в Ексель.

Ще різні думки на цю тему:

  • при устаревании балки gz "іповать файл і складати його в архів;
  • то ж, але з посилкою на пошту;
  • при виникненні критичних помилок - слати мейл (див. приклад з мануала по функції

У кожному реальному PHP додатків час від часу виникають помилки і виключення, вискакують попередження, повідомлення. Якщо ми не будимо записувати цю інформацію (Залогуватися), то в один прекрасний момент стане неможливим зрозуміти, в який же частині додатка виникають ці помилки і виключення, і, відповідно, не зможемо вирішити їх. До того ж, існують такі ситуації, коли логирование подій, дій просто необхідно, як у випадку, з входом користувача в систему і виходом з неї, наприклад.

В PHP вже існують необхідні кошти для журналирования: функція error_log () - для відправки повідомлення в системний журнал, функція set_error_handler (), Для перехоплення попереджень і помилок. Ці функції можуть бути використані для призначеного для користувача керування помилками, даючи розробнику коду можливість самостійного управління логікою обробки і фільтрації помилок.

Однак такий низькорівневий доступ призводить до частого дублювання коду, і що ще більш важливо, такий код більш схильний до помилок. Тому на допомогу програмісту приходять вже готові компоненти, добре протестовані і зарекомендували себе в "бойових" умовах.

До таких компонентів відноситься компонент zend-log з фреймворка Zend. компонент zend-log може бути використаний в якості багатоцільового компонента логування, такий собі майстер на всі руки. Він підтримує безліч форматів журнальних повідомлень і різновидів баз логування (файли, бази даних), плюс до всього має опрацьовану систему фільтрації повідомлень і багато чого ще. також zend-log сумісний з PSR-3 стандартом логування. Встановлюється так:

Сomposer require zendframework / zend-log

Використовується в такий спосіб (для прикладу використовується файл index.php в корені проекту):

Require "vendor / autoload.php";

Use Zend \\ Log \\ Logger;
use Zend \\ Log \\ Writer \\ Stream;

$ Logger \u003d new Logger;

// відправляємо помилки в консоль
$ Writer \u003d new Stream ( "php: // ouput");

$ Logger -\u003e addWriter ($ writer);
$ Logger -\u003e log (Logger :: INFO, "Якась інформація");

Результат виконання коду вище:

2017-09-26T10: 40: 34 + 03: 00 INFO (6): Якась інформація

Підсумковий рядок включає час події, пріоритет і повідомлення. Формат виведеного повідомлення, безумовно, може бути змінений, якщо буде потреба з допомогою методу setFormatter (). За замовчуванням, рядок логу описується наступним шаблоном:

% Timestamp%% priorityName% (% priority%):% message%% extra%

  1. % Timestamp% - це мітка часу
  2. % PriorityName% - текстова мітка пріоритету
  3. % Priority% - числова мітка пріоритету
  4. % Message% - повідомлення
  5. % Extra% - необов'язкове значення для додаткової інформації

Якщо Ви захочете змінити формат повідомлення, то це робиться в такий спосіб:

$ Formatter \u003d new Zend \\ Log \\ Formatter \\ Simple ( "повідомлення% message%". PHP_EOL);
$ Writer -\u003e setFormatter ($ formatter);

компонент zend-log може бути також використаний для логування помилок і виключень самого інтерпретатора PHP. Для цього в класі Logger існую два статичних методу: Logger :: registerErrorHandler ($ logger) - для перехоплення помилок і Logger :: registerExceptionHandler ($ logger) - для перехоплення виключень.

Use Zend \\ Log \\ Logger;
use Zend \\ Log \\ Writer;

$ Logger \u003d new Logger;
$ Writer \u003d new Writer \\ Stream (__ DIR__. "/Test.log");
$ Logger-\u003e addWriter ($ writer);

// Залогуватися помилки
Logger :: registerErrorHandler ($ logger);

// Залогуватися виключення
Logger :: registerExceptionHandler ($ logger);

Як згадувалося раніше, zend-log надає нам можливість фільтрації повідомлень для логування, тобто перед тим як записати повідомлення в лог, ми може подивитися чи задовольняє воно нашим критеріям, і якщо так, то записуємо.

Ось приклад:

$ Filter \u003d new Zend \\ Log \\ Filter \\ Priority (Logger :: CRIT);

// метод addFilter інтерфейсу Writer
$ Writer-\u003e addFilter ($ filter);

В даному прикладі, ми будемо Залогуватися тільки ті повідомлення, чий пріоритет менше або дорівнює критичного ( Logger :: CRIT).

Повний список пріоритетів, визначених в класі Zend \\ Log \\ Logger:

Const EMERG \u003d 0; // Аварія: система непридатна для використання
const ALERT \u003d 1; // Тривога: терміново необхідно вживати заходів
const CRIT \u003d 2; // Критична ситуація
const ERR \u003d 3; // Помилка
const WARN \u003d 4; // Попередження
const NOTICE \u003d 5; // Увага
const INFO \u003d 6; // Інформація
const DEBUG \u003d 7; // Дебаг, налагодження

Ми також можемо фільтрувати повідомлення на основі регулярних виразів, тимчасових міток і т.д. Таким чином, логирование в PHP - це важлива і часом необхідна річ при розробці web-додатків.

В інтернеті існує велика кількість сервісів, що надають послуги з обліку відвідуваності Вашого сайту. Дані послуги надаються як платно, так і безкоштовно. Наприклад, можна привести LiveInternet. Цей сервіс досить широкий в інтернеті і майже кожен сайт користується його послугами. Власник має детальну статистику про відвідування його сайту.

Безперечно! Дані сервіси незамінні в обліку відвідуваності сайту і подальшого вивчення поведінки користувачів. Але в даній статті я хочу розповісти, як можна зробити на сервері лог-файл візитів відвідувачів.

Лог-файл візитів

Даний лог файл буде дуже корисний, для обліку візитів і переглядів відвідувачами Ваш сайт. Для створення лог-файлу використовується скрипт, написаний на мові php. Скрипт досить простий в розумінні та встановлення на сайт.

Скрипт php для створення лог-файлу

Скрипт записує точний час заходу на сайт, визначає браузер відвідувача, і що найголовніше - визначає звідки прийшов відвідувач до Вас. Запис лог-файлу відбувається при кожному відображенні до тієї чи іншої сторінки сайту. Тобто, власник сайту може подивитися в лог файлі які конкретно переглядав сторінки сайту відвідувач за певним IP і часу, використовуючи певний браузер.

Лістинг скрипта записи даних в лог-файл

установка скрипта

Збережіть скрипт в шаблоні, або в зовнішньому файлі users.php. Для того, щоб вставити скрипт в сторінку використовуйте наступний код.

Під логування в PHP мається на увазі те, про яких типах помилок буде повідомляти вам ваше веб-додаток / сайт / php-скрипт і яким чином.

Існує 2 (3) основні способи отримання помилок від програми:

  1. Висновок цих помилок безпосередньо на екран
  2. Запис цих помилок в спеціальний лог-файл
  3. або ж відразу обидва варіанти: висновок цих помилок на екран і запис їх в спеціальний лог-файл

Як правило, практикується таке, що при розробці (на локальному оточенні) всі помилки показуються прямо на екрані, щоб їх було легше і оперативніше відловлювати і виправляти, а в бойовому середовищі (на продакшені) помилки не показуються взагалі (тому що для користувача - це даремна інформація) і вся інформація про них пишеться в лог-файл, який розробник регулярно переглядає.

Налаштування для логування помилок

  1. error_reporting - це найголовніший параметр. Він відповідає за те, повідомлення про помилки яких типів будуть відображатися / писатися в лог-файл.Я вважаю, що тут існує тільки 2 опції, які можливо використовувати:
    • -1 (Або E_ALL) - повідомляється про всі типи помилок;
    • 0 - не повідомляється ні про які типи помилок

    Я рекомендую використовувати виключно -1 (або E_ALL).
    Оскільки додаток не повинно мати жодних помилок, в принципі. Цю опцію можна задати через конфігураційний файл в php.ini або ж прямо в php-скрипті за допомогою виклику функції error_reporting:

    Error_reporting (-1); error_reporting (E_ALL);

    До речі кажучи, це єдина опція, яка є в мові PHP у вигляді функції. Всі інші опції можна задати виключно за допомогою редагування конфігураційного файлу php.ini або ж виклику функції ini_set () передавши в неї, відповідно, необхідний параметр і значення для нього.

  2. display_errors - цей параметр відповідає за безпосередній показ помилок на екрані після того, як вона, власне, відбулася. Даний параметр може мати значення 0 або 1 або On / Off. Тобто або показувати помилки на екрані, або ні.
  3. display_startup_errors - ця опція відповідає за показ помилок, що сталися після запуску PHP. Наприклад, якщо в файлі конфігурації є синтаксична помилка, то інформація про неї буде показана. Даний параметр може мати значення 0 або 1 або On / Off.
  4. log_errors - дана директива відповідає за те, щоб записувати повідомлення про помилки в лог-файл. Даний параметр може мати значення 0 або 1 або On / Off. Тобто записувати помилки в лог або ж немає.
  5. error_log - це налаштування відповідає за шлях до файлу (лог-файлу), в який будуть записуватися всі відбулися помилки програми
  6. html_errors - ця ж опція відповідає за формат відображення помилок програми. Якщо задана як 1 або On, то помилка буде показана за допомогою HTML'а, тобто буде trace походження помилки і все буде досить інформативно і барвисто. Якщо ж значення цієї настройки задано як 0 або Off, то помилки будуть відображатися у вигляді звичайного тексту в вигляді невеликого числа рядків.

1. Налаштування для відображення помилок на екрані




ini_set ( "html_errors", 1);
ini_set ( "log_errors", 0);

2. Налаштування для запису помилок в лог-файл

Error_reporting (-1); // ini_set ( "error_reporting", -1);
ini_set ( "display_errors", 0);
ini_set ( "display_startup_errors", 0);
ini_set ( "log_errors", 1);

3. Налаштування для одночасного відображення помилок і їх записи в лог-файл

Error_reporting (-1); // ini_set ( "error_reporting", -1);
ini_set ( "display_errors", 1);
ini_set ( "display_startup_errors", 1);
ini_set ( "log_errors", 1);
ini_set ( "html_errors", 1);
ini_set ( "error_log", "/var/log/php/error.log");

Так само, ці опції можна задати і в файлі конфігурації php.ini або ж у файлі вашого віртуального хоста.