首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何知道SLES11系统上的系统启动时间?

如何知道SLES11系统上的系统启动时间?
EN

Stack Overflow用户
提问于 2021-05-31 16:02:53
回答 3查看 174关注 0票数 2

我试图计算在SUSE系统(SLES11和SLES12系统)上重新引导所需的时间如下:

代码语言:javascript
复制
reboot_time = end_time - start_time

where
    start_time is "time at which reboot command is triggered"
    end_time   is "time at which system is ready after booting process, finishing up startup and userspace programs" OR "time when login is prompted soon after reboot"

我能认识start_time。但无法了解SLES11系统的time SLES11 (init.d SysV版本)。对于SLES12 (systemd初始化),systemd-analyze给出了所需的信息,但我无法为init.d系统找到可靠的方法。在SysV init系统或SLES11上是否有类似的替代方案,可以让我花在引导上的时间(启动内核、完成启动程序和完成用户空间初始化)?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-08-31 15:09:18

您可以使用以下命令获得(非第二次精确的)最后关机日期

代码语言:javascript
复制
last -x | egrep "shutdown|reboot" | head -1 | awk '{print $5" "$7" "$6" "$8}'

last -x可以为您提供系统启动/重新启动和关闭时间,以及自系统创建以来的所有系统启动日志。问题是不显示年份,而且只有很小的分辨率。

last读取各种日志二进制日志文件(/var/ log /wtmp、utmp和btmp),您可以使用utmpdump实用工具获得关闭&用更精确的时间戳重新启动时间戳

代码语言:javascript
复制
utmpdump /var/log/wtmp | egrep "shutdown|reboot" | awk -F '[' '{print $9}' | sed 's/ ]//g'

最终,您可以使用以下一行(非常长)获得从关机到重新启动所需的时间:

代码语言:javascript
复制
echo "System $(hostname) took $(($(date -d "$(LC_ALL=C utmpdump /var/log/wtmp 2>/dev/null| grep "reboot" | grep -Eo '[[:alpha:]]{3} [[:alpha:]]{3} [[:digit:]]{2} [[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2} [[:digit:]]{4}|[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}T[[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2}' | tail -1)" "+%s") - $(date -d "$(LC_ALL=C utmpdump /var/log/wtmp 2>/dev/null| grep "shutdown" | grep -Eo '[[:alpha:]]{3} [[:alpha:]]{3} [[:digit:]]{2} [[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2} [[:digit:]]{4}|[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}T[[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2}' | tail -1)" "+%s"))) to reboot"

解释:

  • LC_ALL=C将输出以下命令,unlocalized
  • utmpdump /var/log/wtmp 2>/dev/null将列出所有事件,而2>/dev/null将重定向错误,而不必要的output.
  • grep "reboot"grep "shutdown"将筛选utmpdump输出,以显示仅重新启动或关机events
  • '[[:alpha:]]{3} [[:alpha:]]{3} [[:digit:]]{2} [[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2} [[:digit:]]{4}'是捕获非本地化日期字符串的正则表达式,类似于"Fri Aug 02 00:01:27 2019",这些命令用于CentOS
  • '[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}T[[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2}'是捕获看起来类似于"2021-08-17T10:11:03“的ISO 8601日期字符串的regex。这些都用于Debian
  • date -d "datestring",将日期转换为epoch
  • $(command)是command
  • $((x - y))的输出,用于数学运算(如减两个时代)

您还可以使用utmpdump的输出来检索登录时间戳。请注意,关闭/重新启动周期与关闭/系统引导周期不同,因此这些命令必须适应您的使用。还要注意,任何强制的系统重置都不会包含在日志中,因此会给出虚假的值。

票数 1
EN

Stack Overflow用户

发布于 2021-08-31 13:18:25

也许有点麻烦,但您可能只是添加了一个最终执行的脚本,即/etc/init.d/K99WriteShutdownTime (其中K表示关闭脚本,数字越高,执行的时间越晚)。

这个脚本可能包含一些类似的内容

代码语言:javascript
复制
#!/usr/bin/env bash

timestamp_logfile="/var/log/shutdown_timestamp"
date +"%s" > "$timestamp_logfile"

然后,您可以使用另一个脚本(如/etc/init.d/S99WriteGetTime )

代码语言:javascript
复制
#!/usr/bin/env bash

timestamp_logfile="/var/log/shutdown_timestamp"
boot_time_logfile="/var/log/boot_time.log"

if [ -f "$logfile" ]; then
   boot_timestamp=$(date +"%s")
   shutdown_timestamp=$(cat "$timestamp_logfile")
   delta=$((boot_timestamp - shutdown_timestamp))
   echo "$(date +"%Y-%m-%d %H:%M:%S"): It took $delta seconds to boot $(hostname)" >> boot_time_logfile
else
   echo "$(date +"%Y-%m-%d %H:%M:%S"): No prior shutdown time detected. Cannot compute boot time" >> boot_time_logfile
