Skip to content

Linux 日志·监控·启动·脚本与痕迹

在 Linux 系统中,日志管理是维护系统稳定性、排查问题和保障安全的重要环节

系统日志

Linux 系统的日志文件主要集中在 /var/log/ 目录下,常见的关键日志文件包括:

shell
/var/log/messages              系统核心日志,记录内核消息、系统服务启动 / 停止、错误信息等(系统出问题查看此日志)
/var/log/secure                记录验证和授权方面的信息,只要涉及用户密码的操作都会记录在此,如:添加用户、修改密码、ssh登录、sudo授权、权限变更等
/var/log/cron                  定时任务相关日志
/var/log/cups                  打印信息相关日志
/var/log/dmesg                 系统开机自检相关日志
/var/log/maillog               邮件相关日志
/var/log/btmp                  错误登录相关日志,二进制文件,不能使用vim命令查看,可使用lastb命令查看
/var/log/lastlog               系统中所有用户最后一次登录的时间相关日志,二进制文件,不能使用vim命令查看,可使用lastb命令查看
/var/log/wtmp                  永久记录用户的登录、注销、重启、关机,二进制文件,不能使用vim命令查看,可使用last命令查看
/var/run/utmp                  当前登录系统的用户信息,内容时刻变化,使用 w 或者 who 或者 users 等命令查询

/var/log/httpd/                Apache 服务日志(访问日志 access_log、错误日志 error_log)。
/var/log/mysqld.log            MySQL/MariaDB 服务日志(位置可能因配置不同变化)。
/var/log/yum.log            YUM 包管理工具的操作日志(安装 / 升级 / 卸载软件)。

/etc/rsyslog.conf              日志配置文件位置

查看日志

常用命令

shell
# 基础查看
cat /var/log/messages             # 直接输出整个日志文件内容。
tail -f /var/log/secure           # 实时跟踪日志更新(常用排查实时问题)
head -n 20 /var/log/cron          # 查看日志前 20 行。
grep "error" /var/log/messages    # 筛选包含 “error” 的日志行。
less /var/log/messages            # 分页查看大日志文件(按 q 退出)。

# 高级查看 grep
grep "2024-10-28 10:" /var/log/messages             # 按时间筛选日志
grep -c "Failed password" /var/log/secure           # 统计 SSH 登录失败次数
grep "error" /var/log/messages | grep "Oct 28"      # 同时匹配 “error” 和日期

日志级别

在配置文件中通过日志级别来划分日志文件内容的去处

shell
低级别
debug                             一般状态的测试信息
info                              基本状态信息
notice                            普通状态,有一定重要性的
warning                           警告状态,还不影响系统运行的
err                               错误状态,一般会影响服务器运行的
crit                              临界状态,比err还严重的
alert                             警告状态,比crit还严重,需马上处理
emerg                             疼痛状态,系统已经无法使用了
高级别
*                                 代表日志所有等级

自定义日志

将 crit 级别高的信息写入到 /var/log/crit.log 日志文件

  1. 编辑日志配置文件
shell
# 执行
vim /etc/rsyslog.conf

# 写入
*.crit                            /var/log/crit.log
  1. 重启日志配置文件程序
shell
service rsyslog restart
  1. 查看是否生成 /var/log/crit.log 文件
shell
ls /var/log/

日志轮替(日志切割)

把日志按照日期分割开,轮替是将分割的日志保持一定的量,旧的去,新的进

比如:只保留最近 7 天的数据,那么轮替的效果是,到了第八天新建日志文件,删除第一天的文件,让日志文件始终保持最近 7 天

rpm 包的日志会自动加入轮替,源码包和自己指定的日志需要手动配置轮替

  1. 编辑 vim /etc/logrotate.d/nginx
shell
weekly                                  每周对日志文件进行一次轮替一次
rotate 4                                保存4个日志备份文件,如果进行了5次日志轮替,则删除第一个备份日志文件
create                                  在日志轮替时自动创建新的日志文件
dateext                                 使用日期作为日志轮替的后缀
#compress                               日志文件是否进行压缩,取消注释则压缩
include /etc/logrotate.d                引入外部资源文件,前提是外部资源文件的格式必须和 /etc/logrotate.conf 文件格式相同,才生效(分开管理)

