海外VPS,境外服务器推荐
国外VPS 国外VPS 国外VPS 国外VPS

ubuntu20.04 系统日志大小限制教程|设置 journald 与 logrotate 控制日志占用

  • 目标:Ubuntu 20.04 上实施 系统日志大小限制,防止 / 分区被日志写满。
  • 涉及组件:systemd-journaldjournalctl)与 rsyslog + logrotate
  • 关键位置:/etc/systemd/journald.conf/etc/logrotate.d/rsyslog/var/log/
  • 快速命令:journalctl --disk-usagejournalctl --vacuum-size=500Msudo logrotate -f /etc/logrotate.conf
  • 推荐上限:Journal 总占用 ≤ 1G;/var/log/syslog 单文件 ≤ 100M、保留 7 份、启用压缩。

核心原理:Ubuntu 20.04 的日志体系

Ubuntu 20.04 默认同时存在两条日志路径:

  • systemd-journald:二进制日志(journalctl 查看);可在内存(volatile)或磁盘(persistent)持久化。
  • rsyslog + logrotate:传统文本日志(如 /var/log/syslog/var/log/kern.log/var/log/auth.log)。

要实现“ubuntu20.04 系统日志大小限制”,需分别对 journaldlogrotate 设定上限:前者控制 Journal 总体积与单文件大小,后者控制文本日志的轮转、压缩与保留份数。

方法一:限制 systemd-journald 体积(推荐)

1)启用持久化并设置总上限

如果希望限制落盘的 Journal 总体积,先确保持久化目录存在,然后编辑配置:

sudo mkdir -p /var/log/journal
sudo nano /etc/systemd/journald.conf

[Journal] 段添加或修改如下(示例值可按磁盘大小微调):

[Journal]
Storage=persistent
SystemMaxUse=1G
SystemKeepFree=500M
SystemMaxFileSize=200M
SystemMaxFiles=10
RuntimeMaxUse=200M
RuntimeKeepFree=50M

字段说明

  • Storage=persistent:将日志持久化到磁盘(/var/log/journal)。
  • SystemMaxUse:Journal 持久化日志的总占用上限(例如 1G)。
  • SystemKeepFree:为系统磁盘至少预留的空间,防止被日志写爆(如 500M)。
  • SystemMaxFileSize:单个 Journal 文件最大大小(如 200M)。
  • SystemMaxFiles:最多保留的 Journal 文件个数。
  • RuntimeMaxUse/RuntimeKeepFree:仅内存日志时的上限与预留(/run)。

保存后重启服务使之生效:

sudo systemctl restart systemd-journald

2)立刻“瘦身”到指定大小或时长

除了永久配置,还可用 journalctl 的清理命令即时收缩占用:

# 查看当前 Journal 占用
journalctl --disk-usage

# 将历史日志清理到不超过 500MB
sudo journalctl --vacuum-size=500M

# 或仅保留最近 14 天
sudo journalctl --vacuum-time=14d

3)常用数值建议(按服务器类型)

  • 1~2 核 / 1–2GB RAM 小型实例:SystemMaxUse=400MSystemMaxFileSize=100MSystemMaxFiles=6
  • 通用 Web/应用服务器:SystemMaxUse=1GSystemMaxFileSize=200MSystemMaxFiles=10
  • 高并发/日志较多:SystemMaxUse=2GSystemMaxFileSize=256MSystemMaxFiles=12

方法二:限制 /var/log 文件(logrotate 轮转)

