Syslog: примеры (PHP)

Использование PHP функции syslog для системного логирования
Раздел: Логирование
syslog(int priority, string message): bool
Описание функции syslog

Функция syslog() в PHP предназначена для отправки сообщений в системный журнал (лог) операционной системы. Она взаимодействует с демоном syslogd (или его современными аналогами, такими как rsyslog, syslog-ng) и полезна для записи системных событий, ошибок и отладочной информации приложений.

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

Аргументы функции
  • priority (обязательный): целое число, определяющее приоритет сообщения. Формируется путём логического ИЛИ (|) между константой приоритета (LOG_ERR, LOG_WARNING и т.д.) и константой средства (LOG_USER, LOG_LOCAL0 и т.д.).
  • message (обязательный): строка с текстом сообщения для записи в журнал.

Перед первым вызовом syslog() необходимо открыть соединение с журналом с помощью функции openlog() для настройки параметров. После завершения работы рекомендуется вызывать closelog().

Простые примеры использования
Базовый пример с openlog
<?php
// Открываем соединение с syslog
openlog("myPHPApp", LOG_PID | LOG_PERROR, LOG_LOCAL0);

// Отправляем сообщение с приоритетом "ошибка"
syslog(LOG_ERR, "Тестовое сообщение об ошибке.");

// Закрываем соединение
closelog();
?>
В системном журнале (например, /var/log/syslog) появится строка вида:
Feb 10 14:23:45 hostname myPHPApp[12345]: Тестовое сообщение об ошибке.
Примеры с разными приоритетами
<?php
openlog("WebApp", LOG_PID, LOG_USER);

syslog(LOG_INFO, "Пользователь зашел в систему.");
syslog(LOG_WARNING, "Загрузка ЦП превысила 80%.");
syslog(LOG_CRIT, "Критическая ошибка в модуле оплаты!");

closelog();
?>
Сообщения будут записаны с соответствующими метками приоритета (info, warning, crit).
Альтернативы для логирования в PHP
  • error_log(): Более универсальная функция. Может отправлять сообщения не только в syslog (LOG_SYSLOG), но и в файл, на email или в SAPI. Удобна, когда нужна гибкость в выборе приемника логов.
  • Специализированные библиотеки (Monolog): Пакет Monolog предоставляет мощный, многоуровневый логгер с поддержкой десятков обработчиков (handlers) - файлы, syslog, базы данных, Slack и др. Использование Monolog предпочтительнее в современных приложениях из-за структурированности, гибкости и поддержки контекста.
  • Прямая запись в файл (fwrite): Простой, но менее надежный способ. Не обеспечивает централизованное управление логами и ротацию, как это делает syslogd.

Функцию syslog() лучше использовать для интеграции с системной инфраструктурой логирования ОС. Для сложного логирования внутри приложения выбирают Monolog.

Аналоги функции в других языках
Python (модуль logging)
import logging
import logging.handlers

logger = logging.getLogger('myApp')
logger.setLevel(logging.INFO)

# Обработчик для syslog
handler = logging.handlers.SysLogHandler(address='/dev/log')
logger.addHandler(handler)

logger.error('Критическая ошибка в Python')

В Python логирование более объектно-ориентированное и настраиваемое через модуль logging.

JavaScript (Node.js - модуль 'syslog')
const syslog = require('syslog');

// Создаем клиента
const logger = syslog.createClient(514, 'localhost');

logger.log('Предупреждение от Node.js приложения', 
  { severity: 'warning', facility: 'user' }, 
  () => { logger.close(); }
);

В Node.js требуется установка дополнительного модуля. Логирование асинхронное.

MySQL (Syslog Feature)

Начиная с версии 5.1.20, MySQL может отправлять ошибки в syslog. Настройка происходит через параметры конфигурации syslog и syslog-facility в my.cnf, а не через SQL-функцию.

Типичные ошибки и проблемы
1. Отсутствие вызова openlog()
<?php
// Пропущен openlog
syslog(LOG_ERR, "Сообщение"); // Может работать, но поведение не определено
?>

Результат:

Сообщение может не записаться или будет использовано имя скрипта по умолчанию (например, 'php').
2. Неправильный приоритет
<?php
openlog("app", LOG_PID, LOG_USER);
// Использование числа вместо константы
syslog(999, "Странное сообщение.");
?>

Результат:

Приоритет может быть интерпретирован непредсказуемо, часто как LOG_INFO.
3. Специальные символы в сообщении
<?php
openlog("test", LOG_PID, LOG_USER);
syslog(LOG_INFO, "Сообщение с % и \n внутри.");
?>

Символ '%' может обрабатываться демоном syslog особым образом. Символ новой строки (\n) часто обрезается. Лучше избегать их или экранировать.

Изменения в современных версиях PHP
  • PHP 8.0.0: Функция openlog() и syslog() теперь выбрасывают исключение ValueError, если параметр priority в openlog() или priority в syslog() выходят за допустимый диапазон. Ранее в этих случаях вызывалась ошибка уровня E_WARNING.
  • PHP 7.3.0: Добавлена поддержка дополнительных значений для параметра option функции openlog() на системах, поддерживающих константы LOG_PERROR (запись также в stderr) и LOG_CONS (отправка в консоль при ошибке с syslogd).
  • Семантика и сигнатура основных функций (syslog(), openlog(), closelog()) остаются стабильными на протяжении многих версий.
Расширенные примеры
1. Логирование с контекстом и переменными
Пример php
<?php
openlog("BillingService", LOG_ODELAY | LOG_PID, LOG_LOCAL1);

$userId = 14567;
$transactionId = 'txn_987654321';
$amount = 1500.50;

// Формирование структурированного сообщения
$message = sprintf(
    "[Transaction Failed] user_id=%d | txn_id=%s | amount=%.2f | reason=%s",
    $userId,
    $transactionId,
    $amount,
    "Insufficient funds"
);
syslog(LOG_WARNING, $message);

closelog();
?>
В логе: ... BillingService[54321]: [Transaction Failed] user_id=14567 | txn_id=txn_987654321 | amount=1500.50 | reason=Insufficient funds
2. Использование разных facilities (средств)
Пример php
<?php
// Логи безопасности в отдельный facility
openlog("secure-auth", LOG_PID, LOG_AUTH);
syslog(LOG_ALERT, "Multiple failed login attempts for admin.");
closelog();

// Логи отладочной информации от скрипта-демона
openlog("custom-daemon", LOG_PID | LOG_CONS, LOG_DAEMON);
syslog(LOG_DEBUG, "Starting main processing loop.");
closelog();
?>

Разные facility позволяют разделять логи по типу и перенаправлять их в разные файлы через настройки rsyslog.

3. Обработка ошибок с try-catch
Пример php
<?php
openlog("DataImporter", LOG_NDELAY, LOG_LOCAL2);

try {
    // Код, который может вызвать исключение
    $data = riskyOperation();
    syslog(LOG_INFO, "Операция завершена успешно.");
} catch (Exception $e) {
    // Логирование исключения в syslog
    syslog(LOG_CRIT, 
        "Unhandled exception: " . $e->getMessage() . 
        " in " . $e->getFile() . 
        ":" . $e->getLine()
    );
    // Также можно отправить дубликат ошибки на почту через error_log
    error_log($e->getMessage(), 1, 'admin@example.com');
}

closelog();
?>

PHP syslog function comments

En
Syslog Generate a system log message