#单独配置日志文件的轮替
/var/log/nginx/*.log {
    daily          # 每天轮转一次
    missingok      # 日志不存在时不报错
    rotate 7       # 保留7份旧日志
    compress       # 压缩旧日志(.gz)
    delaycompress  # 延迟压缩(下次轮转时再压缩当前日志)
    notifempty     # 日志为空时不轮转
    create 0640 nginx nginx  # 创建新日志文件,权限640,属主nginx
}
  1. /etc/logrotate.conf 参数说明
shell
daily                                日志的轮替周期是每天
weekly                               日志的轮替周期是每周
monthly                              日志的轮替周期是每月
rotate 数字                          保留的日志备份个数,0代表无备份文件
compress                             日志轮替时对日志进行压缩
create mode owner group              建立日志时指定:文件权限、所有者、所属组
mail address                         当日志轮替时以邮件的方式发送到指定邮件地址,比如:mail xxx@lamp.net
missingok                            如果日志不存在则忽略日志的警告信息
notifempty                           如果日志为空文件则不进行轮替
minsize 大小                         日志轮替的最小值,小于这个值则不进行轮替
size 大小                            轮替时日志大于这个大小才会轮替,不考虑时间
dateext                              使日期作为日志轮替的文件后缀
sharedscripts 脚本                   在此关键字后面的脚本只执行一次

prepotate
    #执行脚本
endscript
                                    在日志轮替之前执行脚本命令
postrotate
    #执行脚本
endscript                           在日志轮替之后执行脚本命令

把自己的日志或源码包日志加入轮替

案例一:编辑自己的日志轮替

轮替前给日志文件删除 a 属性,让其变成可修改状态,轮替结束添加 a 属性,让其变成无法修改状态,注意这两个回调,轮替结束后重启 rsyslog 服务确保备份日志文件生成

  1. 编辑配置文件 vi /etc/logrotate.d/mylog
shell
/var/log/mylog {
    weekly
    rotate 1
    sharedscripts
    prerotate
            /usr/bin/chattr -a /var/log/mylog
            # 日志轮替前删除文件的a属性,可以被修改
    endscript

    sharedscripts
    postrotate
            /usr/bin/chattr +a /var/log/mylog
            # 日志轮替后添加文件的a属性,不可以被修改
    endscript

    sharedscripts
    postrotate
            /bin/kill -HUP $(/bin/cat /var/run/syslogd.pid 2>/dev/null) &>/dev/null
            # 日志轮替后重启rsyslog服务,保证日志正常轮替
    endscript
}
  1. 测试
shell
# 执行
logrotate -vf /etc/logrotate.conf

# 参数
logrotate -v 配置文件名                          显示日志轮替过程
logrotate -f 配置文件名                          强制进行所有日志轮替

案例二:把 nginx 服务的日志加入 linux 日志轮替

需重启 nginx 服务(否则不生效)

  1. 编辑配置文件 vi /etc/logrotate.d/mylog
shell
/xxx/nginx/access.log /xxx/nginx/default.log{
    daily
    rotate 15
    sharedscripts
    postrotate
            /bin/kill -HUP $(/bin/cat /var/run/syslogd.pid) &>/dev/null
            # 日志轮替后重启rsyslog服务,保证日志正常轮替
            /bin/kill -HUP $(/bin/cat /usr/local/bginx/logs/nginx.pid) &>/dev/null
            # 重启nginx服务
    endscript
}
  1. 测试
shell
# 执行
logrotate -vf /etc/logrotate.conf

# 参数
logrotate -v 配置文件名                          显示日志轮替过程
logrotate -f 配置文件名                          强制进行所有日志轮替

监控系统信息

shell
# 基础语法
vmstat [选项] [时间间隔] [次数] 

# 选项
-a:显示活跃和非活跃内存
-f:显示从系统启动至今的 fork 数量
-m:显示 slab 信息
-n:只在开始时显示一次头部信息
-s:显示内存相关统计信息及多种系统活动数量
-d:显示磁盘相关统计信息
-p:显示指定磁盘分区统计信息
-t:在输出信息中加入时间戳

# 时间间隔:指定数据刷新的时间间隔(秒)

# 次数:指定刷新的次数,不指定则持续输出

# 输出结果
procs:进程信息字段
r                  等待运行的进程数,数越大,系统越繁忙
b                  不可被唤醒的进程数,数越大,系统越繁忙

memory:内存信息字段
swpd               虚拟内存的使用情况,单位KB
free               空闲内存容量,单位KB
buff               缓冲内存容量,单位KB
cache              缓存内存容量,单位KB

swap:交换分区的信息字段
si                 从磁盘中交换到内存中的数据的量,单位KB
so                 从内存中交换到磁盘中的数据的量,单位KB

io:磁盘读写信息字段
bi                 从块设备读取数据的总量,单位块,越大I/O越繁忙
bo                 写到块设备的数据总量,单位块,越大I/O越繁忙

system:系统信息字段
in                 每秒被终端的进程次数,越大系统和接口设备的通信越繁忙
cs                 每秒进行的时间切换次数,越大系统和接口设备的通信越繁忙

cpu:cpu信息字段
us                 非内核运算消耗cpu的百分比
sy                 内核运算消耗cpu的百分比
id                 空闲cpu的百分比
wa                 等待I/O所消耗的cpu百分比
st                 被虚拟机盗用的cpu百分比

# 示例
vmstat 1 3  # 每一秒中刷新一次,取三条记录

显示开机时内核检测信息

dmesg 是系统管理员诊断系统启动问题、硬件故障和内核相关问题的重要工具

shell
dmesg # 查看内核环缓冲区存储了系统启动过程、硬件检测、驱动加载以及运行时内核产生的各种消息
dmesg | grep CPU # 查看CPU信息
dmesg | grep -i usb # 查找USB设备相关信息
dmesg | grep -i eth # 查找网卡相关信息
dmesg -c  # 清除并显示当前缓冲区内容
dmesg --follow  # 实时监控新消息(类似tail -f)

cat /proc/cpuinfo  # 查看 cpu 相关信息

查看系统内存信息 free

free 用于查看系统的内存使用情况,包括物理内存、交换内存(swap)以及内核缓冲区等信息

shell
# 按单位查看
free -b  # 以字节为单位显示
free -k  # 以 KB 为单位显示(默认)
free -m  # 以 MB 节为单位显示
free -g  # 以 GB 为单位显示
free -h  # 以人类可读的格式显示内存大小(包括 KB、MB、GB)
free -t  # 显示总计信息

# 实时查看
free -s 5 # 每5秒刷新一次

# 结果
              total        used        free      shared  buff/cache   available
Mem:        1933828      697564      176092        2044     1249768     1236264
Swap:             0           0           0
Total:      1933828      697564      176092

total:总内存大小
used:已使用的内存
free:完全空闲的内存
shared:被共享使用的内存
buff/cache:用于缓冲区和缓存的内存 # buff/cache 部分的内存是可以在需要时被系统释放的,所以实际可用内存通常比 free 列显示的要多
available:估计的可用于新应用程序的内存(考虑了可回收的缓存) # available 列给出了更准确的可用内存估计

# 内存相关信息的文件
cat /proc/meminfo

查看内核名称、主机名、内核版本、硬件架构等信息

shell
uname # 显示当前系统,结果:Linux
uname -a  # 查看内核所有信息,结果:Linux iZ8vb1dk99diziyup3k9zqZ 5.10.134-18.al8.x86_64 #1 SMP Fri Dec 13 16:56:53 CST 2024 x86_64 x86_64 x86_64 GNU/Linux
uname -n  # 显示网络节点主机名,结果:iZ8vb1dk99diziyup3k9zqZ
uname -s  # 仅显示内核名称(默认选项),结果:Linux
uname -r  # 显示内核发行版本,结果:5.10.134-18.al8.x86_64
uname -v  # 显示内核版本信息,结果:#1 SMP Fri Dec 13 16:56:53 CST 2024
uname -m  # 显示硬件架构,结果:x86_64
uname -p  # 显示处理器类型,结果:x86_64
uname -i  # 显示硬件平台,结果:x86_64

查看系统中当前用户信息

shell
w  # 此命令,查看系统中所有在线的用户信息,
展示信息:系统时间,开机时常,当前登录的用户数,系统在 1 分钟、5 分钟、15 分钟前的平均负载(越小越好)
登录的用户,登录的终端、来源 ip,登录时间,用户闲置时间,所有进程占用 cpu 的时间,当前进程占用 cpu 时间,用户正在进行的操作
USER     TTY     FROM                   LOGIN@      IDLE       JCPU           PCPU                  WHAT
用户     终端    来源ip(本地为 -    登录时间    闲置时间   所有占用cpu    当前占用cpu           用户正在进行的操作(-bash 在等待)

who  # 查看当前用户信息,展示信息:用户名,登录端口,登录时间(来源ip)

pwd  # 查看当前路径

查看系统启动时间和平均负载

shell
# 基础语法
uptime [选项]

# 选项
uptime # 查看本地时间、系统持续运行时间、当前连接终端的用户数、平均负载
uptime -p # 查看系统持续运行的时间间隔
uptime -s # 查看系统上次开机的具体时间

# 示例
uptime # 结果:09:52:37 up 166 days, 12:27,  1 user,  load average: 0.01, 0.01, 0.00

# 结果解析
09:52:37 # 系统的本地时间
up 166 days, 12:27 # 上次开机到当前的持续运行时间,166天12小时27分钟
1 user # 指当前通过终端、远程连接(如 SSH)等方式登录系统的用户数量,而非系统创建的所有用户总数。可通过 who 命令查看具体是哪些用户登录。
load average: 0.01, 0.01, 0.00 # 分别代表系统在 过去 1 分钟、过去 5 分钟、过去 15 分钟 内的平均负载,数值越低说明系统越空闲,数值越高说明系统资源(CPU、内存、I/O)占用越紧张

CentOS 系统的启动引导主要依赖 GRUB 2,它负责在硬件初始化后加载内核与初始化系统,最终完成系统启动

启动引导的完整流程

shell
1. 硬件自检(POST):计算机开机后,BIOS/UEFI 首先执行硬件自检,确认 CPU、内存、硬盘等硬件正常。
2. 加载 GRUB 2 核心:BIOS/UEFI 从硬盘的 MBR(传统 BIOS)或 EFI 系统分区(UEFI)中加载 GRUB 2 核心程序。
3. 读取 GRUB 2 配置:GRUB 2 核心加载后,读取 /boot/grub2/grub.cfg 配置文件,显示引导菜单(包含不同内核版本或其他系统选项)。
4. 用户选择或自动引导:若设置了超时时间(默认 5 秒),超时后自动加载默认内核;用户也可手动选择需启动的内核。
5. 加载内核与 initramfs:GRUB 2 根据选择,将内核(vmlinuz)和 initramfs 加载到内存中。
6. 初始化系统(systemd):内核启动后,加载 initramfs 中的驱动,挂载根分区,然后启动 systemd(CentOS 7+ 的初始化系统),最终完成用户登录界面的加载。

相关文件

shell
/boot/
/boot/vmlinuz-<内核版本>  # 内核文件
/boot/initramfs-<内核版本>.img  # 初始化内存盘文件

# 配置文件
主配置文件:/boot/grub2/grub.cfg(自动生成,不建议手动修改)。
自定义配置目录:/etc/grub.d/(存放自定义引导项脚本,修改后需更新 grub.cfg)。
默认引导项配置:/etc/default/grub(设置默认启动内核、超时时间等基础参数)。

在 CentOS 中,启动后执行脚本主要通过系统服务(systemd)、rc.local 文件和用户级配置三种方式实现,其中 systemd 是 CentOS 7 及以后版本的推荐标准

方式一:systemd(推荐)

这种方式最规范,支持开机自启、状态管理和日志查看,适用于需要后台运行或依赖系统资源的脚本。

shell
# 第一步:在/usr/lib/systemd/system/目录下新建服务文件,例如my-script.service,内容如下:
[Unit]
Description=My Startup Script  # 服务描述
After=network.target           # 定义服务启动顺序,确保网络就绪后再启动

[Service]
Type=simple                   # 服务类型,simple表示脚本前台运行(若脚本自身后台运行则用forking)
ExecStart=/home/script.sh     # 脚本的绝对路径
User=root                     # 执行脚本的用户,可改为其他普通用户
Restart=no                    # 脚本退出后是否重启,按需设置yes/no

[Install]
WantedBy=multi-user.target    # 设定服务在多用户模式(正常系统运行模式)下启动

# 第二步:刷新服务并设置自启
systemctl daemon-reload # 重新加载systemd配置,识别新服务
systemctl enable my-script.service # 设置服务开机自启
systemctl start my-script.service # 手动启动服务(验证是否正常运行)
systemctl status my-script.service # 查看服务状态

方式二:通过 rc.local 文件

适用于临时测试或简单脚本,无需复杂配置,但优先级低于 systemd 服务。

shell
# 第一步:开启 /etc/rc.d/rc.local 权限
chmod +x /etc/rc.d/rc.local

# 第二步:编辑 rc.local 加入脚本路径
vim /etc/rc.d/rc.local

# 启动后执行我的脚本
/home/script.sh

# 重启系统后,通过脚本输出的日志或效果确认是否执行(例如脚本中可写日志到/var/log/my-script.log)。

方式三:用户级配置

若脚本只需在特定用户登录(如图形界面或 SSH 登录)后执行,而非系统启动时执行

shell
# bash 用户:编辑~/.bashrc或~/.bash_profile,在末尾添加脚本路径
/home/script.sh

# 图形界面用户
 “设置 - 会话和启动” 中添加 “自定义命令”,选择脚本路径并设置 “启动时运行”。

三种方式对比

shell
实现方式         适用场景               优点                       缺点
systemd服务      系统级脚本、后台服务   规范、支持状态管理、日志完整   配置稍复杂
rc.local     简单脚本、临时测试       配置简单、直接               优先级低、不支持状态管理
用户级配置     仅当前用户需要的脚本   不影响其他用户               需用户登录后才执行

主要包括:系统登录、终端会话、用户在线等痕迹

系统日志存储痕迹路径(最关键)

shell
/var/log/messages # 系统通用日志,包含内核、服务等大部分操作。
/var/log/secure   # 用户认证日志,如 SSH 登录、sudo 操作。
/var/log/lastlog  # 记录所有用户最后一次登录时间。

系统登录的历史痕迹

  1. last 登录的历史痕迹
shell
# 基础语法
last [选项] [用户名] [终端]

# 常用选项
-n <>:显示最近的指定数量的记录,例如 last -n 10 显示最近 10 条记录
-f <>:从指定文件(而非默认的 /var/log/wtmp)读取数据
-t <>:显示指定时间之前的记录,时间格式为 YYYYMMDDHHMMSS
-i:显示 IP 地址而非主机名
-w:显示完整的用户名和主机名
-x:显示系统关闭、重启等更多信息
-R:不显示主机名或 IP 地址

# 示例
last  # 显示所有登录历史(默认按时间倒序)
last -n 5 # 显示最近 5 条登录记录:
last root # 显示系统重启记录

# last -n 3 结果
root     pts/0        100.104.125.146  Fri Oct 31 08:51   still logged in
root     pts/0        100.104.125.146  Fri Oct 31 08:51 - 08:51  (00:00)
root     pts/0        100.104.125.184  Thu Oct 30 16:44 - 17:15  (00:30)

# 结果解析
第一列:用户名(reboot 表示系统重启)
第二列:登录终端(pts/0 表示远程登录,tty1 表示本地终端)
第三列:登录来源(IP 地址或主机名)
第四列及以后:登录时间、注销时间和在线时长

# 注意
last 命令通常需要 root 权限才能查看完整的历史记录,普通用户可能只能看到自己的登录记录
last 主要从 /var/log/wtmp 文件中读取数据(该文件记录了系统的登录相关事件)
  1. lastb 查看失败的登录尝试记录的命令
shell
# 基础语法
lastb # 显示所有失败登录记录
lastb username # 显示指定用户的失败登录记录
lastb -s today # 显示今天失败登录记录

# 结果
admin    ssh:notty    139.19.117.197   Wed Oct  1 05:06 - 05:06  (00:00)
admin    ssh:notty    139.19.117.197   Wed Oct  1 04:06 - 04:06  (00:00)
root     ssh:notty    186.122.177.159  Wed Oct  1 03:34 - 03:34  (00:00)

# 结果解析
第一列      用户名(USER) 尝试登录的账号,如 root、ubuntu,若为 unknown 表示用户名未识别。
第二列    终端(TTY) 登录使用的终端设备:ssh:notty:通过 SSH 远程登录(无交互终端),tty1-tty7:本地控制台登录。
第三列      来源(FROM) 登录的来源地址:IP 或主机名
第四列      时间信息       登录尝试开始时间 - 登录结束时间
第五列      持续时间       失败登录持续时间为 0,成功登录会显示实际在线时长

# 文件所在
lastb 主要读取 /var/log/btmp 文件(该文件专门记录失败的登录信息),并以用户友好的格式展示这些记录

# 作用
有助于系统管理员检测可能的暴力破解或未授权登录尝试
  1. lastlog 查看系统中所有用户最后一次登录信息
shell
# 基础语法
lastlog [选项] 只

# 选项
lastlog -u root # 只显示 root 用户的最后登录信息
lastlog -t 5 # 显示最近 5 天内登录过的用户
lastlog -b 30 # 显示30天前登录过的用户

# 结果
用户名         端口     来自             最后登录时间
root          pts/0    192.168.1.100 10月 31 08:30:15 +0800 2025
daemon                               **从未登录过**
bin                                  **从未登录过**
sys                                  **从未登录过**
sync                                 **从未登录过**
games                                **从未登录过**
...
user1         pts/1    192.168.1.101 10月 30 15:45:32 +0800 2025

# 文件所在
/var/log/lastlog  # 此文件会随着系统用户的增加而增大

用户终端操作痕迹 history

展示信息:终端会话的命令记录

shell
# 历史会话:查看、删除
history # 示当前用户在终端中执行过的所有命令,每条命令前会带有编号
history 10 # 查看最近10条命令
history -c # 清除当前会话的历史记录,此命令不会清空 ~/.bash_history文件,所以需要同时删除~/.bash_history文件(rm -f ~/.bash_history),避免历史记录残留。
vi ~/.bash_history # 编辑历史文件,删除指定行

# history命令读取的文件路径
cat ~/.bash_history # 当前用户的 bash 命令历史

用户在线痕迹 w who pwd

shell
w  # 此命令,查看系统中所有在线的用户信息,
展示信息:系统时间,开机时常,当前登录的用户数,系统在 1 分钟、5 分钟、15 分钟前的平均负载(越小越好)
登录的用户,登录的终端、来源 ip,登录时间,用户闲置时间,所有进程占用 cpu 的时间,当前进程占用 cpu 时间,用户正在进行的操作
USER     TTY     FROM                   LOGIN@      IDLE       JCPU           PCPU                  WHAT
用户     终端    来源ip(本地为 -    登录时间    闲置时间   所有占用cpu    当前占用cpu           用户正在进行的操作(-bash 在等待)

who  # 查看当前用户信息,展示信息:用户名,登录端口,登录时间(来源ip)

pwd  # 查看当前路径