logrotate 负责对 /var/log/*.log 做基于大小时间的轮转、压缩与保留。Ubuntu 20.04 默认已启用,你只需在对应规则中声明“大小阈值 + 保留份数”。

1)修改 rsyslog 的轮转规则

编辑系统的 rsyslog 轮转文件:

sudo nano /etc/logrotate.d/rsyslog

(下一批将给出可直接粘贴的完整示例,覆盖 /var/log/syslogauth.logkern.log 等文件,并解释各指令如 sizerotatecompresscopytruncate 的取舍。)

即用模板:拷贝即可的配置片段

为“ubuntu20.04 系统日志大小限制”准备的两段模板(journald 与 logrotate)会在下一批给到,你可直接覆盖并微调数值后应用。

验证与清理:立刻生效与占用回收

改完配置后,你应执行以下检查:

# 验证 journald 配置已加载
systemctl status systemd-journald

# 查看 Journal 占用并确认未超过上限
journalctl --disk-usage

# 强制执行一次轮转,验证 logrotate 规则
sudo logrotate -f /etc/logrotate.conf

# 观察 /var/log/ 占用
sudo du -sh /var/log/* | sort -h

常见问题 FAQ(节选)

Q1:设置了 SystemMaxUse 但占用仍偏大?
检查是否启用了持久化(Storage=persistent)且目录 /var/log/journal 存在;重启 systemd-journald 后再用 --vacuum-size 收敛一次历史占用。

Q2:用 logrotate 后日志短暂停写会丢吗?
对写入频繁的文件建议加 copytruncate,避免切换文件句柄时短暂停写;关键审计日志可选用 postrotate 里重载服务以确保句柄切换。

Q3:只想保留最近 N 天日志?
Journal 用 --vacuum-time=Nd,logrotate 用 maxage N 或按天 daily + rotate 搭配。

即用模板一:/etc/systemd/journald.conf(限制 Journal 体积)

将下列片段完整覆盖到 /etc/systemd/journald.conf(保留注释亦可)。请按你的磁盘大小调整 SystemMaxUseSystemKeepFree 等数值。

[Journal]
# 将日志持久化到磁盘(目录:/var/log/journal)
Storage=persistent

# Journal 总体积上限,建议 400M~2G 之间
SystemMaxUse=1G

# 给根分区至少预留的剩余空间,避免被日志写满
SystemKeepFree=500M

# 单个 Journal 文件上限(达到后切新文件)
SystemMaxFileSize=200M

# 最多保留多少个 Journal 文件(与上限共同生效)
SystemMaxFiles=10

# 仅内存(/run)日志的上限与预留(Storage=volatile 时生效)
RuntimeMaxUse=200M
RuntimeKeepFree=50M

# 提示:Ubuntu 20.04 不建议使用太新的保留参数;以上即可控制体积

一键应用并重启:

sudo mkdir -p /var/log/journal
sudo tee /etc/systemd/journald.conf >/dev/null <<'EOF'
[Journal]
Storage=persistent
SystemMaxUse=1G
SystemKeepFree=500M
SystemMaxFileSize=200M
SystemMaxFiles=10
RuntimeMaxUse=200M
RuntimeKeepFree=50M
EOF

sudo systemctl restart systemd-journald
journalctl --disk-usage

即用模板二:/etc/logrotate.d/rsyslog(限制 /var/log 文本日志)

该模板对常见日志按“达到指定大小即轮转 + 压缩 + 保留 N 份”处理。若你已有自定义规则,合并时注意去重。

/var/log/syslog
{
    daily
    size 100M
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    copytruncate
    create 640 syslog adm
    sharedscripts
    postrotate
        reload rsyslog >/dev/null 2>&1 || true
    endscript
}

# 认证与安全相关日志
/var/log/auth.log /var/log/kern.log /var/log/faillog
{
    weekly
    size 50M
    rotate 8
    compress
    delaycompress
    missingok
    notifempty
    copytruncate
    create 640 syslog adm
    sharedscripts
    postrotate
        reload rsyslog >/dev/null 2>&1 || true
    endscript
}

# APT/DPKG 相关日志
/var/log/apt/history.log /var/log/apt/term.log /var/log/dpkg.log
{
    monthly
    size 30M
    rotate 6
    compress
    delaycompress
    missingok
    notifempty
    copytruncate
    create 640 root adm
}

# 防火墙/自动更新(若存在)
/var/log/ufw.log /var/log/unattended-upgrades/unattended-upgrades.log
{
    weekly
    size 50M
    rotate 6
    compress
    delaycompress
    missingok
    notifempty
    copytruncate
    create 640 syslog adm
}

立即验证该规则:

# 强制执行一次轮转(用于验证)
sudo logrotate -f /etc/logrotate.conf

# 查看 /var/log 占用变化
sudo du -sh /var/log/* | sort -h

完整操作步骤(从检查到验证)

  1. 盘点当前占用
    df -h /
    sudo du -sh /var/log/* | sort -h
    journalctl --disk-usage
    
  2. 部署 Journald 限制:按上文“模板一”覆盖并 restart
  3. 部署 Logrotate 限制:按上文“模板二”覆盖。
  4. 即时回收历史占用(可选):
    sudo journalctl --vacuum-size=500M   # 将 Journal 收敛到 500MB
    sudo logrotate -f /etc/logrotate.conf # 立刻轮转文本日志
    
  5. 再次核验
    journalctl --disk-usage
    sudo du -sh /var/log/* | sort -h
    

推荐参数矩阵(按服务器类型)

类型 Journald:SystemMaxUse Journald:SystemMaxFileSize Journald:SystemKeepFree syslog:size syslog:rotate
轻量实例(1–2GB RAM) 400M 100M 300M 50M 5
通用 Web/应用 1G 200M 500M 100M 7
高并发/日志多 2G 256M 1G 200M 10

监控与告警(防止再次写满)

在没有额外监控系统时,可用简易脚本配合 cron 邮件告警:

sudo tee /usr/local/bin/check-log-usage.sh >/dev/null <<'EOF'
#!/usr/bin/env bash
# 触发条件:/var/log 超过 2G 或 Journal 超过 1.5G
set -e
LOG_DIR_SIZE=$(du -s /var/log | awk '{print $1}') # KB
JOURNAL_SIZE=$(journalctl --disk-usage 2>/dev/null | awk '{print $3$4}' | sed 's/[^0-9.]//g')
# 将 KB 转换为 GB 粗略判断
if [ "$LOG_DIR_SIZE" -gt $((2*1024*1024)) ]; then
  echo "[WARN] /var/log 超过 2G:$((LOG_DIR_SIZE/1024)) MB"
fi
# Journal 简易判断(需要持久化开启才有意义)
# 这里仅提示,不做自动清理,避免误删审计
EOF
sudo chmod +x /usr/local/bin/check-log-usage.sh

加入 cron(每小时检查一次):

(crontab -l 2>/dev/null; echo "0 * * * * /usr/local/bin/check-log-usage.sh | mail -s 'Log usage alert' root") | crontab -

若未配置本地邮件,可改为写入文件再由外部采集:

/usr/local/bin/check-log-usage.sh >> /var/log/log-usage-monitor.log 2>&1

回滚与还原

  • 恢复 journald 默认:将 /etc/systemd/journald.conf 恢复初始(或注释自定义键),删除 /var/log/journal 目录(仅在你确认不再保留持久日志时),然后 systemctl restart systemd-journald
  • 撤销 logrotate 改动:还原 /etc/logrotate.d/rsyslog 备份文件,或删除新增条目,再执行 sudo logrotate -d /etc/logrotate.conf 做一次“干跑”检查配置语法。

常见坑与排错

  • 改了 journald 但占用没降:需要先 restart systemd-journald,再用 --vacuum-size--vacuum-time 收敛历史文件。
  • logrotate 没触发:检查 /var/lib/logrotate/status 的时间,确认 cron.daily 正常;手动执行 sudo /etc/cron.daily/logrotate 看输出。
  • 应用仍写入旧句柄:对于关键服务,考虑在 postrotatesystemctl reload <service> 而非仅 copytruncate
  • 磁盘突然被吃满:除日志外,确认 /var/crash、容器层、临时大文件(如备份/转储)是否占用;日志限制并不能处理非日志数据。

FAQ 继续(围绕“ubuntu20.04 系统日志大小限制”)

Q:Journal 与 /var/log 文本日志如何取舍?
生产上常用“二者并存”:Journal 方便结构化检索与早期排障,文本日志便于外部采集与长期归档。通过上限配合轮转即可控制总体积。

Q:是否能按天精确限制 Journal 保留?
20.04 建议用 journalctl --vacuum-time=Nd 做周期清理(配合 cron),或控制体积为主(SystemMaxUse)。

Q:如何只把 Journal 放到独立分区?
/var/log/journal 挂载到独立分区或磁盘(如 XFS/EXT4),然后 Storage=persistent,即可将 Journal 与根分区解耦。

一键初始化脚本(可选)——落地“ubuntu20.04 系统日志大小限制”

脚本将:① 配置 systemd-journald 体积上限;② 写入 rsyslog 的轮转规则;③ 立即回收历史占用。请先确认数值符合你的磁盘容量与合规需求。

sudo tee /usr/local/sbin/init-log-limits.sh >/dev/null <<'EOF'
#!/usr/bin/env bash
set -euo pipefail

# --------- 参数:按需修改 ----------
J_SYSTEM_MAX_USE="1G"
J_SYSTEM_KEEP_FREE="500M"
J_SYSTEM_MAX_FILE="200M"
J_SYSTEM_MAX_FILES="10"
J_RUNTIME_MAX_USE="200M"
J_RUNTIME_KEEP_FREE="50M"

SYSLOG_SIZE="100M"
SYSLOG_ROTATE="7"
AUTH_SIZE="50M"
AUTH_ROTATE="8"
APT_SIZE="30M"
APT_ROTATE="6"
# -----------------------------------

echo "[1/5] 配置 journald..."
sudo mkdir -p /var/log/journal
sudo install -m 0644 /dev/stdin /etc/systemd/journald.conf <<JEOF
[Journal]
Storage=persistent
SystemMaxUse=${J_SYSTEM_MAX_USE}
SystemKeepFree=${J_SYSTEM_KEEP_FREE}
SystemMaxFileSize=${J_SYSTEM_MAX_FILE}
SystemMaxFiles=${J_SYSTEM_MAX_FILES}
RuntimeMaxUse=${J_RUNTIME_MAX_USE}
RuntimeKeepFree=${J_RUNTIME_KEEP_FREE}
JEOF

echo "[2/5] 重启 journald..."
sudo systemctl restart systemd-journald

echo "[3/5] 写入 rsyslog 轮转规则..."
sudo install -m 0644 /dev/stdin /etc/logrotate.d/rsyslog <<LEOF
/var/log/syslog
{
    daily
    size ${SYSLOG_SIZE}
    rotate ${SYSLOG_ROTATE}
    compress
    delaycompress
    missingok
    notifempty
    copytruncate
    create 640 syslog adm
    sharedscripts
    postrotate
        reload rsyslog >/dev/null 2>&1 || true
    endscript
}

/var/log/auth.log /var/log/kern.log /var/log/faillog
{
    weekly
    size ${AUTH_SIZE}
    rotate ${AUTH_ROTATE}
    compress
    delaycompress
    missingok
    notifempty
    copytruncate
    create 640 syslog adm
    sharedscripts
    postrotate
        reload rsyslog >/dev/null 2>&1 || true
    endscript
}

/var/log/apt/history.log /var/log/apt/term.log /var/log/dpkg.log
{
    monthly
    size ${APT_SIZE}
    rotate ${APT_ROTATE}
    compress
    delaycompress
    missingok
    notifempty
    copytruncate
    create 640 root adm
}
LEOF

echo "[4/5] 立即瘦身与轮转..."
sudo journalctl --vacuum-size="${J_SYSTEM_MAX_USE}" || true
sudo logrotate -f /etc/logrotate.conf || true

echo "[5/5] 验证占用..."
journalctl --disk-usage || true
sudo du -sh /var/log/* | sort -h | tail -n 20 || true

echo "完成:ubuntu20.04 系统日志大小限制 已应用。"
EOF

sudo chmod +x /usr/local/sbin/init-log-limits.sh
sudo /usr/local/sbin/init-log-limits.sh

服务专用规则:Nginx / MySQL / Docker

Nginx 日志轮转(避免占满磁盘)

Ubuntu 20.04 通常已有默认规则;如需“按大小触发 + 无损切换句柄”,可单独新增:

sudo tee /etc/logrotate.d/nginx-size >/dev/null <<'EOF'
/var/log/nginx/*.log {
    weekly
    size 100M
    rotate 10
    missingok
    notifempty
    compress
    delaycompress
    sharedscripts
    postrotate
        # 优雅切换日志文件句柄(优于 copytruncate)
        [ -s /run/nginx.pid ] && kill -USR1 $(cat /run/nginx.pid)
    endscript
}
EOF
sudo logrotate -f /etc/logrotate.conf

MySQL 日志轮转(按实际路径调整)

MySQL 8 在 Ubuntu 20.04 上常见错误日志路径为 /var/log/mysql/error.log;如开启了通用/慢日志,请同步加入:

sudo tee /etc/logrotate.d/mysql-extra >/dev/null <<'EOF'
/var/log/mysql/*.log {
    daily
    size 50M
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    create 640 mysql adm
    sharedscripts
    postrotate
        # 让 mysqld 重新打开日志(若使用文件日志)
        test -x /usr/bin/mysqladmin || exit 0
        /usr/bin/mysqladmin --defaults-file=/etc/mysql/debian.cnf flush-logs >/dev/null 2>&1 || true
    endscript
}
EOF
sudo logrotate -f /etc/logrotate.conf

Docker 容器日志(不要用 logrotate;用守护进程级别限制)

默认 json-file 驱动会在 /var/lib/docker/containers/*/*.log 不断增大。正确做法是在 /etc/docker/daemon.json 里设定最大大小与保留份数:

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json >/dev/null <<'EOF'
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "5"
  }
}
EOF
sudo systemctl restart docker

