PHP Conference Japan 2024

syslog

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

syslog產生系統日誌訊息

說明

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

syslog() 產生一個由系統記錄器分發的日誌訊息。

關於設定使用者自定義日誌處理程式的資訊,請參閱 Unix 手冊頁的 syslog.conf (5)。更多關於 syslog 功能和選項的資訊可以在 Unix 機器上的 syslog (3) 的手冊頁中找到。

參數

優先權 (priority)

下列其中一個常數:LOG_EMERGLOG_ALERTLOG_CRITLOG_ERRLOG_WARNINGLOG_NOTICELOG_INFOLOG_DEBUG

訊息

要傳送的訊息。

回傳值

永遠回傳 true

範例

範例 #1 使用 syslog()

<?php
// 開啟系統日誌,包含程序 ID 並將日誌
// 傳送到標準錯誤輸出,並使用使用者自訂的
// 記錄機制
openlog("myScriptLog", LOG_PID | LOG_PERROR, LOG_LOCAL0);

// 一些程式碼

if (authorized_client()) {
// 做一些事
} else {
// 未經授權的客戶端!
// 記錄嘗試
$access = date("Y/m/d H:i:s");
syslog(LOG_WARNING, "未經授權的客戶端: $access {$_SERVER['REMOTE_ADDR']} ({$_SERVER['HTTP_USER_AGENT']})");
}

closelog();
?>

注意事項

在 Windows 上,系統日誌服務是使用事件記錄檔來模擬的。

注意:

在 Windows 中,openlog()facility 參數無法使用 LOG_LOCAL0LOG_LOCAL7

參見

新增筆記

使用者貢獻的筆記 16 則筆記

james dot ellis at gmail dot com
17 年前
如果有人想知道為什麼他們的日誌訊息會出現在多個日誌檔中,以下是一個適用於 *nix 系統的答案

如果您的 syslog.conf 看起來像這樣(假設您使用 LOG_LOCAL0 進行網路應用程式記錄)

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 傳送到記錄 socket 的原始訊息,請先停止您的 syslog/rsyslog/ng-syslog 服務,然後使用 netcat-openbsd 套件監聽記錄 socket:

nc -U -l /dev/log

現在,從 PHP 記錄一些訊息:

<?php
syslog
(LOG_LOCAL1|LOG_INFO, "來自 PHP 的測試訊息");
?>

您將會在 netcat 中看到 rfc3164 格式的輸出:

<142>Oct 24 14:32:51 php: 來自 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 執行緒接受多個請求,則 *必須* 呼叫 closelog(),前提是 Apache 的錯誤日誌設定為寫入 syslog。否則將導致 Apache 的錯誤日誌寫入到 openlog() 中使用的 facility/ident。

例如,在 httpd.conf 中,您設定了:

ErrorLog syslog:local7

然後在 PHP 中,您執行了:

<?php
openlog
("myprogram", 0, LOG_LOCAL0);
syslog("我的系統日誌訊息");
?>

從現在開始,這個 Apache 執行緒將會把錯誤日誌寫入到 local0,程序名稱為 "myprogram",而不是 httpd!呼叫 closelog() 可以解決這個問題。
rgagnon24 at gmail dot com
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 編譯時所使用的系統標頭檔的差異。您並不能真正做些什麼,但如果您想知道為什麼您的訊息在不同平台上以不同優先級記錄,請注意這可能是原因。
huangyg11 at gmail dot com
9 年前
對於想要同時寫入多個系統日誌設備的人

syslog(LOG_INFO|LOG_LOCAL0, "給 local0 的訊息");
syslog(LOG_INFO|LOG_LOCAL1, "給 local1 的訊息");
匿名
3 年前
手動為訊息加上時間戳記(如文件範例所示)沒有意義,因為所有正常的日誌系統都會自行為所有條目加上時間戳記。
helly at php dot net
17 年前
如果您正在使用 syslog-ng 並且希望錯誤發送到系統日誌,請使用 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); };
antoine dot leverve dot EXT at zodiacaerospace dot com
8 年前
文件說「優先級(降冪排列)」是不正確的,因為後面的表格實際上是**升冪**排列。

例如,我的輸出顯示
LOG_ERR : 4
LOG_WARNING : 5
LOG_DEBUG : 6

一個重要的區別,這讓我吃了不少苦頭!
daniele dot patoner at biblio dot unitn dot it
21 年前
這對我來說有效,可以將日誌重定向到單獨的系統日誌檔案

將此行放入您的 /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,"訊息: $data");

closelog();
?>
mavetju at chello dot nl
23 年前
在 FreeBSD 中,我可以使用:syslog(LOG_INFO,"test");

BSD/OS 不支援這個,我必須使用優先級的字面值 (158: local3.info)
syslog(158,"test");
gregj at pdxperts dot com
21 年前
發送到日誌檔的訊息字串限制為 500 個字元。
dpreece at paradise dot net dot nz
22 年前
要透過系統日誌守護程式設定自訂日誌檔(在本例中為 FreeBSD)...

在 /etc/syslog.conf 中新增一行,表示來自 httpd 程序的所有錯誤都將寫入名為(例如)/var/log/httpd-php.log 的檔案

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

請注意 tab,它是一個定位字元!接下來建立一個要寫入的空白檔案。我相信有 1e+6 種方法可以做到這一點,但我選擇

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

最後找到您的系統日誌守護程式並向其發送一個 sighup 以通知它更改

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

瞧!現在 PHP syslog 呼叫的紀錄會出現在 /var/log/httpd-php.log 裡了。
bb at lb-data dot co dot at
25 年前
在 Windows NT 中,請使用以下的優先權值:
1 = 錯誤
6 = 資訊
Torsten
20 年前
我在 Windows XP 上使用 IIS 5.1 發送 syslog 訊息時遇到問題。函式呼叫看似成功,但事件檢視器卻沒有顯示任何記錄。
最後我發現,用於網路伺服器的使用者帳戶 (IUSR_<電腦名稱>) 沒有足夠的權限發送 syslog 警示。我將這個使用者從 Guest 群組新增到 Users 群組,解決了這個問題。
rcgraves+php at brandeis dot edu
24 年前
關於標頭檔

`man 3 syslog` 定義了優先權,但沒有定義整數值。您需要閱讀系統標頭檔才能找到這些值。

假設我想在郵件日誌中記錄一條資訊訊息(這剛好是真的)。man 頁面告訴我需要使用 LOG_MAIL|LOG_INFO。因此,我在 /usr/include/sys/syslog.h 中查找(這剛好是 Linux 系統,您的系統可能不同):

#define LOG_INFO 6 /* 資訊 */
#define LOG_MAIL (2<<3) /* 郵件系統 */

2<<3 表示向左位移 3 位元,也就是乘以 8。所以我需要 2*8 + 6 = 22。`syslog(22,"這條訊息會出現在郵件日誌中");` 確實如此。
To Top