关联/ var / log / *时间戳


20

/var/log/messages/var/log/syslog和其他一些日志文件使用包含绝对时间的时间戳,例如Jan 13 14:13:10

/var/log/Xorg.0.log/var/log/dmesg以及输出一样$ dmesg,使用的格式类似于

[50595.991610] malkovich: malkovich malkovich malkovich malkovich

我猜/收集的数字代表自启动以来的秒和微秒。

但是,我尝试将这两组时间戳关联起来(使用的输出uptime)产生了大约5000秒的差异。

这大约是我的计算机被暂停的时间。

有没有简便的方法可以将dmesg和Xorg使用的数字时间戳映射到绝对时间戳?

更新

为了弄清楚这个问题的初步步骤,并希望使我的问题更加清楚,我编写了一个Python脚本来解析/var/log/syslog和输出时间偏差。在运行ubuntu 10.10的计算机上,该文件包含许多内核起源的行,这些行都标记了dmesg时间戳和syslog时间戳。该脚本为该文件中包含内核时间戳的每一行输出一行。

用法:

python syslogdriver.py /var/log/syslog | column -nts $'\t'

输出增加(请参阅下面的列定义):

abs              abs_since_boot  rel_time      rel_offset  message
Jan 13 07:49:15  32842.1276569   32842.301498  0           malkovich malkovich

... rel_offset为0,所有介入的行...

Jan 13 09:55:14  40401.1276569   40401.306386  0           PM: Syncing filesystems ... done.
Jan 13 09:55:14  40401.1276569   40401.347469  0           PM: Preparing system for mem sleep
Jan 13 11:23:21  45688.1276569   40402.128198  -5280       Skipping EDID probe due to cached edid
Jan 13 11:23:21  45688.1276569   40402.729152  -5280       Freezing user space processes ... (elapsed 0.03 seconds) done.
Jan 13 11:23:21  45688.1276569   40402.760110  -5280       Freezing remaining freezable tasks ... (elapsed 0.01 seconds) done.
Jan 13 11:23:21  45688.1276569   40402.776102  -5280       PM: Entering mem sleep

... rel_offset对于所有其余行是-5280 ...

Jan 13 11:23:21  45688.1276569   40403.149074  -5280       ACPI: Preparing to enter system sleep state S3
Jan 13 11:23:21  45688.1276569   40403.149477  -5280       PM: Saving platform NVS memory
Jan 13 11:23:21  45688.1276569   40403.149495  -5280       Disabling non-boot CPUs ...
Jan 13 11:23:21  45688.1276569   40403.149495  -5280       Back to C!
Jan 13 11:23:21  45688.1276569   40403.149495  -5280       PM: Restoring platform NVS memory
Jan 13 11:23:21  45688.1276569   40403.151034  -5280       ACPI: Waking up from system sleep state S3

...最后几行从下到下,仍远高于输出的末尾。 其中一些可能是在dmesg发生挂起之前写入了的循环缓冲区,并仅在syslog之后传播。这就解释了为什么它们都具有相同的syslog时间戳。

列定义:

abs 是syslog记录的时间。

abs_since_boot是自系统启动以来以秒为单位的相同时间,基于的内容/proc/uptime和的值time.time()

rel_time 是内核时间戳。

rel_offsetabs_since_boot和之间的区别是rel_time。我将其舍入为数十秒,以避免由于绝对(即syslog-生成)时间戳仅具有秒精度而导致的一次性错误。这实际上不是正确的方法,因为它确实(我认为..)只会导致产生小于10的错误的机会较小。如果有人有更好的主意,请告诉我。

我也对syslog的日期格式有一些疑问。特别是,我想知道是否有一年。我猜不是,在任何情况下都可能会帮助自己解决TFM中的信息,但是如果有人碰巧知道它会很有用。..当然,假设有人在将来的某个时候使用此脚本,而不是仅仅破坏了几行Perl代码。

下一个:

因此,除非你们中的一个给予我一些可喜的启示,否则我的下一步将是添加一个函数,以获取给定内核时间戳的时间偏差。我应该能够将一个或一组syslog以及内核时间戳一起提供给脚本,以获得绝对时间戳。然后,我可以重新调试我的Xorg问题,此问题目前已解决。


1
我认为这被视为错误,应予以报告。BTW syslog-ng使用合理的时间戳,您可以对它们进行排序sort,具有年份,时区等。python脚本为+1。
stribika 2011年

