如何获取上次系统休眠/暂停/恢复的日期/时间?

use*_*663 5 resume suspend hibernate

如何获取这些事件的日期/时间:

  • 上次系统休眠/挂起
  • 上次系统恢复

Byt*_*der 7

您可以检查系统日志文件中/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 entryPM: suspend exit


我现在没有可用的休眠系统来搜索该事件的适当消息,但我希望有类似的东西。尝试搜索,例如grep hiber /var/log/syslog找到合适的模式。当您有一个时,请发表评论,我很乐意将其添加到此答案中以供将来参考。

但是请注意时间戳并将它们与您知道的实际实时时间进行比较,因为一些“延迟”消息systemd[1]: Started Suspend.可以在系统实际关闭之前触发,但实际上会被记录并写入磁盘,时间戳为当它再次打开时。


use*_*663 0

正如我评论 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 启动。