แปลงเวลาประทับของ dmesg เป็นรูปแบบวันที่ที่กำหนดเอง


113

ฉันกำลังพยายามทำความเข้าใจการประทับเวลา dmesg และพบว่าเป็นการยากที่จะแปลงสิ่งนั้นเพื่อเปลี่ยนเป็นวันที่จาวา / รูปแบบวันที่ที่กำหนดเอง

ความช่วยเหลือใด ๆ ที่ชื่นชมมาก

บันทึก dmesg ตัวอย่าง:

[14614.647880] airo(eth1): link lost (missed beacons)

ขอบคุณ!

คำตอบ:


181

การทำความเข้าใจการdmesgประทับเวลานั้นค่อนข้างง่าย: เวลาเป็นวินาทีนับตั้งแต่เคอร์เนลเริ่มทำงาน ดังนั้นเมื่อมีเวลาเริ่มต้น ( uptime) คุณสามารถเพิ่มวินาทีและแสดงในรูปแบบใดก็ได้ที่คุณต้องการ

หรือดีกว่านั้นคุณสามารถใช้-Tตัวเลือกบรรทัดคำสั่งdmesgและแยกวิเคราะห์รูปแบบที่มนุษย์อ่านได้

จากหน้าคน :

-T, --ctime
    Print human readable timestamps. The timestamp could be inaccurate!

    The time source used for the logs is not updated after system SUSPEND/RESUME.

10
คำสั่งใดที่ยอมรับ -T dmesg ของฉันไม่ได้ทั้ง manpage ก็บอกมัน (Linux Mint Debian Edition)
gyorgyabraham

1
Mine ทำ ( dmesgจากutil-linux 2.20.1ภายใต้ Ubuntu 13.04)

2
ไม่มีใน redhat และ / หรือ oracle linux 5.6 rpm -qf /bin/dmesg => util-linux-2.13-0.56.0.2.el5
michael

7
ตัวเลือกนี้ปรากฏขึ้นutil-linux 2.20ตามบันทึกประจำรุ่น: ftp.kernel.org/pub/linux/utils/util-linux/v2.20/…
ks1322

1
@xealits ขอบคุณสำหรับการติดตามนั่นเป็นสิ่งที่ดีสำหรับคุณ :) สำหรับคำถามนี้ฉันคิดว่าส่วนที่เข้าใจนั้นมีน้อยและ "แปลงเพื่อเปลี่ยนเป็น java date / รูปแบบวันที่ที่กำหนดเอง" เป็นส่วนหลัก แต่ความคิดเห็นของคุณอาจแตกต่างกัน ขอให้มีความสุขมาก ๆ นะครับ;)

32

ด้วยความช่วยเหลือของdr answer ฉันเขียนวิธีแก้ปัญหาที่ทำให้การแปลงใส่ใน. bashrc ของคุณ มันจะไม่ทำลายอะไรเลยถ้าคุณไม่มีการประทับเวลาหรือการประทับเวลาที่ถูกต้องแล้ว

dmesg_with_human_timestamps () {
    $(type -P dmesg) "$@" | perl -w -e 'use strict;
        my ($uptime) = do { local @ARGV="/proc/uptime";<>}; ($uptime) = ($uptime =~ /^(\d+)\./);
        foreach my $line (<>) {
            printf( ($line=~/^\[\s*(\d+)\.\d+\](.+)/) ? ( "[%s]%s\n", scalar localtime(time - $uptime + $1), $2 ) : $line )
        }'
}
alias dmesg=dmesg_with_human_timestamps

นอกจากนี้การอ่านที่ดีเกี่ยวกับตรรกะการแปลงการประทับเวลา dmesg และวิธีเปิดใช้งานการประทับเวลาเมื่อไม่มี: https://supportcenter.checkpoint.com/supportcenter/portal?eventSubmit_doGoviewsolutiondetails=&solutionid=sk92677


การปรับปรุงเล็กน้อย: คุณสามารถลบ 'tail -1' ในไปป์ไลน์และปล่อยให้ awk กินเส้นและพิมพ์จากบรรทัดสุดท้ายในบัฟเฟอร์ local dmesg_bin=$(type -a dmesg | awk 'END { print $NF }')
Brian เมื่อ