@stribika:那是内核问题还是系统日志问题?或两者?似乎需要通知syslog系统已被挂起..也许它可以通过挂起和恢复挂接本身来做到这一点。
直觉

在我看来,内核似乎有问题。rel_time值不会“跳过”系统挂起的时间。但是,我发现奇怪的是,在实际发生挂起之前就开始出现歪斜。这些值已经是错误的,Freezing user space processes因为在睡眠之前显然已经完成了这些值。
stribika 2011年

2
@stribika:我的工作原理是,这些事件要等到恢复后才推送到syslog,因为它们是在syslog本身被挂起之后发生的。
直觉

@stribika:另外,您对内核处于“错误状态”是正确的:据我了解(重新考虑之后),syslog只是将绝对时间戳记添加到[12345.6789]..内核发出的文本(以开头)的前缀,因此它可以正确地执行操作,但要以我上次评论所解决的问题为准。我不确定内核在这里到底应该做什么?这取决于那些相对于启动的时间戳意味着什么。 在某些情况下,运行时间(而不是自启动以来的时间)可能很有意义。我想理想情况下,这两个值都会有可靠的记录。
直觉

Answers:


4

有趣的问题,不确定我是否曾经尝试过这样做。但是我注意到您正在谈论的时间戳记,而且我一直认为它距启动仅几秒钟。

在我的服务器上的系统日志中,我有:

Jan 10 19:58:55 wdgitial kernel: [    0.000000] Initializing cgroup subsys cpuset
Jan 10 19:58:55 wdgitial kernel: [    0.000000] Initializing cgroup subsys cpu
Jan 10 19:58:55 wdgitial kernel: [    0.000000] Linux version 2.6.32-21-server (buildd@yellow) (gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5) ) #32-Ubuntu SMP Fri Apr 16     09:17:34 UTC 2010 (Ubuntu 2.6.32-21.32-server 2.6.32.11+drm33.2)
Jan 10 19:58:55 wdgitial kernel: [    0.000000] Command line:  root=/dev/xvda1 ro quiet splash

我想这在大多数Linux发行版中是相当一致的,因为这是内核吐出的东西。

这里有日期和时间戳。


3

您可以尝试一下:

首先,获取dmesg文件的时间戳(我的假设是这将是dmesg的时间0)。您将使用

ls -l --time-style = +%s

/var/log$ ls -l --time-style=+%s dmesg
-rw-r----- 1 root adm 56181 1294941018 dmesg

您可以通过以下方式将秒转换为人类可读的日期

perl -e 'print scalar localtime(1294941018)' 

因此,要查看可读的事件时间,请在dmesg中添加事件发生后的秒数。如果dmesg事件为55.290387秒,请添加55或55.290387:

perl -e 'print scalar localtime(1294953978 + 55)'

将以秒为单位的秒转换为可读时间的另一种方法是按照建议使用date -d。如果您告诉'date'代表-d所提供的时间,则可以使用@指示要转换的时间以秒为单位。

date -d "@1294953978"

这将为您提供类似“ CST 2011 Thu Jan 13 15:26:18 Cst 2011”的输出。

日期+%s
将以秒-自纪元格式打印当前时间。

我不记得如何进行外壳数学运算,因此通常使用上述的perl方法。:)


1
@jgbelacqua:您想要date -d @$((1294953978 + 55)),至少在bash下。但是,某些内核时间戳是不正确的,这意味着此方法产生的时间将早于它们中相应的时间戳/var/log/syslog。看起来这是由于RAM挂起事件而发生的,大概是休眠状态,可能还有其他原因,因为在这些时间段内内核时间没有增加。有关更多信息,请参阅问题更新。
直觉

2

将数字从dmesg映射到日期的最简单方法是使用该date程序。

date -d "-50595 seconds"

此命令显示当前时间减去50595秒的日期。

来自man date