如需每个容器不同限制,可在 docker run 或 Compose 里覆盖 --log-opt

journald 防喷涌(限速参数)

在高并发或异常噪声场景,可启用写入限速,避免日志“洪水”影响 IO:

# 在 /etc/systemd/journald.conf 的 [Journal] 中追加
RateLimitIntervalSec=30s
RateLimitBurst=1000

表示在 30 秒窗口内最多接收 1000 条超限消息,超出将被丢弃并统计(可依业务调小)。

将 Journal 放到独立分区(进一步隔离风险)

  1. 准备分区/磁盘并格式化(示例:/dev/vdb1):
    sudo mkfs.ext4 -L journal /dev/vdb1
  2. 创建挂载点并迁移现有数据:
    sudo systemctl stop systemd-journald
    sudo mkdir -p /var/log/journal
    sudo mount /dev/vdb1 /var/log/journal
    sudo chown -R root:systemd-journal /var/log/journal
    sudo chmod 2755 /var/log/journal
    sudo systemctl start systemd-journald
  3. 写入 /etc/fstab 永久挂载:
    echo 'LABEL=journal /var/log/journal ext4 defaults,noatime 0 2' | sudo tee -a /etc/fstab

这样,“ubuntu20.04 系统日志大小限制” 不仅靠参数控体积,还把 Journal 与根分区解耦,防止互相拖累。

