log
啟用並設定 HTTP 要求記錄(也稱為存取記錄)。
log
指令套用於其所出現的網站區塊的主機名稱,除非使用 hostnames
子指令覆寫。
設定後,預設會記錄對網站的所有要求。若要根據條件略過一些要求的記錄,請使用 skip_log
指令。
從 Caddy v2.5 起,預設會將具有潛在敏感資訊的標頭(Cookie
、Set-Cookie
、Authorization
和 Proxy-Authorization
)記錄為空值。此行為可以使用 log_credentials
全域伺服器選項停用。
語法
log [<logger_name>] {
hostnames <hostnames...>
output <writer_module> ...
format <encoder_module> ...
level <level>
}
-
logger_name 是此網站記錄器名稱的選用覆寫。
預設會自動產生記錄器名稱,例如
log0
、log1
,依 Caddyfile 中網站的順序而定。這只在您希望從全域選項中定義的其他記錄器可靠地參照此記錄器的輸出時才有用。請參閱以下 範例。 -
hostnames 是此記錄器套用的主機名稱的選用覆寫。
預設情況下,記錄器套用於它出現在其中的網站區塊的主機名稱,也就是網站地址。如果您希望在 萬用字元網站區塊 中為每個子網域定義不同的記錄器,這將很有用。請參閱以下 範例。
-
output 設定要將記錄寫入何處。請參閱以下
output
模組。預設值:
stderr
。 -
format 描述如何編碼或格式化記錄。請參閱以下
format
模組。預設值:如果偵測到
stderr
是終端機,則為console
,否則為json
。 -
level 是要記錄的最低輸入層級。預設值:
INFO
。請注意,目前存取記錄僅發出
INFO
和ERROR
層級記錄。
輸出模組
output 子指令讓您可以自訂記錄寫入的位置。
stderr
標準錯誤(終端機,為預設值)。
output stderr
stdout
標準輸出(終端機)。
output stdout
discard
無輸出。
output discard
file
檔案。預設情況下,記錄檔會輪替(「滾動」)以防止磁碟空間耗盡。
記錄滾動由 lumberjack 提供
output file <filename> {
roll_disabled
roll_size <size>
roll_uncompressed
roll_local_time
roll_keep <num>
roll_keep_for <days>
}
-
<filename> 是記錄檔的路徑。
-
roll_disabled 停用記錄滾動。這可能會導致磁碟空間耗盡,因此只有在您的記錄檔以其他方式維護時才使用此選項。
-
roll_size 是記錄檔滾動的大小。目前的實作支援以 MB 為單位;小數值會向上取整到下一個整數 MB。例如,
1.1MiB
會向上取整到2MiB
。預設值:
100MiB
-
roll_uncompressed 關閉 gzip 記錄壓縮。
預設值:啟用 gzip 壓縮。
-
roll_local_time 設定滾動在檔名中使用當地時間戳記。
預設值:使用 UTC 時間。
-
roll_keep 是在刪除最舊的記錄檔之前要保留的記錄檔數量。
預設值:
10
-
roll_keep_for 是以 持續時間字串 為單位保留滾動檔案的時間長度。目前的實作支援以天為單位;小數值會向上取整到下一個整數天。例如,
36h
(1.5 天)會向上取整到48h
(2 天)。預設值:2160h
(90 天)
net
網路插座。如果插座斷線,它會在嘗試重新連線時將記錄傾印到標準錯誤輸出。
output net <address> {
dial_timeout <duration>
soft_start
}
-
<address> 是要寫入記錄的 地址。
-
dial_timeout 是等待與記錄插座建立成功連線的時間長度。如果插座斷線,記錄發射可能會被封鎖長達此時間長度。
-
soft_start 會在連線到插座時忽略錯誤,讓您即使遠端記錄服務已斷線,也能載入您的設定檔。記錄會改發射到標準錯誤輸出。
格式模組
format 子指令讓您自訂記錄編碼 (格式化) 的方式。它出現在 log
區塊中。
除了每個個別編碼器的語法外,這些常見屬性也可以設定在大部分的編碼器上
format <encoder_module> {
message_key <key>
level_key <key>
time_key <key>
name_key <key>
caller_key <key>
stacktrace_key <key>
line_ending <char>
time_format <format>
time_local
duration_format <format>
level_format <format>
}
-
message_key 記錄條目訊息欄位的鍵。預設值:
msg
-
level_key 記錄條目層級欄位的鍵。預設值:
level
-
time_key 記錄條目時間欄位的鍵。預設值:
ts
-
name_key 記錄條目名稱欄位的鍵。預設值:
name
-
caller_key 記錄條目呼叫者欄位的鍵。
-
stacktrace_key 記錄條目堆疊追蹤欄位的鍵。
-
line_ending 要使用的換行符號。
-
time_format 時間戳記的格式。
預設值:如果格式預設為
console
,則為wall_milli
,否則為unix_seconds_float
。可能是下列其中之一
unix_seconds_float
自 Unix 紀元以來的浮點秒數。unix_milli_float
自 Unix 紀元以來的浮點毫秒數。unix_nano
自 Unix 紀元以來的整數奈秒數。iso8601
範例:2006-01-02T15:04:05.000Z0700
rfc3339
範例:2006-01-02T15:04:05Z07:00
rfc3339_nano
範例:2006-01-02T15:04:05.999999999Z07:00
wall
範例:2006/01/02 15:04:05
wall_milli
範例:2006/01/02 15:04:05.000
wall_nano
範例:2006/01/02 15:04:05.000000000
common_log
範例:02/Jan/2006:15:04:05 -0700
- 或者,任何相容的時間配置字串;請參閱 Go 文件 以取得完整詳細資訊。
請注意,格式字串的部分是配置的特殊常數;因此,
2006
是年份,01
是月份,Jan
是字串形式的月份,02
是日期。請勿在格式字串中使用實際的目前日期數字。 -
time_local 記錄使用當地系統時間,而非預設的 UTC 時間。
-
duration_format 時間間隔的格式。
預設值:
seconds
。可能是下列其中之一
seconds
已經過的秒數浮點數。nano
已經過的奈秒數整數。string
使用 Go 內建的字串格式,例如1m32.05s
或6.31ms
。
-
level_format 層級的格式。
預設值:如果格式預設為
console
,則為color
,否則為lower
。可能是下列其中之一
lower
小寫。upper
大寫。color
大寫,帶有 ANSI 色彩。
console
主控台編碼器會將日誌條目格式化為人類可讀的格式,同時保留一些結構。
format console
json
將每個日誌條目格式化為 JSON 物件。
format json
filter
包裝另一個編碼器模組,允許每個欄位進行篩選。
format filter {
wrap <encode_module> ...
fields {
<field> <filter> ...
}
}
巢狀欄位可以透過使用 >
來表示一層巢狀結構來參照。換句話說,對於像 {"a":{"b":0}}
這樣的物件,內部欄位可以參照為 a>b
。
下列欄位是日誌的基本組成,且無法篩選,因為它們是由底層記錄函式庫作為特殊案例新增的:ts
、level
、logger
和 msg
。
以下是可用的篩選條件
delete
標記一個欄位,使其在編碼時略過。
<field> delete
rename
重新命名日誌欄位的金鑰。
<field> rename <key>
replace
標記一個欄位,使其在編碼時以提供的字串取代。
<field> replace <replacement>
ip_mask
使用 CIDR 遮罩來遮蔽欄位中的 IP 位址,也就是從左側開始保留 IP 中的位元數。如果欄位是字串陣列(例如 HTTP 標頭),陣列中的每個值都會被遮蔽。這個值可以是 IP 位址的逗號分隔字串。
IPv4 和 IPv6 位址有不同的總位元數,因此它們有各自的設定。
最常見的篩選欄位為
request>remote_ip
給直接連線的用戶端request>client_ip
給解析後的「真實用戶端」當trusted_proxies
已設定request>headers>X-Forwarded-For
如果在反向代理之後
<field> ip_mask {
ipv4 <cidr>
ipv6 <cidr>
}
query
標記一個欄位來執行一個或多個動作,以處理 URL 欄位的查詢部分。最常見的,要過濾的欄位會是 request>uri
。
<field> query {
delete <key>
replace <key> <replacement>
hash <key>
}
可用的動作有
-
delete 從查詢中移除給定的金鑰。
-
replace 用 replacement 取代給定查詢金鑰的值。用於插入一個編輯佔位符;你會看到查詢金鑰在 URL 中,但值是隱藏的。
-
hash 用值的 SHA-256 hash 的前 4 個位元組取代給定查詢金鑰的值,小寫十六進位。用於模糊值(如果它很敏感),同時能夠注意到每個請求是否具有不同的值。
cookie
標記一個欄位來執行一個或多個動作,以處理 Cookie
HTTP 標頭的值。最常見的,要過濾的欄位會是 request>headers>Cookie
。
<field> cookie {
delete <name>
replace <name> <replacement>
hash <name>
}
可用的動作有
-
delete 從標頭中透過名稱移除給定的 cookie。
-
replace 用 replacement 取代給定 cookie 的值。用於插入一個編輯佔位符;你會看到 cookie 在標頭中,但值是隱藏的。
-
hash 用值的 SHA-256 hash 的前 4 個位元組取代給定 cookie 的值,小寫十六進位。用於模糊值(如果它很敏感),同時能夠注意到每個請求是否具有不同的值。
如果為同一個 cookie 名稱定義了許多動作,只會套用第一個動作。
regexp
標記一個欄位在編碼時套用正規表示式替換。如果欄位是一個字串陣列(例如 HTTP 標頭),陣列中的每個值都會套用替換。
<field> regexp <pattern> <replacement>
使用的正規表示式語言是 RE2,包含在 Go 中。請參閱 RE2 語法參考 和 Go regexp 語法概述。
在替換字串中,擷取群組可以用 ${group}
參照,其中 group
是表示式中擷取群組的名稱或數字。擷取群組 0
是完整的 regexp 匹配,1
是第一個擷取群組,2
是第二個擷取群組,依此類推。
hash
標記一個欄位在編碼時用值的 SHA-256 hash 的前 4 個位元組(8 個十六進位字元)替換。如果欄位是一個字串陣列(例如 HTTP 標頭),陣列中的每個值都會被雜湊。
用於模糊值(如果它很敏感),同時能夠注意到每個請求是否具有不同的值。
<field> hash
範例
啟用存取記錄到預設記錄器。
換句話說,預設情況下,這會記錄到 stderr
,但可以透過使用 log
全域選項 重新設定 default
記錄器來變更
example.com {
log
}
將記錄寫入檔案(預設啟用記錄輪動)
example.com {
log {
output file /var/log/access.log
}
}
自訂記錄輪動
example.com {
log {
output file /var/log/access.log {
roll_size 1gb
roll_keep 5
roll_keep_for 720h
}
}
}
從記錄中刪除 User-Agent
要求標頭
example.com {
log {
format filter {
wrap console
fields {
request>headers>User-Agent delete
}
}
}
}
塗銷多個敏感 cookie。(請注意,預設情況下,某些敏感標頭會記錄為空值;請參閱 log_credentials
全域選項 以啟用記錄 Cookie
標頭值)
example.com {
log {
format filter {
wrap console
fields {
request>headers>Cookie cookie {
replace session REDACTED
delete secret
}
}
}
}
}
遮罩要求中的遠端位址,保留 IPv4 位址的前 16 位元(例如 255.255.0.0),以及 IPv6 位址的前 32 位元。
請注意,從 Caddy v2.7 開始,remote_ip
和 client_ip
都會記錄,其中 client_ip
是在設定 trusted_proxies
時的「真實 IP」
example.com {
log {
format filter {
wrap console
fields {
request>remote_ip ip_mask {
ipv4 16
ipv6 32
}
}
}
}
}
透過覆寫每個記錄器的 hostnames
,為 萬用字元網站區塊 中的每個子網域撰寫個別記錄檔。這會使用 片段 來避免重複
(subdomain-log) {
log {
hostnames {args[0]}
output file /var/log/{args[0]}.log
}
}
*.example.com {
import subdomain-log foo.example.com
@foo host foo.example.com
handle @foo {
respond "foo"
}
import subdomain-log bar.example.com
@bar host bar.example.com
handle @bar {
respond "bar"
}
}
將特定子網域的存取記錄寫入兩個不同的檔案,並採用不同的格式(一個使用 transform-encoder
外掛程式 ,另一個使用
json
)。
這會透過在網站區塊中將記錄器名稱覆寫為 foo
,然後在全域選項中包含由該記錄器產生的存取記錄,並使用 include http.log.access.foo
{
log access-formatted {
include http.log.access.foo
output file /var/log/access-foo.log
format transform "{common_log}"
}
log access-json {
include http.log.access.foo
output file /var/log/access-foo.json
format json
}
}
foo.example.com {
log foo
}