#!/usr/bin/env zsh indent=" " # Ref: https://gitlab.gnome.org/GNOME/gnome-shell/issues/1 function skip-crap { local datep="[0-9][0-9]:[0-9][0-9]:[0-9][0-9]: " local crap_start="^${datep}Object [^ ]+ \(.*\), has been already finalized. Impossible to \w* any property \w* it.*" local crap_continue=( "^${datep}== Stack trace for context.*" "^${datep}#[0-9]+\s*0x.*" ) local skip=0 local skipped=0 local begin_skip_date # Could probably be done more elegantly with awk/sed ? while IFS=$'\n' read -r line; do if [[ $line =~ $crap_start ]]; then # echo setting skip skip=1 begin_skip=$line ((skipped += 1)) continue fi if [[ $skip == 1 ]]; then if [[ ($line =~ $crap_continue[1]) || ($line =~ $crap_continue[2]) ]]; then ((skipped += 1)) continue else # echo reset skip echo -E "$begin_skip" printf "${indent}... skipped \"already finalized\" crap ($skipped lines)\n" skip=0 skipped=0 fi fi echo -E "$line" done } # We use non-breaking space to encode newlines in multiline messages function decode-multiline-message { stdbuf -oL sed -e 's| |\n |g' } function gnome-shell-exe-path { if systemctl --user status gnome-shell-x11.service > /dev/null; then echo --user-unit=gnome-shell-x11.service elif systemctl --user status gnome-shell-wayland.service > /dev/null; then echo --user-unit=gnome-shell-wayland.service elif uname -a | grep --silent "NixOS"; then echo $(dirname =gnome-shell(:A))/.gnome-shell-wrapped else echo =gnome-shell fi } function procees { jq --unbuffered --raw-output ' {ts: .__REALTIME_TIMESTAMP, message: .MESSAGE} | @sh "TS=\(.ts); MESSAGE=\(.message)\u0000" ' | while read -r -d $'\0' DATA; do eval $DATA TS=$((TS/1000000)) PP_TS=$(date -d @${TS} +'%T') if [[ $MESSAGE == *$'\n'* ]]; then echo $PP_TS: echo -E $MESSAGE | sed 's/^/ /' else echo -E "$PP_TS: $MESSAGE" fi done } journalctl --follow --lines 400 -o json --output-fields MESSAGE \ $@ $(gnome-shell-exe-path) \ | procees \ | skip-crap \ | decode-multiline-message