fi
票数 0
EN

Stack Overflow用户

发布于 2021-09-07 08:00:37

在init系统上(如SLES11),只有在启动所有启动程序之后才会向用户显示登录提示。因此,我们可以依赖于从wtmp文件获得登录提示时间(如用户"Orsiris“所建议的那样)。

下面是在上次重新启动后获得登录提示的python脚本。

代码语言:javascript
复制
#!/usr/bin/env python3
import subprocess
import re
from datetime import datetime
from typing import List


class UnableToFindLoginTimeError(Exception):
    pass


class UnexpectedCommandException(Exception):
    pass


class CommandResult:
    def __init__(self, command, stdout, stderr, exit_code):
        self.command = command
        self.stdout = stdout
        self.stderr = stderr
        self.exit_code = exit_code

    def validate(self, check_stderr=True, check_exit_code=True):
        if (check_stderr and self.stderr) or (check_exit_code and self.exit_code != 0):
            raise UnexpectedCommandException('Unexpected command result')


def run_command(command, timeout=600):
    completed_process = subprocess.run(
        command,
        encoding='utf-8',
        timeout=timeout,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        shell=True,
        errors='ignore',
    )
    command_result = CommandResult(
        stdout=completed_process.stdout.strip(),
        stderr=completed_process.stderr.strip(),
        exit_code=completed_process.returncode,
        command=command,
    )
    return command_result


def _extract_data_in_square_brackets(row: str) -> List[str]:
    """
    Extract data within square brackets from a string.

    Example:
    '[One] [Two ] [Three   ] [Wed Aug 25 09:21:59 2021 UTC]'
    returns
    ['One', 'Two', 'Three', 'Wed Aug 25 09:21:59 2021 UTC']
    """
    regex = r'\[(.*?)\]'
    columns_list = re.findall(regex, row)
    return [item.strip() for item in columns_list]


def convert_datetime_string_to_epoch(datetime_str: str) -> int:
    """
    Run following command to automatically parse datetime string (in any valid format) into epoch:
    # date -d '{datetime_str}' +%s

    Note: The Unix epoch is the number of seconds that have elapsed since January 1, 1970 (midnight UTC/GMT).
    At any point of time, epoch will be same throughout all time zones.

    Example: epoch for "Fri Sep  3 11:08:09 UTC 2021" will be 1630667289.
    """
    command_result = run_command(f"date -d '{datetime_str}' +%s")
    command_result.validate()
    epoch = round(float(command_result.stdout.strip()))
    return epoch


def get_login_time_from_wtmp() -> datetime:
    """
    Read through /var/log/wtmp binary file using utmpdump
    and find least LOGIN time after last reboot.

    wtmp gives historical data of utmp (gives information about user logins, logouts, system boot etc.).
    In case of failed logins, we see multiple entries for same tty in the output.
    In such case, we get first occurred entry after last reboot since that is when
    startup processes have been completed and welcome screen appeared.

    Sample:
    -------
    Output:
    [2] [00000] [~~  ] [reboot  ] [~           ] [3.10.0-957.12.2.el7.x86_64] [0.0.0.0        ] [Mon Aug 16 06:21:06 2021 UTC]
    [6] [01828] [tty1] [LOGIN   ] [tty1        ] [                    ] [0.0.0.0        ] [Mon Aug 16 06:21:26 2021 UTC]
    [2] [00000] [~~  ] [reboot  ] [~           ] [3.10.0-957.12.2.el7.x86_64] [0.0.0.0        ] [Wed Aug 25 09:21:34 2021 UTC]
    [6] [01815] [tty1] [LOGIN   ] [tty1        ] [                    ] [0.0.0.0        ] [Wed Aug 25 09:21:59 2021 UTC]

    Returns: "Wed Aug 25 09:21:59 2021 UTC" as datetime object
    """
    command_result = run_command(f'utmpdump /var/log/wtmp | grep -e reboot -e LOGIN')
    command_result.validate(check_stderr=False)
    output = command_result.stdout
    list_of_login_epochs = []
    # read output in reverse order
    for line in output.splitlines()[::-1]:
        if 'reboot' in line:
            # exit loop since we dont require data before last reboot
            break
        items = _extract_data_in_square_brackets(line)
        if 'LOGIN' in items:
            login_time_str = items[-1].strip()
            epoch = convert_datetime_string_to_epoch(login_time_str)
            list_of_login_epochs.append(epoch)

    if not list_of_login_epochs:
        raise UnableToFindLoginTimeError()

    # collect least login time out of all since we need time at which login was prompted first.
    least_epoch = min(list_of_login_epochs)
    login_datetime_object = datetime.utcfromtimestamp(round(least_epoch))
    return login_datetime_object


if __name__ == '__main__':
    print(
        f'Login screen was displayed to user after last reboot at {get_login_time_from_wtmp()} UTC'
    )
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67777065

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档