@ ลูคัส: คุณสามารถอธิบายโดยใช้ 'type -a dmesg | ... ' แทน $ (ซึ่ง dmesg)? มีข้อได้เปรียบกับท่อ 3 ขั้นตอนเพื่อให้ได้เส้นทางนั้นหรือไม่?
Stabledog

@Stabledog: คำถามที่ดี สำหรับคำอธิบายว่าเหตุใดจึงใช้typeover whichโปรดดูคำถามนี้ ฉันแก้ไขคำตอบเพื่อหลีกเลี่ยงท่อสามชั้นที่ไร้ประโยชน์
Lucas Cimon

ตัวอย่าง bash / perl นี้ใช้ได้ผลสำหรับฉันฉันมีเครื่อง RHEL5.7 รุ่นเก่าที่ฉันต้องดูแลและ dmesg ไม่มีตัวเลือกในการพิมพ์การประทับเวลาในเวลาของมนุษย์
Paul M

17

สำหรับระบบที่ไม่มี "dmesg -T" เช่น RHEL / CentOS 6 ฉันชอบฟังก์ชัน "dmesg_with_human_timestamps" ที่มีให้โดยlucas-cimonก่อนหน้านี้ มีปัญหาเล็กน้อยกับบางกล่องของเราที่มีเวลาพร้อมใช้งานมาก ปรากฎว่าการประทับเวลาเคอร์เนลใน dmesg ได้มาจากค่าเวลาทำงานที่เก็บไว้โดย CPU แต่ละตัว เมื่อเวลาผ่านไปสิ่งนี้จะไม่ตรงกับนาฬิกาเวลาจริง ด้วยเหตุนี้การแปลงที่ถูกต้องที่สุดสำหรับรายการ dmesg ล่าสุดจะขึ้นอยู่กับนาฬิกาของ CPU มากกว่า / proc / uptime ตัวอย่างเช่นในกล่อง CentOS 6.6 เฉพาะที่นี่:

# grep "\.clock" /proc/sched_debug  | head -1
  .clock                         : 32103895072.444568
# uptime
 15:54:05 up 371 days, 19:09,  4 users,  load average: 3.41, 3.62, 3.57
# cat /proc/uptime
32123362.57 638648955.00

การคำนวณเวลาทำงานของ CPU เป็นมิลลิวินาทีมีค่าชดเชยเกือบ 5 1/2 ชั่วโมงที่นี่ ดังนั้นฉันจึงแก้ไขสคริปต์และแปลงเป็นทุบตีดั้งเดิมในกระบวนการ:

dmesg_with_human_timestamps () {
    FORMAT="%a %b %d %H:%M:%S %Y"

    now=$(date +%s)
    cputime_line=$(grep -m1 "\.clock" /proc/sched_debug)

    if [[ $cputime_line =~ [^0-9]*([0-9]*).* ]]; then
        cputime=$((BASH_REMATCH[1] / 1000))
    fi

    dmesg | while IFS= read -r line; do
        if [[ $line =~ ^\[\ *([0-9]+)\.[0-9]+\]\ (.*) ]]; then
            stamp=$((now-cputime+BASH_REMATCH[1]))
            echo "[$(date +"${FORMAT}" --date=@${stamp})] ${BASH_REMATCH[2]}"
        else
            echo "$line"
        fi
    done
}

alias dmesgt=dmesg_with_human_timestamps

ฟังก์ชันไม่ทำงานใน zsh ต้องทำในการทุบตีที่เหมาะสม ที่กล่าวว่าในกล่องที่มีเวลาทำงาน 221 วันโซลูชันนี้มีการประทับเวลาลงไปจนถึงนาทีที่แท้จริง วิธีแก้ปัญหาอื่น ๆ แสดงให้เห็นว่าสาเหตุที่แท้จริงของเหตุการณ์ที่เกิดขึ้น 2 ชั่วโมงก่อนหน้านี้ในวันนั้น ขอบคุณอัลเลน คุณบันทึกช่วงบ่ายของฉัน
เทรนตัน

