Sometimes we underestimate the existence of logs. For the system administrator logs are important. From the log, we can analyze what causes an error. dmesg is a command that print kernel messages into your screen. Dmesg print its data by reading the kernel ring buffer.
The data can be information about processor, hard disk, printer, keyboard, memory and drivers. Since dmesg read all messages from kernel ring buffer which is a real-time data, the output messages can be long messages.
How to run dmesg
You can type dmesg on your console. Here’s a sample print out of dmesg without any parameter.
$ dmesg
Sample output :
[ 0.000000] Initializing cgroup subsys cpuset [ 0.000000] Initializing cgroup subsys cpu [ 0.000000] Linux version 3.8.0-31-generic (buildd@aatxe) (gcc version 4.7.3 (Ubuntu/Linaro 4.7.3-1ubuntu1) ) #46-Ubuntu SMP Tue Sep 10 19:56:49 UTC 2013 (Ubuntu 3.8.0-31.46-generic 3.8.13.8) [ 0.000000] KERNEL supported cpus: [ 0.000000] Intel GenuineIntel [ 0.000000] AMD AuthenticAMD [ 0.000000] NSC Geode by NSC [ 0.000000] Cyrix CyrixInstead [ 0.000000] Centaur CentaurHauls [ 0.000000] Transmeta GenuineTMx86 [ 0.000000] Transmeta TransmetaCPU [ 0.000000] UMC UMC UMC UMC
dmesg output is divided into 3 parts.
- Time : this show you number of seconds from the boot time. If you find 20.091730. It is mean the message is created 20 second after boot time.
- Device_name : this show you the device name
- Messages : this is the actual message. From here, we can analyze what was happen.
Why we need dmesg
Here’s some real example on my computer. I had this error when open Chrome browser.
When I check via dmesg, I got this message.
Now it’s clear for me that the cause of the error was Out of Memory. It happened when I tried to open more than 15 tabs. So next time, I will aware that I should not open more than 15 tabs.
1) Using dmesg with pipe ( | ) sign
Run dmesg without parameter will produce a long messages. To make it easier to read, combine it with pipe ( | ) sign. Here’s some examples.
Print dmesg output per page
$ dmesg | less
Sample output :
[ 0.000000] Initializing cgroup subsys cpuset [ 0.000000] Initializing cgroup subsys cpu [ 0.000000] Linux version 3.8.0-31-generic (buildd@aatxe) (gcc version 4.7.3 (Ubuntu/Linaro 4.7.3-1ubuntu1) ) #46-Ubuntu SMP Tue Sep 10 19:56:49 UTC 2013 (Ubuntu 3.8.0-31.46-generic 3.8.13.8) [ 0.000000] KERNEL supported cpus: [ 0.000000] Intel GenuineIntel [ 0.000000] AMD AuthenticAMD [ 0.000000] NSC Geode by NSC [ 0.000000] Cyrix CyrixInstead [ 0.000000] Centaur CentaurHauls [ 0.000000] Transmeta GenuineTMx86 [ 0.000000] Transmeta TransmetaCPU [ 0.000000] UMC UMC UMC UMC
Print information related to eth
$ dmesg | grep eth
Sample output :
[ 1.972418] e1000 0000:00:03.0 eth0: (PCI:33MHz:32-bit) 08:00:27:d2:c1:16 [ 1.972430] e1000 0000:00:03.0 eth0: Intel(R) PRO/1000 Network Connection [ 18.867656] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready [ 21.733138] e1000: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX [ 21.737967] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready [ 21.738052] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
Print information related to USB
$ dmesg | grep usb
Sample output :
[ 0.131874] ACPI: bus type usb registered [ 0.131910] usbcore: registered new interface driver usbfs [ 0.131921] usbcore: registered new interface driver hub [ 0.131955] usbcore: registered new device driver usb [ 1.091722] usb usb1: New USB device found, idVendor=1d6b, idProduct=0001 [ 1.091727] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1 [ 1.091730] usb usb1: Product: OHCI Host Controller [ 1.091731] usb usb1: Manufacturer: Linux 3.8.0-31-generic ohci_hcd [ 1.091733] usb usb1: SerialNumber: 0000:00:06.0
Please notice that grep command is case-sensitive. ie from the above example "usb" and "USB" give different results. To ignore case-sensitive feature, use -i parameter after grep command. Compare this command output with USB case above.
$ dmesg | grep -i usb
Sample output :
[ 0.131874] ACPI: bus type usb registered [ 0.131910] usbcore: registered new interface driver usbfs [ 0.131921] usbcore: registered new interface driver hub [ 0.131955] usbcore: registered new device driver usb [ 0.997759] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver [ 0.997783] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver [ 0.997929] ohci_hcd 0000:00:06.0: new USB bus registered, assigned bus number 1 [ 1.091722] usb usb1: New USB device found, idVendor=1d6b, idProduct=0001 [ 1.091727] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1 [ 1.091730] usb usb1: Product: OHCI Host Controller [ 1.091731] usb usb1: Manufacturer: Linux 3.8.0-31-generic ohci_hcd [ 1.091733] usb usb1: SerialNumber: 0000:00:06.0 [ 1.091856] hub 1-0:1.0: USB hub found [ 1.093110] uhci_hcd: USB Universal Host Controller Interface driver
2) Print with human readable time
By default, the timestamp from dmesg output is not human readable. To make it human readable, you can use - -ctime parameter.
$ dmesg - -ctime
Sample output :
[Tue Dec 10 16:34:33 2013] 131MB HIGHMEM available. [Tue Dec 10 16:34:33 2013] 891MB LOWMEM available. [Tue Dec 10 16:34:33 2013] mapped low ram: 0 - 37bfe000 [Tue Dec 10 16:34:33 2013] low ram: 0 - 37bfe000 [Tue Dec 10 16:34:33 2013] Zone ranges: [Tue Dec 10 16:34:33 2013] DMA [mem 0x00010000-0x00ffffff] [Tue Dec 10 16:34:33 2013] Normal [mem 0x01000000-0x37bfdfff] [Tue Dec 10 16:34:33 2013] HighMem [mem 0x37bfe000-0x3ffeffff] [Tue Dec 10 16:34:33 2013] Movable zone start for each node [Tue Dec 10 16:34:33 2013] Early memory node ranges [Tue Dec 10 16:34:33 2013] node 0: [mem 0x00010000-0x0009efff] [Tue Dec 10 16:34:33 2013] node 0: [mem 0x00100000-0x3ffeffff
Please notice that -ctime parameter may not accurate IF you do SUSPEND/RESUME.
3) dmesg is not showing the timestamp in the output
This is one of the common problems faced by linux admins and users who are working on unix-like-operating-systems. Here we can see in the below output where the timestamps are not being shown in dmesg output.
$ dmesg IPv6: ADDRCONF(NETDEV_UP): enp0s3: link is not ready e1000: enp0s3 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX IPv6: ADDRCONF(NETDEV_UP): enp0s3: link is not ready IPv6: ADDRCONF(NETDEV_CHANGE): enp0s3: link becomes ready bridge: automatic filtering via arp/ip/ip6tables has been deprecated. Update your scripts to load br_netfilter if you need this. Netfilter messages via NETLINK v0.30. ip_set: protocol 6
In such case, we can use the below command to find if the timestamps are enabled.
$ cat /sys/module/printk/parameters/time N
Here it shows the timestamps are not enabled for this. We can use the below command to enable the same.
$ echo Y > /sys/module/printk/parameters/time $ cat /sys/module/printk/parameters/time Y
After enabling the timestamps, Now dmesg will display the timestamps too as follows:
$dmesg | tail -15 [ 49.834670] IPv6: ADDRCONF(NETDEV_UP): enp0s3: link is not ready [ 49.839367] e1000: enp0s3 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX [ 49.843175] IPv6: ADDRCONF(NETDEV_UP): enp0s3: link is not ready [ 49.843198] IPv6: ADDRCONF(NETDEV_CHANGE): enp0s3: link becomes ready [ 50.373814] bridge: automatic filtering via arp/ip/ip6tables has been deprecated. Update your scripts to load br_netfilter if you need this. [ 50.562062] Netfilter messages via NETLINK v0.30. [ 50.589251] ip_set: protocol 6
4) Don’t print timestamp
If you don’t want to see timestamp, you can use -t parameter
$ dmesg -t
Sample output :
Bluetooth: Core ver 2.16 NET: Registered protocol family 31 Bluetooth: HCI device and connection manager initialized Bluetooth: HCI socket layer initialized Bluetooth: L2CAP socket layer initialized Bluetooth: SCO socket layer initialized Bluetooth: BNEP (Ethernet Emulation) ver 1.3 Bluetooth: BNEP filters: protocol multicast Bluetooth: BNEP socket layer initialized
5) Display facility list
dmesg can also only print message from particular category or facility. To fulfill this purpose, use --facility paramater
$ dmesg --facility=daemon
Sample output :
[ 1.325619] udevd[95]: starting version 175 [ 18.946799] udevd[446]: starting version 175
That option will print messages from system daemon only.
Supported log facilities are :
kern - kernel messages user - random user-level messages mail - mail system daemon - system daemons auth - security/authorization messages syslog - messages generated internally by syslogd lpr - line printer subsystem news - network news subsystemt
6) Print log level
dmesg can also print log based on level. To print output like this, use - -level parameter
$ dmesg - -level=err
Sample output :
[ 0.000000] tsc: Fast TSC calibration failed [ 19.595760] piix4_smbus 0000:00:07.0: SMBus base address uninitialized - upgrade BIOS or use force_addr=0xaddr
This option will print error messages only.
Supported levels are :
emerg - system is unusable alert - action must be taken immediately crit - critical conditions err - error conditions warn - warning conditions notice - normal but significant condition info - informational debug - debug-level messages
7) Decode facility and level (priority) number
You can put information about facility and level number without using --facility or --level parameter. Use -x parameter to decode facility and level number into human readable prefixes.
$ dmesg -x
Sample output :
kern :debug : [ 0.000000] e820: remove [mem 0x000a0000-0x000fffff] usable kern :info : [ 0.000000] e820: last_pfn = 0x3fff0 max_arch_pfn = 0x1000000 kern :debug : [ 0.000000] MTRR default type: uncachable kern :debug : [ 0.000000] MTRR variable ranges disabled: kern :info : [ 0.000000] x86 PAT enabled: cpu 0, old 0x7040600070406, new 0x7010600070106 kern :info : [ 0.000000] CPU MTRRs all blank - virtualized system.
8) Clear dmesg output
If you need to clear the ring buffer message, you can use -c parameter
$ dmesg -c
This parameter will produce dmesg output then deleted it. You must have root privilege to do this action. Otherwise, you will have an error message like this :
pungki@dev-machine:~$ dmesg -c dmesg: klogctl failed: Operation not permitted
If you are using -C parameter (capital C), then the logs will be immediately deleted. This parameter also need root privilege.
$ dmesg -C
Is it really deleted?
If you accidentally delete the logs using -c or -C parameters, this not really delete the logs. You can still view the logs by accessing file /var/log/kern.log or /var/log/dmesg
9) Displaying desired output using head and tail with pipe symbol
For example, we have inserted a removable device or made changes to any disk volumes. In such cases we can check the latest entries of dmesg by using the tail command.
$ dmesg | tail -15
Above command will produce the last 15 lines of the dmesg log. Please find below the sample output using the above command. Please note that here it is showing the latest changes happened in my personal machine.
$ dmesg | tail -15 [ 49.834670] IPv6: ADDRCONF(NETDEV_UP): enp0s3: link is not ready [ 49.839367] e1000: enp0s3 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX [ 49.843175] IPv6: ADDRCONF(NETDEV_UP): enp0s3: link is not ready [ 49.843198] IPv6: ADDRCONF(NETDEV_CHANGE): enp0s3: link becomes ready [ 50.373814] bridge: automatic filtering via arp/ip/ip6tables has been deprecated. Update your scripts to load br_netfilter if you need this. [ 50.562062] Netfilter messages via NETLINK v0.30. [ 50.589251] ip_set: protocol 6
Similarly, we can use the head command to find the first few lines from dmesg log. This will be useful to find the changes happened just after booting up.
$ dmesg | head -15
By using the tail -f option we can continuously monitor dmesg log for any new entries. It is recommended always to keep a tab open for dmesg and do the changes in other tabs simultaneously and keep checking the dmesg log for any errors.
$tail -f /var/log/dmesg
Above command will keep displaying the latest log entries of /var/log/dmesg.
10) Increase dmesg buffer size
Allocating sufficient buffer size is very important to make sure that we are not losing any messages which have to be recorded in dmesg logs.
log_buf_len=
We can add the above parameter in /etc/default/grub to allocate the desired buffer size to dmesg as follows:
$vi /etc/default/grub GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=cl/root rd.lvm.lv=cl/swap rhgb quiet log_buf_lenn=5M"
After making above changes , we have to regenerate the grub.conf file as follows:
$grub2-mkconfig --output=/boot/grub2/grub.conf
11) Find dmesg from the previous session
Whenever we start/reboot the linux machine new dmesg will be created under /var/log as a dmesg log file
dmesg logs from previous sessions are log-rotated to the same path (/var/log). We can find the boot messages of the last session from this log file.
/var/log/dmesg.old
We can check the details of the log file using cat , head or tail
Important things to remember about dmesg
There is a misconception that, dmesg is read from /var/log/dmesg which is not true.
Actually, dmesg reads from kernel ring buffer and gives the latest messages from it. Dmesg writes the boot messages to /varlog/dmesg.
Best practices
Always use dmesg with --ctime or -T option to read the timings in human readable formats which makes understanding easier.
Wrapping up
Dmesg can be useful for diagnosing problems related to the system. dmesg records every message since the machine is boot-up. Dmesg also records all system changes that occur in real time. This is one of the Linux commands that must be known by System Administrator. As always, you can type "man dmesg" to get more detailed information.
This is your friend
$ dmesg –-ctime
not
$ dmesg –ctime
Thank you very much for you feedback. Its now fixed.