|
| 1 | +--- |
| 2 | +author: Major Hayden |
| 3 | +date: '2025-02-16' |
| 4 | +summary: | |
| 5 | + A recent switch back to i3 (from sway) left me wondering how to examine just the Xorg logs sent to journald. |
| 6 | +tags: |
| 7 | + - 4runner |
| 8 | + - repair |
| 9 | + - toyota |
| 10 | +title: Viewing Xorg logs with journalctl in Fedora |
| 11 | +coverAlt: High altitude view of an island with mountains and a beach |
| 12 | +coverCaption: | |
| 13 | + [Reinaldo Photography](https://unsplash.com/photos/an-aerial-view-of-a-small-island-in-the-middle-of-the-ocean-4I0kdYvHJAI) via Unsplash |
| 14 | +--- |
| 15 | + |
| 16 | +I love being an early adopter and trudging off into the unknown. |
| 17 | +After all, that's one of the best ways to learn new things and you end up improving the experience for everyone who comes behind you. |
| 18 | +However, things can get a little frustrating from time to time especially when your daily work dictates that your desktop works really well. 😉 |
| 19 | + |
| 20 | +Sway has been my desktop of choice for a few years and although it seems to work well, I ran into lots of issues with Wayland. |
| 21 | +It was easy to plot a course around most of these problems, but not all of them. |
| 22 | + |
| 23 | +I've recently run back to safety with my old, trusty, i3 window manager in Xorg. |
| 24 | +Then I realized a few of my Xorg configuration weren't taking effect and I couldn't figure out how to isolate the Xorg logs in the system journal to narrow down the problem. |
| 25 | + |
| 26 | +Skip to the end if you're short on time or peruse the next section if you haven't been deep in the innards of your system journal in a while. 🔍 |
| 27 | + |
| 28 | +## Journal metadata |
| 29 | + |
| 30 | +Every journal entry in journald has metadata attached to it which you can use to filter the logs. |
| 31 | +Most people know about filtering based on systemd services, like this: |
| 32 | + |
| 33 | +```text |
| 34 | +> journalctl --boot --unit chronyd.service | head |
| 35 | +systemd[1]: Starting chronyd.service - NTP client/server... |
| 36 | +chronyd[2662]: chronyd version 4.6.1 starting (+CMDMON +NTP +REFCLOCK +RTC +PRIVDROP +SCFILTER +SIGND +ASYNCDNS +NTS +SECHASH +IPV6 +DEBUG) |
| 37 | +chronyd[2662]: Using leap second list /usr/share/zoneinfo/leap-seconds.list |
| 38 | +chronyd[2662]: Frequency -3.595 +/- 6.086 ppm read from /var/lib/chrony/drift |
| 39 | +chronyd[2662]: Loaded seccomp filter (level 2) |
| 40 | +systemd[1]: Started chronyd.service - NTP client/server. |
| 41 | +chronyd[2662]: Added source 192.168.10.1 |
| 42 | +chronyd[2662]: Selected source 208.67.72.50 (2.fedora.pool.ntp.org) |
| 43 | +chronyd[2662]: System clock TAI offset set to 37 seconds |
| 44 | +chronyd[2662]: Selected source 173.73.96.68 (2.fedora.pool.ntp.org) |
| 45 | +``` |
| 46 | + |
| 47 | +This command shows all of the messages from the `chronyd` service since the last boot. |
| 48 | +However, we can get much more specific with our filtering using other criteria. |
| 49 | + |
| 50 | +## Examining metadata |
| 51 | + |
| 52 | +You can examine the metadata behind each log line with the json output in journalctl: |
| 53 | + |
| 54 | +```text |
| 55 | +> journalctl --boot --unit chronyd.service -o json -n 1 | jq |
| 56 | +{ |
| 57 | + "_CMDLINE": "/usr/sbin/chronyd -F 2", |
| 58 | + "_SYSTEMD_CGROUP": "/system.slice/chronyd.service", |
| 59 | + "_MACHINE_ID": "xxxxx", |
| 60 | + "_UID": "990", |
| 61 | + "SYSLOG_TIMESTAMP": "Feb 16 13:55:59 ", |
| 62 | + "__SEQNUM_ID": "c94633ee6da2480ca4602ca6ab47f82a", |
| 63 | + "_PID": "2662", |
| 64 | + "PRIORITY": "6", |
| 65 | + "_HOSTNAME": "zorro", |
| 66 | + "_SYSTEMD_SLICE": "system.slice", |
| 67 | + "SYSLOG_FACILITY": "3", |
| 68 | + "_GID": "989", |
| 69 | + "_SYSTEMD_INVOCATION_ID": "156fce8836374564b01aeb6628160ccb", |
| 70 | + "__CURSOR": "s=c94633ee6da2480ca4602ca6ab47f82a;i=19fb3a;b=ed9e1fccb1744136a3d726bbf2425388;m=33abfdf67;t=62e47cbf2b72f;x=f9a8d4e3bc4fef30", |
| 71 | + "__MONOTONIC_TIMESTAMP": "13870554983", |
| 72 | + "_SOURCE_REALTIME_TIMESTAMP": "1739735759501027", |
| 73 | + "_TRANSPORT": "syslog", |
| 74 | + "_EXE": "/usr/sbin/chronyd", |
| 75 | + "_SYSTEMD_UNIT": "chronyd.service", |
| 76 | + "SYSLOG_IDENTIFIER": "chronyd", |
| 77 | + "_BOOT_ID": "ed9e1fccb1744136a3d726bbf2425388", |
| 78 | + "__REALTIME_TIMESTAMP": "1739735759501103", |
| 79 | + "__SEQNUM": "1702714", |
| 80 | + "_RUNTIME_SCOPE": "system", |
| 81 | + "SYSLOG_PID": "2662", |
| 82 | + "_CAP_EFFECTIVE": "2000400", |
| 83 | + "MESSAGE": "Selected source 173.73.96.68 (2.fedora.pool.ntp.org)", |
| 84 | + "_COMM": "chronyd", |
| 85 | + "_SELINUX_CONTEXT": "system_u:system_r:chronyd_t:s0" |
| 86 | +} |
| 87 | +``` |
| 88 | + |
| 89 | +The most helpful one for us is `_COMM_`. |
| 90 | +We can use it to limit our search solely to Xorg logs. |
| 91 | + |
| 92 | +Every Xorg startup has a line with the Xorg version that looks like this: |
| 93 | +`X.Org X Server 1.21.1.15`. |
| 94 | +Let's search for that: |
| 95 | + |
| 96 | +```text |
| 97 | +> journalctl --boot -o json | grep -i "x.org x server" | jq |
| 98 | +{ |
| 99 | + "_HOSTNAME": "zorro", |
| 100 | + "_BOOT_ID": "ed9e1fccb1744136a3d726bbf2425388", |
| 101 | + "_SYSTEMD_INVOCATION_ID": "5cf933063b1246909d4ea15e7154bff4", |
| 102 | + "_MACHINE_ID": "xxxxx", |
| 103 | + "__CURSOR": "s=c94633ee6da2480ca4602ca6ab47f82a;i=19de06;b=ed9e1fccb1744136a3d726bbf2425388;m=4597347;t=62e2f4fcc855d;x=b4f482006e1523ff", |
| 104 | + "__MONOTONIC_TIMESTAMP": "72971079", |
| 105 | + "_SYSTEMD_SESSION": "2", |
| 106 | + "_SYSTEMD_SLICE": "user-1000.slice", |
| 107 | + "_SELINUX_CONTEXT": "system_u:system_r:xdm_t:s0-s0:c0.c1023", |
| 108 | + "__SEQNUM_ID": "c94633ee6da2480ca4602ca6ab47f82a", |
| 109 | + "_AUDIT_LOGINUID": "1000", |
| 110 | + "__REALTIME_TIMESTAMP": "1739630597408093", |
| 111 | + "_CMDLINE": "/usr/libexec/Xorg vt2 -displayfd 3 -auth /run/user/1000/gdm/Xauthority -nolisten tcp -background none -noreset -keeptty -novtswitch -verbose 3", |
| 112 | + "_AUDIT_SESSION": "2", |
| 113 | + "_SYSTEMD_USER_SLICE": "-.slice", |
| 114 | + "__SEQNUM": "1695238", |
| 115 | + "_GID": "1000", |
| 116 | + "_RUNTIME_SCOPE": "system", |
| 117 | + "SYSLOG_IDENTIFIER": "/usr/libexec/gdm-x-session", |
| 118 | + "MESSAGE": "X.Org X Server 1.21.1.15", |
| 119 | + "_STREAM_ID": "7f35e3ce14d44dc8b589be76d4d355d9", |
| 120 | + "_TRANSPORT": "stdout", |
| 121 | + "_CAP_EFFECTIVE": "0", |
| 122 | + "_SYSTEMD_UNIT": "session-2.scope", |
| 123 | + "_UID": "1000", |
| 124 | + "_EXE": "/usr/libexec/Xorg", |
| 125 | + "PRIORITY": "4", |
| 126 | + "_COMM": "Xorg", |
| 127 | + "_SYSTEMD_CGROUP": "/user.slice/user-1000.slice/session-2.scope", |
| 128 | + "_SYSTEMD_OWNER_UID": "1000", |
| 129 | + "_PID": "3929" |
| 130 | +} |
| 131 | +``` |
| 132 | + |
| 133 | +Note that the value for `_COMM` is `Xorg`. |
| 134 | +We can use that to search our logs with ease using the `cat` output from journalctl, which makes the output as terse as possible. |
| 135 | +It removes all the headers and make it look like you're reading a plain old text log file: |
| 136 | + |
| 137 | +```text |
| 138 | +> journalctl --output cat --boot _COMM=Xorg | head |
| 139 | +(--) Log file renamed from "/home/major/.local/share/xorg/Xorg.pid-3929.log" to "/home/major/.local/share/xorg/Xorg.0.log" |
| 140 | +X.Org X Server 1.21.1.15 |
| 141 | +X Protocol Version 11, Revision 0 |
| 142 | +Current Operating System: Linux zorro 6.12.13-200.fc41.x86_64 #1 SMP PREEMPT_DYNAMIC Sat Feb 8 20:05:26 UTC 2025 x86_64 |
| 143 | +Kernel command line: BOOT_IMAGE=(hd0,gpt2)/vmlinuz-6.12.13-200.fc41.x86_64 root=UUID=bae22798-ce48-43e9-ac24-7bf7f7158e90 ro rootflags=subvol=root rd.luks.uuid=luks-defea11e-374c-48ab-83df-4f06c4c02186 rhgb quiet |
| 144 | +Build ID: xorg-x11-server 21.1.15-1.fc41 |
| 145 | +Current version of pixman: 0.44.2 |
| 146 | + Before reporting problems, check http://wiki.x.org |
| 147 | + to make sure that you have the latest version. |
| 148 | +Markers: (--) probed, (**) from config file, (==) default setting, |
| 149 | +``` |
| 150 | + |
| 151 | +In my particular case, I was missing the amdgpu driver for Xorg. |
| 152 | +I installed the `xorg-x11-drv-amdgpu` package, rebooted, and now my logs showed the driver being loaded on startup: |
| 153 | + |
| 154 | +```text |
| 155 | +> journalctl --output cat --boot _COMM=Xorg | grep -i amdgpu | head |
| 156 | +(II) Applying OutputClass "AMDgpu" to /dev/dri/card1 |
| 157 | + loading driver: amdgpu |
| 158 | +(==) Matched amdgpu as autoconfigured driver 0 |
| 159 | +(II) LoadModule: "amdgpu" |
| 160 | +(II) Loading /usr/lib64/xorg/modules/drivers/amdgpu_drv.so |
| 161 | +(II) Module amdgpu: vendor="X.Org Foundation" |
| 162 | +(II) AMDGPU: Driver for AMD Radeon: |
| 163 | + All GPUs supported by the amdgpu kernel driver |
| 164 | +(II) AMDGPU(0): Creating default Display subsection in Screen section |
| 165 | +(==) AMDGPU(0): Depth 24, (--) framebuffer bpp 32 |
| 166 | +``` |
| 167 | + |
| 168 | +## Further reading |
| 169 | + |
| 170 | +There are _tons_ of ways to filter journald logs and one of the best resources for learning about all of them is the [journalctl man page](https://www.freedesktop.org/software/systemd/man/latest/journalctl.html). |
| 171 | +There's also a [helpful journalctl cheat sheet](https://gist.github.com/sergeyklay/f401dbc8286f732783e05072f03ecb61) on GitHub. |
0 commit comments