เครื่อง RHEL5.x ไม่มี / proc / sched_debug :-(
Paul M

14

ดังนั้นKevZeroจึงขอวิธีแก้ปัญหา kludgy น้อยลงดังนั้นฉันจึงได้สิ่งต่อไปนี้:

sed -r 's#^\[([0-9]+\.[0-9]+)\](.*)#echo -n "[";echo -n $(date --date="@$(echo "$(grep btime /proc/stat|cut -d " " -f 2)+\1" | bc)" +"%c");echo -n "]";echo -n "\2"#e'

นี่คือตัวอย่าง:

$ dmesg|tail | sed -r 's#^\[([0-9]+\.[0-9]+)\](.*)#echo -n "[";echo -n $(date --date="@$(echo "$(grep btime /proc/stat|cut -d " " -f 2)+\1" | bc)" +"%c");echo -n "]";echo -n "\2"#e'
[2015-12-09T04:29:20 COT] cfg80211:   (57240000 KHz - 63720000 KHz @ 2160000 KHz), (N/A, 0 mBm), (N/A)
[2015-12-09T04:29:23 COT] wlp3s0: authenticate with dc:9f:db:92:d3:07
[2015-12-09T04:29:23 COT] wlp3s0: send auth to dc:9f:db:92:d3:07 (try 1/3)
[2015-12-09T04:29:23 COT] wlp3s0: authenticated
[2015-12-09T04:29:23 COT] wlp3s0: associate with dc:9f:db:92:d3:07 (try 1/3)
[2015-12-09T04:29:23 COT] wlp3s0: RX AssocResp from dc:9f:db:92:d3:07 (capab=0x431 status=0 aid=6)
[2015-12-09T04:29:23 COT] wlp3s0: associated
[2015-12-09T04:29:56 COT] thinkpad_acpi: EC reports that Thermal Table has changed
[2015-12-09T04:29:59 COT] i915 0000:00:02.0: BAR 6: [??? 0x00000000 flags 0x2] has bogus alignment
[2015-12-09T05:00:52 COT] thinkpad_acpi: EC reports that Thermal Table has changed

หากคุณต้องการให้ทำงานได้ดีขึ้นเล็กน้อยให้ใส่เวลาประทับจาก proc ลงในตัวแปรแทน :)


4

ในเวอร์ชันล่าสุดของ dmesg คุณสามารถโทรdmesg -T.


3
RC ได้รับคำตอบเดียวกันนี้เมื่อสองปีก่อนคุณ
josch

4

หากคุณไม่มี-Tตัวเลือกdmesgสำหรับตัวอย่างเช่นบน Andoid คุณสามารถใช้busyboxเวอร์ชันนี้ได้ ต่อไปนี้ยังช่วยแก้ปัญหาอื่น ๆ :

  1. รูปแบบนำโดยสิ่งที่ดูเหมือนว่าข้อมูลสีถูกใส่ผิดชอบคำนำหน้า[0.0000]<6>
  2. สร้างจำนวนเต็มจากการลอย

ได้รับแรงบันดาลใจจากบทความในบล็อกนี้

#!/bin/sh                                                                                                               
# Translate dmesg timestamps to human readable format                                                                   

# uptime in seconds                                                                                                     
uptime=$(cut -d " " -f 1 /proc/uptime)                                                                                  

# remove fraction                                                                                                       
uptime=$(echo $uptime | cut -d "." -f1)                                                                                 

# run only if timestamps are enabled                                                                                    
if [ "Y" = "$(cat /sys/module/printk/parameters/time)" ]; then                                                          
  dmesg | sed "s/[^\[]*\[/\[/" | sed "s/^\[[ ]*\?\([0-9.]*\)\] \(.*\)/\\1 \\2/" | while read timestamp message; do      
    timestamp=$(echo $timestamp | cut -d "." -f1)                                                                       
    ts1=$(( $(busybox date +%s) - $uptime + $timestamp ))                                                               
    ts2=$(busybox date -d "@${ts1}")                                                                                    
    printf "[%s] %s\n" "$ts2" "$message"                                                                                
  done                                                                                                                  
else                                                                                                                    
  echo "Timestamps are disabled (/sys/module/printk/parameters/time)"                                                   
fi                                                                                                                      

อย่างไรก็ตามโปรดทราบว่าการใช้งานนี้ค่อนข้างช้า


3

คุณจะต้องอ้างอิง "btime" ใน / proc / stat ซึ่งเป็นช่วงเวลา Unix เมื่อระบบบูตล่าสุด จากนั้นคุณสามารถอิงตามเวลาบูตระบบนั้นจากนั้นเพิ่มวินาทีที่ผ่านไปที่กำหนดใน dmesg เพื่อคำนวณการประทับเวลาสำหรับแต่ละเหตุการณ์


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.