PHP Conference Japan 2024

syslog

(PHP 4, PHP 5, PHP 7, PHP 8)

syslog生成系统日志消息

描述

syslog(int $priority, string $message): true

syslog() 生成一个日志消息,该消息将由系统日志记录器分发。

有关设置用户定义日志处理程序的信息,请参阅 syslog.conf (5) Unix 手册页。有关 syslog 功能和选项的更多信息,可以在 Unix 机器上的 syslog (3) 手册页中找到。

参数

priority

以下常量之一:LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG

message

要发送的消息。

返回值

始终返回 true

示例

示例 #1 使用 syslog()

<?php
// 打开 syslog,包含进程 ID,并将日志发送到标准错误,并使用用户定义的
// 日志记录机制
openlog("myScriptLog", LOG_PID | LOG_PERROR, LOG_LOCAL0);

// 一些代码

if (authorized_client()) {
// 执行某些操作
} else {
// 未经授权的客户端!
// 记录尝试
$access = date("Y/m/d H:i:s");
syslog(LOG_WARNING, "Unauthorized client: $access {$_SERVER['REMOTE_ADDR']} ({$_SERVER['HTTP_USER_AGENT']})");
}

closelog();
?>

注释

在 Windows 上,syslog 服务使用事件日志模拟。

注意:

对于 openlog()facility 参数,使用 LOG_LOCAL0LOG_LOCAL7 在 Windows 中不可用。

参见

添加注释

用户贡献的注释 16 条注释

james dot ellis at gmail dot com
17 年前
如果有人想知道为什么他们的日志消息会出现在多个日志文件中,这里有一个适用于 *nix 系统的答案

如果你的 syslog.conf 看起来像这样(假设你使用 LOG_LOCAL0 进行 Web 应用日志记录)

local0.info /var/log/web/info.log

这将收集所有 LOG_INFO 及以上级别的消息,即除调试消息之外的所有消息

尝试使用以下方法来确保只有指定日志级别的消息进入相关的日志文件

local0.=info /var/log/web/info.log

此外,你可能希望添加以下内容,以确保你的消息不会出现在通用日志文件(如“messages”,“all”,“syslog”和“debug”)中

local0.none /var/log/messages
local0.none /var/log/debug
等等

