單一 VPS 自架日誌管理的 RAM 與保留規則
比較 journald、logrotate、Loki 與 OpenSearch 在單一 VPS 上的實際需求,說明 12 GB RAM 建議何時過高,以及保留規則如何決定成本。
單一 VPS 上自架日誌管理的實際成本
在單一 VPS(virtual private server)上自架日誌管理,關鍵只有一個問題:你需要搜尋叢集,還是只需要輪替與 grep?多數廠商指南會先從 3 個節點和 12 GB RAM 開始,甚至還沒送出第一行日誌。在單一伺服器上,這種答案沒有用處,因此以下比較的是各選項在尚未儲存任何內容前,對小型主機的要求。
如果你只執行 1 或 2 台伺服器,並且只想知道上週二發生了什麼,systemd-journald 和 logrotate 已經能完成這項工作,讀完下一節即可停止。如果必須將多台機器的日誌集中到同一處,並搜尋數週內的內容,Grafana Loki 適合小型主機,因為它會為標籤建立索引,而不是為每行文字建立索引。Elasticsearch 和 OpenSearch 提供真正的全文搜尋,但會以記憶體消耗作為代價,因為 JVM(Java virtual machine)heap 有無法低於的最低值。
從 journald 開始,因為大多數人處理到這裡就足夠了
systemd-journald 已在目前的 Ubuntu 或 Debian 伺服器上執行。它會擷取每個服務單元的標準輸出、核心訊息,以及所有送往 syslog 的內容。以下 4 個命令涵蓋大多數事件。
journalctl -u nginx.service --since "2026-08-14 09:00" --until "2026-08-14 10:00"
journalctl -p err -b
journalctl -f -u ssh.service
journalctl --disk-usage最後一個命令會輸出類似 Archived and active journals take up 1.1G in the file system. 的行。這個數值決定你是否還需要其他處理。如果大小只有幾百 MB,而且你能使用 -u 與 --since 找到所需內容,就不必再做其他設定。
journal 是否能在重新開機後保留,取決於 Storage=,以及 /var/log/journal 是否存在。在常見的 Storage=auto 設定下,當該目錄存在時,journald 會將資料寫入 /var/log/journal;目錄不存在時,則寫入 /run/log/journal。/run 是由記憶體支援的檔案系統,因此沒有該目錄的伺服器會在重新開機時刪除所有日誌,而這正是你想讀取這些日誌的時機。Ubuntu 映像檔會提供該目錄。精簡映像檔與以容器為基礎的映像檔通常不會提供。
ls -d /var/log/journal
sudo mkdir -p /var/log/journal
sudo systemctl restart systemd-journald
journalctl --disk-usage重新啟動後,journalctl --disk-usage 應回報低於 /var/log/journal 的大小,而不是 /run。預設值本身已有大小上限,這也是 journald 能正式解決問題,而不只是備援方案的主要原因。journald.conf man page 將 SystemMaxUse= 設為檔案系統大小的 10%,將 SystemKeepFree= 設為 15%,並將每個計算出的預設值上限設為 4G。SystemMaxFileSize= 預設為 SystemMaxUse= 的八分之一,上限為 128M,因此通常會保留 7 個輪替檔案。MaxRetentionSec= 預設為 0,會停用依檔案存留時間刪除的功能。請再次注意最後一個預設值:journal 在開箱即用的情況下只受大小限制,完全不受存留時間限制。
[Journal]
Storage=persistent
SystemMaxUse=2G
MaxRetentionSec=30day將設定寫入 /etc/systemd/journald.conf.d/99-size.conf,重新啟動 journald,然後確認 journalctl --disk-usage 是否逐漸接近新的上限。若要立即回收空間,而不是等到下一次輪替,請執行 sudo journalctl --vacuum-size=500M 或 sudo journalctl --vacuum-time=14d。兩者都會列出每個刪除的檔案,因此命令執行後沒有輸出,表示沒有檔案可刪除。
journal 以外的內容,例如 /var/log/nginx/access.log,由 logrotate 負責處理,而它每天會透過 systemd timer 執行。有一個問題值得了解,因為它看起來像是 df 的錯誤。輪替後,舊檔案會從目錄清單中消失,但 daemon 仍保持檔案開啟,因此 df -h 會回報磁碟已滿,而 du -sh /var/log 回報的使用量卻低得多。只有程序重新開啟其日誌後,空間才會釋放;設定檔中的 postrotate reload 行就是用於此目的。sudo lsof -nP +L1 會列出已刪除但仍保持開啟的檔案,並顯示持有每個檔案的程序。使用 sudo logrotate -d /etc/logrotate.d/nginx 可在不變更任何內容的情況下測試規則。
將多台伺服器的日誌傳送至單一收集器
當伺服器不只一台時,同時管理多台 Linux 伺服器會更容易,因為所有日誌都會集中到同一處。大多數發行版已預先安裝 rsyslog,因此最簡單的中央收集器做法,是在每台傳送端使用同一個檔案。
*.* action(type="omfwd" target="logs.example.com" port="514" protocol="tcp")將內容儲存為 /etc/rsyslog.d/50-forward.conf,再使用 sudo rsyslogd -N1 檢查。此命令會驗證設定並結束,不會啟動任何服務。接著重新啟動 rsyslog。在收集器上,啟用 TCP 輸入。
module(load="imtcp")
input(type="imtcp" port="514")請注意兩個機械性問題。一般 syslog 不提供加密或驗證,因此任何能連線至 514 埠的主機,都能注入看起來與原始日誌完全相同的內容。請將它綁定至私有網路或 VPN,並對該埠設定防火牆規則。其次,預設的 action queue 位於記憶體中。當收集器無法連線時,佇列會填滿,訊息也會遭到捨棄,且不會保留副本。rsyslog 在其可靠轉送教學中,說明了此情況適用的磁碟輔助佇列。
為何 ELK stack 不適合小型 VPS
ELK 代表 Elasticsearch(用於儲存與搜尋)、Logstash(用於輸入管線)及 Kibana(用於介面)。最低需求是 JVM heap,而且在任何日誌到達前就已設定。
Elastic 的文件建議,將每個 Elasticsearch node 的 heap 設為可用總記憶體的 50% 以下,因為程序也會使用 off-heap buffer,並依賴作業系統的 file cache 快速讀取 index 檔案。因此,2 GB heap 代表至少需要 4 GB 機器,還沒計入 Kibana,也還沒計入該伺服器實際要執行的服務。Elastic 也表示,Elasticsearch 會根據 node 的角色與總記憶體自動決定 heap 大小。這表示小型主機只能取得小型 heap,之後大部分時間都在執行 garbage collection。
Logstash 會直接耗盡小型主機的資源預算。Elastic 自己的 JVM 設定頁面建議,典型輸入處理的 heap 不得低於 4GB,也不得高於 8GB。這已經是 4 GB VPS 的全部記憶體,而且只供管線中間的一個程序使用。
The data behind this chart
[
{
"label": "Loki plus Alloy (no JVM)",
"documented_heap_mb": 0
},
{
"label": "OpenSearch demo compose",
"documented_heap_mb": 512
},
{
"label": "OpenSearch production example",
"documented_heap_mb": 2048
},
{
"label": "Logstash recommended minimum",
"documented_heap_mb": 4096
}
]這些是各專案在自有文件中公布的數值。它們不是在測試主機上量測的結果,實際工作負載可能使數值改變。OpenSearch 的範例 compose 檔案在示範環境中,為每個 node 設定 512 MB;在 production 範例中則設定 2048 MB,而 Logstash 建議的下限是 4096 MB。Loki 和 Alloy 的 heap 欄位顯示 0,因為它們是 Go 程式,不需要保留 JVM heap。這個數字就說明了全部差異:無論是否有日誌到達,JVM 元件都會保留這段記憶體。
如果仍要在一台小型伺服器上使用 Elastic stack,請移除 Logstash,改用輕量級 collector 直接將資料送入 Elasticsearch。Logstash 的用途是在大量資料下進行剖析與轉換;在單一主機上,可以將這些工作移至邊緣端,或直接略過。
Elasticsearch 和 OpenSearch 也需要將 vm.max_map_count 調高至 262144,因為它們會對 index 檔案使用 memory map,而 Linux 的預設限制過低。全新主機上的 container 若在啟動數秒後退出,通常就是這個原因,沒有其他問題。
OpenSearch 或 Elasticsearch:你可以部署哪一個?
先簡述授權歷史,因為這決定你獲准執行的內容。2021 年 1 月,Elastic 將 Elasticsearch 和 Kibana 從 Apache 2.0 改為 SSPL(server side public license)與 Elastic License 2.0 雙重授權模式。AWS 將最後一版 Apache 2.0 程式碼分支為 OpenSearch,並維持 Apache 2.0 授權。2024 年 9 月,Elastic 另加入 AGPLv3(GNU Affero General Public License version 3),作為免費原始碼的另一種授權選項。對於在單一 VPS 上自行託管、僅供一人使用的情境,這些授權都允許你的使用方式。當你將軟體作為代管服務提供給其他人時,授權限制才會產生影響。
在小型主機上,實際差異比這段歷史顯示的更小,因為兩者底層使用的是相同引擎。名稱有所不同:OpenSearch 使用 ISM(index state management),Elasticsearch 使用 ILM(index lifecycle management)。截至 2026 年 8 月,OpenSearch 2.12 及更新版本在首次執行時若未設定 admin 密碼,將拒絕啟動。
sudo sysctl -w vm.max_map_count=262144
printf 'vm.max_map_count = 262144\n' | sudo tee /etc/sysctl.d/99-opensearch.conf
docker run -d -p 9200:9200 -p 9600:9600 -e "discovery.type=single-node" \
-e "OPENSEARCH_INITIAL_ADMIN_PASSWORD=<custom-admin-password>" \
opensearchproject/opensearch:latestsysctl -w 這一行會立即套用設定,而 /etc/sysctl.d/ 中的檔案內容則負責讓設定在重新開機後保留。使用 curl -k -u admin:<password> https://localhost:9200 確認容器已啟動。它會使用示範憑證透過 https 回應,因此 -k 會略過驗證;健康檢查成功時,會回傳一小段 JSON,其中包含叢集名稱與版本。OpenSearch 安裝頁面也提醒 Docker Desktop 使用者,至少要讓主機提供 4 GB 記憶體。這足以反映該程序預期可使用的資源量。
Loki 如何維持精簡:使用標籤,而不是完整文字索引
Loki 只針對標籤建立一份索引,並將日誌行儲存為壓縮區塊。查詢會先選取串流,再篩選文字。{unit="ssh.service"} |= "Failed password" 會依據標籤選取串流,接著掃描這些區塊中的字串。系統不會為日誌行的內容建立索引,因此資料寫入成本較低,也不需要在記憶體中維護反向索引。成本會轉移到查詢時間;如果你通常知道要查看哪個服務,這樣的取捨很合理。
Grafana 的文件指出,單體模式,也就是讓 Loki 全部在單一程序中搭配 -target=all 執行,適合每天約 20GB 以下的小型讀寫量。單一 VPS 通常遠低於這個規模。
需要注意的是標籤基數。每一種不同的標籤值組合都是一個串流,而串流數量會影響 Loki 的記憶體與索引大小。若標籤存放用戶端 IP 位址或請求識別碼,每個值都會建立一個串流;因此,忙碌的 Web 伺服器一天可能產生數萬個串流,程序會持續成長,直到 kernel 終止它。標籤應只使用可直接列在紙上的值,例如 unit、host、job、level。可變動的詳細資訊應放在日誌行本身,讓篩選運算式在查詢時尋找。
在同一台 VPS 上安裝 Loki 和 Alloy
這項工作由兩個程序負責。Loki 儲存日誌並處理查詢。Grafana Alloy 讀取日誌並將其推送到 Loki。過去負責傳送日誌的是 Promtail,但它已於 2 March 2026 終止生命週期,因此新的安裝應使用 Alloy;Loki 自己的 Docker 範例現在也隨附 Alloy 設定。
wget https://raw.githubusercontent.com/grafana/loki/v3.7.0/cmd/loki/loki-local-config.yaml -O loki-config.yaml使用前先讀取該檔案。它會在 /tmp/loki/chunks 下方設定 path_prefix: /tmp/loki,這對示範環境正確,但不適合伺服器:容器的 /tmp 下方沒有任何資料能在容器重新建立後保留,因此下次更新映像檔時,歷史資料就會消失。請將它指向掛載的路徑。
common:
instance_addr: 127.0.0.1
path_prefix: /loki
storage:
filesystem:
chunks_directory: /loki/chunks
rules_directory: /loki/rules
replication_factor: 1
ring:
kvstore:
store: inmemorydocker volume create loki-data
docker run --name loki -d \
-v $(pwd):/mnt/config -v loki-data:/loki \
-p 127.0.0.1:3100:3100 \
grafana/loki:3.7.0 -config.file=/mnt/config/loki-config.yaml
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3100/ready最後一個指令應輸出 200,因為 Loki 準備好接受網路流量後,/ready 會回傳 HTTP 200。其他結果表示程序仍在啟動,或設定遭到拒絕;docker logs loki 會指出原因。執行指令中的兩個細節是刻意設定的。連接埠只發布到 127.0.0.1,因為範例設定包含 auth_enabled: false,而 Loki 本身不提供使用者驗證。因此,任何能連到 port 3100 的人都能讀取所有日誌,也能寫入偽造的日誌。請將它限制在 loopback,或放在 VPN 或具備驗證功能的反向代理後方。具名 volume 很重要,因為映像檔會以 loki 使用者及 UID 10001 執行。因此,若主機上的 bind mount 目錄由 root 擁有,容器將無法寫入。
sudo apt-get update && sudo apt-get install -y gpg wget
sudo mkdir -p /etc/apt/keyrings/
sudo wget -O /etc/apt/keyrings/grafana.asc https://apt.grafana.com/gpg-full.key
echo "deb [signed-by=/etc/apt/keyrings/grafana.asc] https://apt.grafana.com stable main" \
| sudo tee /etc/apt/sources.list.d/grafana.list
sudo apt-get update
sudo apt-get install -y alloyAlloy 會讀取 /etc/alloy/config.alloy。此設定會讀取 system journal 和一組檔案,並將兩者推送到本機 Loki。
loki.write "local" {
endpoint {
url = "http://127.0.0.1:3100/loki/api/v1/push"
}
}
loki.relabel "journal" {
forward_to = []
rule {
source_labels = ["__journal__systemd_unit"]
target_label = "unit"
}
}
loki.source.journal "read" {
forward_to = [loki.write.local.receiver]
relabel_rules = loki.relabel.journal.rules
labels = {job = "systemd-journal", host = "app-01"}
}
local.file_match "nginx" {
path_targets = [{"__path__" = "/var/log/nginx/*.log", "job" = "nginx", "host" = "app-01"}]
}
loki.source.file "nginx" {
targets = local.file_match.nginx.targets
forward_to = [loki.write.local.receiver]
}這項 relabel 規則會將 journal 欄位 __journal__systemd_unit 複製到名為 unit 的 label,之後 {unit="ssh.service"} 才能運作。沒有這項規則時,unit 名稱會位於日誌項目內,而不是 label 中。因此無法依 unit 名稱篩選,每次查詢都必須掃描所有資料。
sudo systemctl reload alloy
systemctl show -p User alloy
sudo journalctl -n 5
sudo -u alloy journalctl -n 5大多數安裝會卡在這裡。Alloy 會以自己的服務帳號執行,而不是 root。讀取 system journal 需要加入 systemd-journal 群組;在 Debian 和 Ubuntu 上,/var/log/nginx 下的檔案則屬於 adm 群組。將上一個指令輸出的帳號代入最後一個指令中的 systemctl show。如果回傳的項目遠少於以 root 執行時的結果,表示該帳號無法讀取 system journal。即使設定完全正確,Loki 仍會保持空白。加入這些群組,然後先執行 sudo usermod -aG systemd-journal,adm alloy,再執行 sudo systemctl restart alloy 重新啟動。
curl -G -s "http://127.0.0.1:3100/loki/api/v1/query_range" \
--data-urlencode 'query={job="systemd-journal"}' \
--data-urlencode 'limit=5' | jq '.data.result | length'大於 0 的數字表示存在具有該 label 的 stream,且其中包含日誌項目。0 表示目前尚未有任何資料以該 label 傳入。有一項預設值常會造成誤判:loki.source.journal 會將 max_age 設為 7h,因此全新啟動時只會讀取 journal 最近 7 小時的內容,不會讀取更早的資料。若要使用圖形介面,請在同一台主機上執行 Grafana,並將 Loki 資料來源指向 http://127.0.0.1:3100.。容器日誌需要不同的資料來源:Alloy 會探索執行中的 Docker 容器並持續讀取其日誌,這也是 Loki 自己的入門範例採用的方式;在 VPS 上的單節點 k3s 叢集 中,該工作則會改為讀取 kubelet 寫入的 pod 日誌目錄。
保留期限:決定日誌何時刪除
幾乎沒有人會在磁碟空間用盡之前決定保留期限,最後往往在凌晨 3 點、服務停止時才處理。第一天就根據兩個問題決定:你實際會查閱多久以前的日誌,以及下個月進行事件檢討時仍必須保留哪些資料。對單一伺服器而言,14 到 30 天通常能同時滿足這兩點。
Loki 在啟用 compactor 之前完全不會刪除任何資料。保留功能預設為關閉,因此當 retention_period 留在設定檔中卻未發揮作用,導致磁碟區用盡時,很多人都會感到意外。
limits_config:
retention_period: 744h
compactor:
working_directory: /loki/retention
compaction_interval: 10m
retention_enabled: true
retention_delete_delay: 2h
retention_delete_worker_count: 150
delete_request_store: filesystem744h 等於 31 天。這個區塊受 4 項已記載的規則控制:
- 保留功能由 compactor 套用,Grafana 文件建議以單一執行個體執行 compactor。在單一 VPS 上會自動符合這項條件。
- 最短保留期限為 24h,且只有在索引週期為 24h 時保留功能才會運作。範例中的
schema_config已使用period: 24h,因此維持不變。 retention_enabled為 true 後就必須設定delete_request_store。它指定儲存刪除要求的 store,因此在以檔案系統為後端的單一節點中,應與 schema 中現有的object_store: filesystem相同。- Chunk 會先被標記,並在
retention_delete_delay後刪除;這裡是 2h,因此釋放磁碟空間的時間會晚於保留政策所表示的時間。重新載入 5 分鐘後,不要只根據df判斷設定是否生效。
OpenSearch 會刪除整個索引,而不是個別日誌行,因此日誌索引會按日建立。ISM policy 會讓索引依序經過不同狀態,達到指定存留時間後刪除;而 ism_template 會將政策套用至新建立的索引,因此不必每次手動設定。
14 天後刪除日誌索引的 ISM policy
{
"policy": {
"description": "delete log indexes after 14 days",
"default_state": "hot",
"states": [
{
"name": "hot",
"actions": [],
"transitions": [
{ "state_name": "delete", "conditions": { "min_index_age": "14d" } }
]
},
{
"name": "delete",
"actions": [ { "delete": {} } ],
"transitions": []
}
],
"ism_template": { "index_patterns": ["logs-*"], "priority": 100 }
}
}使用 PUT 對 _plugins/_ism/policies/logs-retention 發出要求即可建立。此範本只會套用至政策建立後建立的索引,因此磁碟上已存在的索引仍需手動套用政策。
無論使用哪個系統,保留期限的設定都取決於背後的可用空間檢查。若磁碟區已被 10 天的日誌填滿,即使設定在 14 天後刪除也無法挽救問題。因此,請將此政策搭配 VPS 磁碟健康監控,並在使用量達到 80% 時發出警示。
每 GB 日誌需要多少磁碟空間
實際需求取決於日誌的行數與欄位,因此應以自己的資料測量,不要直接採用任何已發布的比例。兩者的機制差異足以判斷大致方向。OpenSearch 和 Elasticsearch 會為每個已索引欄位建立倒排索引,並儲存文件本身,因此寫入磁碟的資料會大於原始文字,而且每個 replica 都會使容量需求倍增。在單一節點上,請將 replica 數量設為 0,因為同一節點上的 replica shard 無法承受該節點故障;若維持為 1,磁碟使用量會加倍,叢集健康狀態也會永久停留在 yellow。Loki 會寫入壓縮後的 chunk 與小型 label index,因此其磁碟用量主要取決於日誌行的壓縮大小。
sudo du -sh /var/lib/docker/volumes/loki-data/_data
curl -k -u admin:<password> "https://localhost:9200/_cat/indices?v&h=index,docs.count,store.size"在連續兩天執行適用的項目。兩次結果的差異就是每日增長量。將此數值乘以保留天數,再為 compaction 與 merge 預留約 30% 的空間,然後與 volume 容量比較。若容量不足,請先縮短保留期限,再購買磁碟,因為擴充 volume 只會將相同問題延後幾週。
小型主機最先會發生什麼問題
記憶體會先耗盡。核心的 OOM(記憶體不足)終止程式會挑選大型程序,而日誌主機上最大的程序通常是 JVM。journalctl -k | grep -i "killed process" 會顯示終止事件,並在方括號中列出程序名稱。被終止的程序不一定是日誌堆疊;也可能是 sshd 或資料庫。這會導致日誌實驗反而讓你要收集日誌的應用程式停止運作。請為容器明確設定記憶體上限,讓故障發生在你指定的位置;這正是 Docker Compose 的記憶體限制 的用途。
磁碟會接著耗盡,搜尋引擎也會以特定且容易辨識的方式失敗。Elasticsearch 和 OpenSearch 會在多個層級監控磁碟使用量。低水位線為 85%,高水位線為 90%。達到 95% 的 flood stage 時,該節點上具有 shard 的每個索引都會收到 index.blocks.read_only_allow_delete,之後寫入會因 blocked by: [FORBIDDEN/12/index read-only / allow delete (api)] 而失敗。使用量降回高水位線以下後,系統會解除封鎖。請先釋放磁碟空間;只有封鎖持續存在時,才手動清除。
curl -k -u admin:<password> -X PUT "https://localhost:9200/_all/_settings" \
-H 'Content-Type: application/json' \
-d '{"index.blocks.read_only_allow_delete": null}'Loki 的失敗較不明顯。它沒有可切換的唯讀模式,因此磁碟區已滿時,發送端會出現推送失敗,查詢結果也會出現缺漏;基數問題則會表現為記憶體緩慢增加,而不是錯誤。請定期監控 chunks 目錄的大小,不要等到發生事故後才檢查。
最後一種故障是寫入錯誤的資料。日誌系統不是指標系統:每 10 秒取樣一次的 CPU 負載若以文字儲存,保存成本高,也不便於繪圖;這項工作應交給 Ubuntu 24.04 上的 Zabbix 監控伺服器 等工具。應用程式例外需要分組、去重與 stack trace 檢視,這是 自架錯誤追蹤器 的工作。確認網站是否停止運作則是另一項工作,可交由 Uptime Kuma 等 uptime 與狀態頁面 處理。請讓日誌系統專注於供人員閱讀的文字行。
FAQ
我需要 Elasticsearch 來搜尋伺服器日誌嗎?
如果只有一或兩台伺服器,不需要。journalctl 已可依 unit、優先級、開機工作階段與時間範圍篩選,輪替後的檔案也可搭配 grep 與 zgrep 使用。當你有許多機器、需要一次搜尋所有機器的全文,或有多位人員需要共用介面時,搜尋叢集才值得占用記憶體。在此規模以下,設定大小上限與保留時間的 journald 不需額外 RAM,也能完成相同工作。
自架日誌管理需要多少 RAM?
請依各專案公布的數據估算,不要套用經驗法則。Loki 和 Alloy 是 Go 程式,不需要預先保留固定的 heap;Grafana 文件指出,單體式 Loki 每天最高約可處理 20GB。OpenSearch 的範例 compose 為示範環境設定 512 MB heap,生產環境範例則設定 2 GB;Elastic 表示 heap 必須維持在總記憶體的 50% 以下,因此 2 GB heap 代表在加入 Kibana 前,主機至少需要 4 GB。Logstash 文件則建議自身 heap 不低於 4GB。這些是文件記載的設定值,不是效能基準,因此請先測量自身負載,再規劃資源配置。
Loki 與 OpenSearch 用於日誌時,實際差異是什麼?
差異在索引模型。Loki 只為 labels 建立索引,並將日誌內容保存為壓縮 chunk,在查詢時掃描。因此寫入成本低,但廣泛查詢的成本較高。OpenSearch 會為欄位內容建立索引,因此任意全文搜尋速度快,但索引會同時增加記憶體與磁碟用量。如果你知道要查詢的服務和時間範圍,請選擇 Loki。如果需要搜尋事先無法預測的文字,請選擇 OpenSearch。
我應該在 VPS 上保留多久的日誌?
請先決定保留天數,不要等磁碟空間替你決定。每個系統只應在一個位置設定保留期限:journald 使用 MaxRetentionSec= 和 SystemMaxUse=,Loki 在啟用 compactor 時使用 retention_period,OpenSearch 則使用搭配 min_index_age 的 ISM policy。對大多數單一伺服器環境而言,14 到 30 天足以支援除錯與事件檢討。任何必須保留更久的資料,都應複製到主機外保存,因為只留在故障伺服器上的日誌不算可靠紀錄。
Promtail 仍然是將日誌傳送至 Loki 的方式嗎?
不是。Promtail 已於 2 March 2026 終止生命週期,Grafana Alloy 取代了它。Loki 官方的 Docker 安裝範例現在會提供 Alloy 設定,Grafana 也提供轉換工具,可將現有的 Promtail 設定轉換為 Alloy 語法。現有的 Promtail 安裝仍可執行,但不會再收到修正,因此應將遷移視為維護工作,而不是可以無限延期的升級作業。