周期清理策略(配合体积上限)

在已设定 SystemMaxUse 的前提下,可额外用 --vacuum-time 做“按天保留”:

(crontab -l 2>/dev/null; echo "13 3 * * * /usr/bin/journalctl --vacuum-time=14d") | crontab -

上例每日 03:13 清理,仅保留最近 14 天的 Journal。

审计/合规建议(示例基线)

  • 生产最小保留:业务日志(文本)≥ 30 天,系统审计与安全日志 ≥ 90 天;体积上限由磁盘与采集频率共同约束。
  • 归档与外送:把日志汇聚到 ELK/ClickHouse/云观测平台;本机仅保短期,降低“被写满”风险。
  • 时间同步:启用 systemd-timesyncd 或 NTP,保证跨节点日志时序一致。

快速诊断清单(谁在撑爆磁盘?)

# 查看 /var/log 各文件体积排行(Top 20)
sudo du -ah /var/log | sort -h | tail -n 20

# 哪些进程仍握着“已删除”的大文件句柄(幽灵占用)
sudo lsof | grep '(deleted)'

# 最近 1 分钟内最热的日志写入对象
sudo find /var/log -type f -mmin -1 -printf "%T@ %p\n" | sort -n | tail -n 30 | awk '{print $2}'

# Journal 统计(占用与文件数)
journalctl --disk-usage
ls -lh /var/log/journal/*/*.journal 2>/dev/null | wc -l

长尾问答(更贴近检索词意图)

“ubuntu20.04 系统日志大小限制 不生效”怎么办?
确认 Storage=persistent、目录存在、已 restart systemd-journald,并执行一次 --vacuum-size 收敛历史文件。

“如何只限制 /var/log/syslog 体积,不影响其他日志?”
sizerotate 等指令仅写入 /etc/logrotate.d/rsyslog 对应 /var/log/syslog 的条目,其它文件不改动。

“K8s/容器场景如何做 ubuntu20.04 系统日志大小限制?”
宿主机启用 journald 体积上限;容器引擎用 json-filemax-size/max-file;集群层面把应用日志外送到集中存储。

版权声明:本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
文章名称:《ubuntu20.04 系统日志大小限制教程|设置 journald 与 logrotate 控制日志占用》
文章链接:https://www.vps90.com/ubuntu20-04-%e7%b3%bb%e7%bb%9f%e6%97%a5%e5%bf%97%e5%a4%a7%e5%b0%8f%e9%99%90%e5%88%b6%e6%95%99%e7%a8%8b%ef%bd%9c%e8%ae%be%e7%bd%ae-journald-%e4%b8%8e-logrotate-%e6%8e%a7%e5%88%b6%e6%97%a5%e5%bf%97
本站资源仅供个人学习交流,请于下载后24小时内删除,不允许用于商业用途,否则法律问题自行承担。