节省磁盘空间以及其他方面 - 更多信息请参阅“man syslog.conf”
stevekamerman at gmail dot com
6 年前
此函数以 BSD Syslog RFC 3164 格式发送消息(https://tools.ietf.org/html/rfc3164)。

要查看 PHP 发送到日志套接字的原始消息,首先停止你的 syslog/rsylsog/ng-syslog 服务,然后使用 netcat-openbsd 包监听日志套接字

nc -U -l /dev/log

现在,从 PHP 记录一些内容

<?php
syslog
(LOG_LOCAL1|LOG_INFO, "Test from PHP");
?>

你将在 netcat 中看到 rfc3164 输出

<142>Oct 24 14:32:51 php: Test from PHP
OWM
4 年前
Syslog 自动检测换行符控制字符,因此会根据多行拆分消息。为了防止 PHP 7.3+ 中的此行为,你可以使用当前未记录的 ini 设置

<?php

ini_set
('syslog.filter', 'raw');

# 更多信息请参见:https://bugs.php.net/bug.php?id=77913
Antonio Lobato
14 年前
警告:如果你使用 openlog() 来准备 syslog(),并且你的 Apache 线程接受多个请求,那么如果你将 Apache 的错误日志配置为写入 syslog,则*必须*调用 closelog()。否则,Apache 的错误日志将写入 openlog 中使用的任何功能/标识。

例如,在 httpd.conf 中,你拥有

ErrorLog syslog:local7

在 php 中,你执行

<?php
openlog
("myprogram", 0, LOG_LOCAL0);
syslog("My syslog message");
?>

从现在开始,这个 Apache 线程将错误日志写入 local0,并且使用进程名称 "myprogram" 而不是 httpd!调用 closelog() 将解决此问题。
[email protected]
5年前
在另一个对象中使用 LOG_ 常量时,当在 Windows 上开发但在 Linux 上部署时,这个问题让我纠结了一段时间。

Windows 将一些 LOG_ 常量评估为相同的值,而 LINUX 则不会。

需要了解的 8 个常量及其在不同平台上的差异

Linux 上这些常量的值为:
========================
LOG_EMERG = 0
LOG_ALERT = 1
LOG_CRIT = 2
LOG_ERR = 3
LOG_WARNING = 4
LOG_NOTICE = 5
LOG_INFO = 6
LOG_DEBUG = 7

而在 Windows 上,则为:
==========================
LOG_EMERG = 1
LOG_ALERT = 1
LOG_CRIT = 1
LOG_ERR = 4
LOG_WARNING = 5
LOG_NOTICE = 6
LOG_INFO = 6
LOG_DEBUG = 6

因此,如果在代码中设置了 LOG_WARNING,Linux 将使用 4 作为优先级,而 Windows 将使用 5。

这并非 PHP 在任何平台上的错误,而是 PHP 编译时使用的系统头文件之间的差异。实际上没有什么可以做的,但请注意,如果您想知道为什么消息在不同平台上的优先级不同,这可能是原因。
[email protected]
9年前
对于那些希望同时写入多个 syslog 设施的人

syslog(LOG_INFO|LOG_LOCAL0, "message for local0");
syslog(LOG_INFO|LOG_LOCAL1, "message for local1");
匿名用户
3年前
手动为消息添加时间戳(如文档示例所示)没有意义,因为所有正常的日志系统都会自己为所有条目添加时间戳。
[email protected]
17 年前
如果您使用的是 syslog-ng 并希望将错误发送到 syslog,则使用 ini 设置 "error_log = syslog" 并将以下内容添加到您的 syslog-ng.conf 中

destination php { file("/var/log/php.log" owner(root) group(devel) perm(0620)); };
log { source(src); filter(f_php); destination(php); };
[email protected]
8年前
当文档说“优先级(按降序排列)”时,它是错误的,因为后面的表格实际上是按**升序**排列的。

例如,我的输出显示
LOG_ERR : 4
LOG_WARNING : 5
LOG_DEBUG : 6

一个重要的区别,给我造成了一些困扰!
[email protected]
21年前
这对我有用,可以将日志重定向到单独的 syslog 文件

将此行放入 /etc/syslog.conf 中

local0.debug /var/log/php.log

然后重新启动 syslogd

/etc/init.d/syslog restart

php 示例

<?php
define_syslog_variables
();
openlog("TextLog", LOG_PID, LOG_LOCAL0);

$data = date("Y/m/d H:i:s");
syslog(LOG_DEBUG,"Messagge: $data");

closelog();
?>
[email protected]
23年前
使用 FreeBSD 我可以使用:syslog(LOG_INFO,"test");

BSD/OS 不支持此功能,我不得不使用优先级的字面值 (158: local3.info)
syslog(158,"test");
[email protected]
21年前
发送到日志文件的消息字符串限制为 500 个字符。
[email protected]
22年前
要通过 syslog 守护进程(在本例中为 FreeBSD)设置自定义日志文件...

在 /etc/syslog.conf 中添加一行,说明 httpd 进程的所有错误都将写入名为(例如)/var/log/httpd-php.log 的文件

!httpd
*.* {tab} /var/log/httpd-php.log

注意制表符,它是制表符字符!接下来创建一个空白文件以写入。我相信有 1e+6 种方法可以做到这一点,但我选择

# cat > httpd-php.log << EOF
? EOF

最后找到您的 syslog 守护进程并向其发送 sighup 以通知它更改

# ps ax | grep syslogd
133 ?? Ss 0:07.23 syslogd -s
# kill -1 133

瞧!Php syslog 调用现在将到达 /var/log/httpd-php.log 中
[email protected]
25年前
在 Windows NT 中,使用以下优先级值
1 = 错误,
6 = 信息
Torsten
20年前
我在尝试使用 Windows XP 下的 IIS 5.1 发出 syslog 消息时遇到问题。函数调用似乎成功了,但事件查看器显示没有创建条目。
最后我发现用于 Web 服务器的用户帐户 (IUSR_<Computername>) 没有足够的权限来发出 syslog 警报。我通过将此用户添加到“用户”组而不是仅“来宾”组来更改此设置。
[email protected]
24年前
对于启用头文件的

man 3 syslog 定义了优先级,但没有定义整数值。为此,您需要阅读您的系统头文件。

假设我想在邮件日志中记录一条信息性消息(这恰好是正确的)。手册页告诉我我想要 LOG_MAIL|LOG_INFO。所以我查看 /usr/include/sys/syslog.h 并找到(这恰好是 Linux,您的系统可能不同)

#define LOG_INFO 6 /* informational */
#define LOG_MAIL (2<<3) /* mail system */

2<<3 表示将 3 位左移,这意味着乘以 8。所以我想要 2*8 + 6 = 22。syslog(22,"this message will appear in the mail log"); 它确实出现了。
To Top