log
啟用並配置 HTTP 請求記錄 (也稱為存取記錄)。
log
指令適用於其出現的站點區塊的主機名稱,除非被 hostnames
子指令覆寫。
配置後,預設情況下將記錄對站點的所有請求。若要有條件地跳過某些請求的記錄,請使用 log_skip
指令。
若要將自訂欄位新增至記錄條目,請使用 log_append
指令。
預設情況下,具有潛在敏感資訊的標頭 (Cookie
、Set-Cookie
、Authorization
和 Proxy-Authorization
) 將在存取記錄中記錄為 REDACTED
。可以使用 log_credentials
全域伺服器選項停用此行為。
語法
log [<logger_name>] {
hostnames <hostnames...>
no_hostname
output <writer_module> ...
format <encoder_module> ...
level <level>
}
-
logger_name 是此站點的記錄器名稱的可選覆寫。
預設情況下,記錄器名稱會自動產生,例如
log0
、log1
等,取決於 Caddyfile 中站點的順序。這僅在您希望從全域選項中定義的另一個記錄器可靠地引用此記錄器的輸出時才有用。請參閱下方的 範例。 -
hostnames 是此記錄器適用的主機名稱的可選覆寫。
預設情況下,記錄器適用於其出現的站點區塊的主機名稱,即站點位址。如果您希望在 萬用字元站點區塊 中為每個子網域定義不同的記錄器,這非常有用。請參閱下方的 範例。
-
no_hostname 防止記錄器與任何站點區塊的主機名稱關聯。預設情況下,記錄器與
log
指令出現的 站點位址 關聯。當您想要根據某些條件 (例如請求路徑或方法) 將請求記錄到不同的檔案時,使用
log_name
指令 非常有用。 -
output 配置寫入記錄的位置。請參閱下方的
output
模組。預設值:
stderr
。 -
format 描述如何編碼或格式化記錄。請參閱下方的
format
模組。預設值:如果檢測到
stderr
為終端機,則為console
,否則為json
。 -
level 是要記錄的最小條目層級。預設值:
INFO
。請注意,存取記錄目前僅發出
INFO
和ERROR
層級記錄。
輸出模組
output 子指令可讓您自訂記錄的寫入位置。
stderr
標準錯誤 (console,為預設值)。
output stderr
stdout
標準輸出 (console)。
output stdout
discard
無輸出。
output discard
file
檔案。預設情況下,記錄檔會輪換 ("rolled") 以防止磁碟空間耗盡。
記錄輪換由 lumberjack 提供
output file <filename> {
mode <mode>
roll_disabled
roll_size <size>
roll_uncompressed
roll_local_time
roll_keep <num>
roll_keep_for <days>
}
-
<filename> 是記錄檔的路徑。
-
mode 是用於記錄檔的 Unix 檔案模式/權限。模式由 1 到 4 個八進制數字組成 (與 Unix chmod
命令接受的數字格式相同,只是全零模式被解釋為預設模式
600
)。例如,644
為記錄檔的所有者提供讀/寫權限,但僅為群組所有者和其他使用者提供讀取權限;600
為記錄檔的所有者提供讀/寫權限,並且不允許其他任何人存取。預設值:
600
-
roll_disabled 停用記錄輪換。這可能會導致磁碟空間耗盡,因此僅在您的記錄檔以其他方式維護時才使用此選項。
-
roll_size 是輪換記錄檔的大小。目前的實作支援兆字節解析度;小數值會向上捨入到下一個整數兆字節。例如,
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
網路通訊端。如果通訊端關閉,它將在嘗試重新連線時將記錄轉儲到 stderr。
output net <address> {
dial_timeout <duration>
soft_start
}
-
<address> 是要寫入記錄的 位址。
-
dial_timeout 是等待成功連線到記錄通訊端的時間長度。如果通訊端關閉,記錄發射可能會被阻止長達此時間。
-
soft_start 將忽略連線到通訊端時的錯誤,即使遠端記錄服務關閉,也允許您載入配置。記錄將改為發射到 stderr。
格式模組
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
。可以是以下之一
s
、second
或seconds
經過的秒數浮點數。ms
、milli
或millis
經過的毫秒數浮點數。ns
、nano
或nanos
經過的奈秒數整數。string
使用 Go 的內建字串格式,例如1m32.05s
或6.31ms
。
-
level_format 層級的格式。
預設值:如果格式預設為
console
,則為color
,否則為lower
。可以是以下之一
lower
小寫。upper
大寫。color
大寫,帶有 ANSI 顏色。
console
console 編碼器格式化記錄條目以提高人類可讀性,同時保留一些結構。
format console
json
將每個記錄條目格式化為 JSON 物件。
format json
filter
允許按欄位篩選。
format filter {
fields {
<field> <filter> ...
}
<field> <filter> ...
wrap <encode_module> ...
}
巢狀欄位可以透過使用 >
表示一層巢狀結構來引用。換句話說,對於像 {"a":{"b":0}}
這樣的物件,內部欄位可以引用為 a>b
。
以下欄位是記錄的基本組成部分,無法篩選,因為它們由底層記錄庫作為特殊情況新增:ts
、level
、logger
和 msg
。
指定 wrap
是可選的;如果省略,則會根據目前的輸出模組是否為 stderr
或 stdout
,以及是否為互動式終端機來選擇預設值,在這種情況下會選擇 console
,否則會選擇 json
。
作為快捷方式,可以省略 fields
區塊,並且可以直接在 filter
區塊中指定篩選器。
這些是可用的篩選器
delete
標記要從編碼中跳過的欄位。
<field> delete
rename
重新命名記錄欄位的鍵。
<field> rename <key>
replace
標記要以編碼時提供的字串替換的欄位。
<field> replace <replacement>
ip_mask
使用 CIDR 遮罩遮罩欄位中的 IP 位址,即從 IP 位址左側開始保留的位元數。如果欄位是字串陣列 (例如 HTTP 標頭),則會遮罩陣列中的每個值。該值可以是逗號分隔的 IP 位址字串。
IPv4 和 IPv6 位址有單獨的配置,因為它們具有不同的總位元數。
最常見的是,要篩選的欄位將是
- 直接連線用戶端的
request>remote_ip
- 配置
trusted_proxies
時,已剖析的 "真實用戶端" 的request>client_ip
- 如果在反向代理後方,則為
request>headers>X-Forwarded-For
<field> ip_mask [<ipv4> [<ipv6>]] {
ipv4 <cidr>
ipv6 <cidr>
}
query
標記要執行一個或多個動作的欄位,以操作 URL 欄位的查詢部分。最常見的是,要篩選的欄位將是 request>uri
。
<field> query {
delete <key>
replace <key> <replacement>
hash <key>
}
可用的動作是
-
delete 從查詢中移除給定的鍵。
-
replace 將給定查詢鍵的值替換為 replacement。適用於插入編輯佔位符;您會看到查詢鍵在 URL 中,但值已隱藏。
-
hash 將給定查詢鍵的值替換為值 SHA-256 雜湊的前 4 個位元組,小寫十六進制。適用於模糊化敏感值,同時能夠注意到每個請求是否具有不同的值。
cookie
標記要執行一個或多個動作的欄位,以操作 Cookie
HTTP 標頭的值。最常見的是,要篩選的欄位將是 request>headers>Cookie
。
<field> cookie {
delete <name>
replace <name> <replacement>
hash <name>
}
可用的動作是
-
delete 從標頭中依名稱移除給定的 Cookie。
-
replace 將給定 Cookie 的值替換為 replacement。適用於插入編輯佔位符;您會看到 Cookie 在標頭中,但值已隱藏。
-
hash 將給定 Cookie 的值替換為值 SHA-256 雜湊的前 4 個位元組,小寫十六進制。適用於模糊化敏感值,同時能夠注意到每個請求是否具有不同的值。
如果為同一個 Cookie 名稱定義了多個動作,則僅會套用第一個動作。
regexp
標記要套用正規表示式替換的欄位,在編碼時。如果欄位是字串陣列 (例如 HTTP 標頭),則每個值都會套用替換。
<field> regexp <pattern> <replacement>
使用的正規表示式語言是 RE2,包含在 Go 中。請參閱 RE2 語法參考 和 Go 正規表示式語法概述。
在替換字串中,可以使用 ${group}
引用捕獲群組,其中 group
是表達式中捕獲群組的名稱或編號。捕獲群組 0
是完整的正規表示式匹配,1
是第一個捕獲群組,2
是第二個捕獲群組,依此類推。
hash
標記要以編碼時值 SHA-256 雜湊的前 4 個位元組 (8 個十六進制字元) 替換的欄位。如果欄位是字串陣列 (例如 HTTP 標頭),則會雜湊陣列中的每個值。
適用於模糊化敏感值,同時能夠注意到每個請求是否具有不同的值。
<field> hash
append
將欄位附加到所有記錄條目。
format append {
fields {
<field> <value>
}
<field> <value>
wrap <encode_module> ...
}
它最適用於新增有關產生記錄條目的 Caddy 實例的資訊,可能透過環境變數。欄位值可以是全域佔位符 (例如 {env.*}
),但不是每個請求的佔位符,因為記錄是在 HTTP 請求上下文之外寫入的。
指定 wrap
是可選的;如果省略,則會根據目前的輸出模組是否為 stderr
或 stdout
,以及是否為互動式終端機來選擇預設值,在這種情況下會選擇 console
,否則會選擇 json
。
可以省略 fields
區塊,並且可以直接在 append
區塊中指定欄位。
範例
啟用預設記錄器的存取記錄。
換句話說,預設情況下,這會記錄到 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 {
request>headers>User-Agent delete
}
}
}
編輯多個敏感 Cookie。(請注意,某些敏感標頭預設會以空值記錄;請參閱 log_credentials
全域選項 以啟用記錄 Cookie
標頭值)
example.com {
log {
format filter {
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 {
request>remote_ip ip_mask 16 32
request>client_ip ip_mask 16 32
}
}
}
若要將來自環境變數的伺服器 ID 附加到所有記錄條目,並將其與 filter
鏈接以刪除標頭
example.com {
log {
format append {
server_id {env.SERVER_ID}
wrap filter {
request>headers>Cookie delete
}
}
}
}
若要在 萬用字元站點區塊 中為每個子網域寫入單獨的記錄檔,方法是覆寫每個記錄器的 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
}