您可以检查系统日志文件中/var/log/syslog是否有指示挂起/休眠/恢复事件的消息,并查看它们的时间戳。
对于挂起和恢复,检查例如这个模式:
grep -E 'PM: suspend (entry|exit)' /var/log/syslog
Run Code Online (Sandbox Code Playgroud)
示例输出:
Sep 8 09:43:26 type40mark3 kernel: [150509.893804] PM: suspend entry (deep)
Sep 8 15:03:39 type40mark3 kernel: [150514.147721] PM: suspend exit
Sep 8 16:33:41 type40mark3 kernel: [155914.275076] PM: suspend entry (deep)
Sep 8 17:04:58 type40mark3 kernel: [155919.343276] PM: suspend exit
Run Code Online (Sandbox Code Playgroud)
这仅检查当前的 syslog 文件,但由于它受日志轮换的影响,旧消息将存档在编号和压缩文件中,例如/var/log/syslog.1和/var/log/syslog.2.gz。要一次检查所有这些,请zgrep改用它,它可以读取压缩文件,并sort在实际时间戳日期之前按顺序恢复它们:
zgrep -hE 'PM: suspend (entry|exit)' /var/log/syslog* | sort -M
Run Code Online (Sandbox Code Playgroud)
要仅获取最后两行(通常为最后挂起和恢复),您可以附加| tail -n 2到上述任一命令。
如果您只想挂起或仅恢复,请将过滤器模式更改为 egPM: suspend entry或PM: suspend exit。
我现在没有可用的休眠系统来搜索该事件的适当消息,但我希望有类似的东西。尝试搜索,例如grep hiber /var/log/syslog找到合适的模式。当您有一个时,请发表评论,我很乐意将其添加到此答案中以供将来参考。
但是请注意时间戳并将它们与您知道的实际实时时间进行比较,因为一些“延迟”消息systemd[1]: Started Suspend.可以在系统实际关闭之前触发,但实际上会被记录并写入磁盘,时间戳为当它再次打开时。
正如我评论 Byte Commader 的响应一样,出于某种原因,至少在我的两个 Ubuntu 16 安装中,“PM:挂起”和“PM:恢复”事件似乎都在恢复期间写入了系统日志。因此,该解决方案中的暂停时间与恢复时间在一秒之内。不过,恢复时间是正确的。
所以这个解决方案不是基于日志文件的。它基于非常简单的连续运行的服务并监视睡眠前后的时间差。如果差异远大于睡眠时间,则存在“暂停”,例如挂起/恢复操作。唤醒后同步时间时会记录暂停。
pauselogger.sh
set -e
if [[ "$#" < 1 || "$#" > 1 ]]
then
echo "Illegal number of parameters"
echo "Usage $0 <sleeptime in seconds>"
exit 1
fi
sleepTime=$1
fileName="/var/log/state.log"
dateStr1=$(date "+%Y-%m-%d %T.%N %z %s")
dateInt1=$(echo $dateStr1 | cut -d' ' -f4)
dateInt2=$dateInt1
dateStr2=$dateStr1
diff=0
for (( ; ; ))
do
diff="$(($dateInt1-$dateInt2))"
maxDiff=$(echo $sleepTime*1.1 + 1 | bc) # Pause is 10% longer than sleep.
if (( $(echo "$diff > $maxDiff" |bc -l) )); then
echo "$dateStr2 DOWN pre sleep" >> $fileName
echo "$dateStr1 UP post sleep $diff" >> $fileName
fi
dateStr2=$dateStr1
dateInt2=$dateInt1
sleep $sleepTime
dateStr1=$(date "+%Y-%m-%d %T.%N %z %s")
dateInt1=$(echo $dateStr1 | cut -d' ' -f4)
done
Run Code Online (Sandbox Code Playgroud)
服务定义也是简单的文件:/etc/systemd/system/pauselogger.service
[Unit]
Description=Simple Pause Logger
[Service]
ExecStart=/usr/sbin/pauselogger.sh 30
Restart=on-failure
[Install]
WantedBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)
然后启动并启用记录器:
sudo systemctl start pauselogger
sudo systemctl enable pauselogger
Run Code Online (Sandbox Code Playgroud)
日志档案:
2019-09-13 00:44:17.602146211 +0300 1568324657 UP post sleep 225
2019-09-13 01:04:59.968326886 +0300 1568325899 DOWN pre sleep
2019-09-13 10:25:18.575107533 +0300 1568359518 UP post sleep 33619
2019-09-13 10:49:41.594151484 +0300 1568360981 DOWN pre sleep
2019-09-13 10:51:57.129617072 +0300 1568361117 UP post sleep 136
Run Code Online (Sandbox Code Playgroud)
该解决方案的优点是,尽管有暂停命令,它仍然可以工作。如果使用操作系统级别的挂起/休眠/恢复,它会记录暂停,但如果在虚拟机内使用它也可以工作,例如 VirtualBox savestate/resume。
缺点是至少两个日志条目都是在唤醒期间写入的,该解决方案不适合,例如,如果需要在保存状态操作之前启动脚本。此外,不会记录导致睡眠/唤醒的命令:操作系统挂起与 VirtualBox savestate 或操作系统恢复与 VirtualBox 启动。