Запуск команды dmesg выдает сообщения ядра, которые могут быть крайне полезными при диагностике ошибок в системе. По-умолчанию вывод выглядит так:
[ 1.395260] Adding 2097148k swap on /dev/xvda1. Priority:-1 extents:1 across:2097148k SS [ 1.475155] EXT4-fs (xvda2): re-mounted. Opts: errors=remount-ro [ 3.312940] ADDRCONF(NETDEV_UP): eth0: link is not ready [ 3.511496] udevd[298]: starting version 175 [ 4.324542] init: failsafe main process (420) killed by TERM signal [ 7.570289] init: udev-fallback-graphics main process (631) terminated with status 1 [ 14.760020] eth0: no IPv6 routers present [ 136.420113] postgres (1792): /proc/1792/oom_adj is deprecated, please use /proc/1792/oom_score_adj instead. [88098.612698] init: hvc0 main process ended, respawning
В начале каждой строки указано время, прошедшее с момента старта системы, до наступления события. Пожалуй, нам будет удобнее вывести время в понятном для человека формате — с указанием реальной даты и времени.
Вывод времени события в логе dmesg будет отличаться для разных систем.
Содержание
dmesg — Debian и Ubuntu
В дистрибутивах на базе Debian вывод времени события выполнить очень просто. Вместо использования dmesg можно вывести содержимое файла /var/log/kern.log
Мы получим тот же самый вывод, только в удобном формате
dmesg в Fedora, CentOS, RedHat
В дистрибутивах Linux на базе RedHat система не ведет лога, аналогичного /var/log/kern.log.
Чтобы вывести информацию dmesg в удобном формате с указанием времени и даты, можно использовать небольшой скрипт на Perl или Python:
Версия скрипта для вывода даты и времени dmesg на Perl
#!/usr/bin/perl
use strict;
use warnings;
my @dmesg_new = ();
my $dmesg = "/bin/dmesg";
my @dmesg_old = `$dmesg`;
my $now = time();
my $uptime = `cat /proc/uptime | cut -d"." -f1`;
my $t_now = $now - $uptime;
sub format_time {
my @time = localtime $_[0];
$time[4]+=1; # Adjust Month
$time[5]+=1900; # Adjust Year
return sprintf '%4i-%02i-%02i %02i:%02i:%02i', @time[reverse 0..5];
}
foreach my $line ( @dmesg_old )
{
chomp( $line );
if( $line =~ m/\[\s*(\d+)\.(\d+)\](.*)/i )
{
# now - uptime + sekunden
my $t_time = format_time( $t_now + $1 );
push( @dmesg_new , "[$t_time] $3" );
}
}
print join( "\n", @dmesg_new );
print "\n";
Модификация вывода dmesg на Python
#!/usr/bin/env python
# coding=utf8
# Copyright (C) 2010 Saúl ibarra Corretgé <saghul@gmail.com>
#
"""
pydmesg: dmesg with human-readable timestamps
"""
from __future__ import with_statement
import re
import subprocess
import sys
from datetime import datetime, timedelta
_datetime_format = "%Y-%m-%d %H:%M:%S"
_dmesg_line_regex = re.compile("^\[(?P<time>\d+\.\d+)\](?P<line>.*)$")
def exec_process(cmdline, silent, input=None, **kwargs):
"""Execute a subprocess and returns the returncode, stdout buffer and stderr buffer.
Optionally prints stdout and stderr while running."""
try:
sub = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)
stdout, stderr = sub.communicate(input=input)
returncode = sub.returncode
if not silent:
sys.stdout.write(stdout)
sys.stderr.write(stderr)
except OSError,e:
if e.errno == 2:
raise RuntimeError('"%s" is not present on this system' % cmdline[0])
else:
raise
if returncode != 0:
raise RuntimeError('Got return value %d while executing "%s", stderr output was:\n%s' % (returncode, " ".join(cmdline), stderr.rstrip("\n")))
return stdout
def human_dmesg():
now = datetime.now()
uptime_diff = None
try:
with open('/proc/uptime') as f:
uptime_diff = f.read().strip().split()[0]
except IndexError:
return
else:
try:
uptime = now - timedelta(seconds=int(uptime_diff.split('.')[0]), microseconds=int(uptime_diff.split('.')[1]))
except IndexError:
return
dmesg_data = exec_process(['dmesg'], True)
for line in dmesg_data.split('\n'):
if not line:
continue
match = _dmesg_line_regex.match(line)
if match:
try:
seconds = int(match.groupdict().get('time', '').split('.')[0])
nanoseconds = int(match.groupdict().get('time', '').split('.')[1])
microseconds = int(round(nanoseconds * 0.001))
line = match.groupdict().get('line', '')
t = uptime + timedelta(seconds=seconds, microseconds=microseconds)
except IndexError:
pass
else:
print "[%s]%s" % (t.strftime(_datetime_format), line)
if __name__ == '__main__':
human_dmesg()
Вставьте указанный код в файл, сделайте его выполнимым и запустите. После запуска вы получите вывод команды dmesg в удобном формате — с датой и временем.
Русский
Спасибо за скрипт на perl!
Воспользовался скриптом на Perl. Работает!
Спасибо