-d, --date=STRING
       display time described by STRING, not `now'

该数字等于开机时间,而不是自启动时间以来经过的时间。


2

由于您已注意到暂停/恢复期间的时间偏差发生了变化,因此我将在至少一个地方对此进行记录。dmesg(1)手册页显示:

挂起/恢复系统后,用于日志的时间源不会更新。

我找不到使内核使这些时间戳与墙上时间保持同步的方法。


1

快速,肮脏,有效。

$ dmesg | grep 3w | perl /root/print_time_offset.pl

该脚本的内容:

$ cat /root/print_time_offset.pl

#!/usr/bin/perl

$uptime = `cat /proc/uptime | awk '{print $1}';`;
$boot = time() - $uptime;
chomp $boot;
while (<STDIN>) {
        if ($_ =~ /^\[([\s\d\.]+)\]/) {
                $time_offset = $1;
        }
        $real_time = sprintf scalar localtime($boot + $time_offset);
        $_ =~ s/\[[\s\d\.]+\]/\[$real_time\]/;
        print $_;
}

示例输出如下:

[Mon Feb 21 23:06:33 2011] 3ware 9000 Storage Controller device driver for Linux v2.26.02.012.
[Mon Feb 21 23:06:33 2011] 3w-9xxx 0000:03:00.0: PCI INT A -> GSI 16 (level, low) -> IRQ 16
[Mon Feb 21 23:06:33 2011] 3w-9xxx 0000:03:00.0: setting latency timer to 64
[Mon Feb 21 23:06:33 2011] scsi4 : 3ware 9000 Storage Controller
[Mon Feb 21 23:06:33 2011] 3w-9xxx: scsi4: Found a 3ware 9000 Storage Controller at 0xfbcde000, IRQ: 16.
[Mon Feb 21 23:06:34 2011] 3w-9xxx: scsi4: Firmware FE9X 4.08.00.006, BIOS BE9X 4.08.00.001, Ports: 4.
[Mon Feb 21 23:06:35 2011] 3w-9xxx: scsi4: ERROR: (0x03:0x0101): Invalid command opcode:opcode=0x85.
[Mon Feb 21 23:06:35 2011] 3w-9xxx: scsi4: ERROR: (0x03:0x0101): Invalid command opcode:opcode=0x85.
[Mon Feb 21 23:06:35 2011] 3w-9xxx: scsi4: ERROR: (0x03:0x0101): Invalid command opcode:opcode=0x85.
[Mon Feb 21 23:06:35 2011] 3w-9xxx: scsi4: ERROR: (0x03:0x0101): Invalid command opcode:opcode=0x85.
[Mon Feb 21 23:06:35 2011] 3w-9xxx: scsi4: ERROR: (0x03:0x0101): Invalid command opcode:opcode=0x85.
[Mon Feb 21 23:06:35 2011] 3w-9xxx: scsi4: ERROR: (0x03:0x0101): Invalid command opcode:opcode=0x85.
[Sat Feb 26 02:01:01 2011] 3w-9xxx: scsi4: AEN: INFO (0x04:0x0029): Verify started:unit=0, subunit=1.
[Sat Feb 26 02:01:01 2011] 3w-9xxx: scsi4: AEN: INFO (0x04:0x0029): Verify started:unit=0, subunit=0.
[Sat Feb 26 16:49:13 2011] 3w-9xxx: scsi4: AEN: INFO (0x04:0x002B): Verify completed:unit=0, subunit=1.
[Sat Feb 26 17:07:19 2011] 3w-9xxx: scsi4: AEN: INFO (0x04:0x002B): Verify completed:unit=0, subunit=0.
[Sat Mar  5 02:00:16 2011] 3w-9xxx: scsi4: AEN: INFO (0x04:0x0029): Verify started:unit=0, subunit=1.
[Sat Mar  5 02:00:16 2011] 3w-9xxx: scsi4: AEN: INFO (0x04:0x0029): Verify started:unit=0, subunit=0.
[Sat Mar  5 18:48:57 2011] 3w-9xxx: scsi4: AEN: INFO (0x04:0x002B): Verify completed:unit=0, subunit=1.
[Sat Mar  5 19:05:17 2011] 3w-9xxx: scsi4: AEN: INFO (0x04:0x002B): Verify completed:unit=0, subunit=0.
[Sat Mar 12 02:00:30 2011] 3w-9xxx: scsi4: AEN: INFO (0x04:0x0029): Verify started:unit=0, subunit=1.
[Sat Mar 12 02:00:30 2011] 3w-9xxx: scsi4: AEN: INFO (0x04:0x0029): Verify started:unit=0, subunit=0.

1
我猜您只阅读了问题的前几段。再次详细检查。或者,尝试挂起计算机并检查脚本是否正确报告了新记录消息的绝对时间戳。
直觉
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.