|
Surface Go 2 on Ubuntu Serverでサイネージのハングアップを検知する
Surface Go 2 on Ubuntu Serverでサイネージのハングアップを検知する
概要
更新履歴
- 2026/05/28 初版
- 2026/05/29 サービスの有効化について追記
目次
はじめに
-
Surface GoにUbuntuをインストールしてChroniumでサイネージを運用してるが,サイネージのWebブラウザが何かしらの理由でハングアップした事例が発生.
- プロセスは起動したままで,CPUリソースも普通に動作している.しかし画面が再描画されない.
- よって,この表示上の不具合を検知して対処するために,5分後にスクリーンショットを撮って画像を保存し,再度撮影.画像に差分がない場合,表示エラーがでていると判断してOS再起動をさせる.
- 実現方法は次の通り.
- ImageMagickのimportコマンドを使ってデスクトップを撮影.
- compareコマンドで画像を比較し,差分が小さければサイネージの表示機能がフリーズしていると判断し,OS再起動して復旧を試みる.
環境準備
ツールのインストール(ImageMagick)
ujpadmin@namba:~$ sudo apt install imagemagick🆑
[sudo] password for server:
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages were automatically installed and are no longer required:
gstreamer1.0-gl gstreamer1.0-x libaa1 libavtp0 libdca0
libdirectfb-1.7-7t64 libdv4t64 libdvdnav4 libdvdread8t64 libfaad2
libfluidsynth3 libgles2 libgraphene-1.0-0
libgssdp-1.6-0 libgstreamer-gl1.0-0 libgstreamer-plugins-bad1.0-0
libgstreamer-plugins-good1.0-0 libgupnp-1.6-0 libgupnp-igd-1.6-0
libinstpatch-1.0-2 liblrdf0
libltc11 libmfx1 libmicrohttpd12t64 libmjpegutils-2.1-0t64
libmodplug1 libmpcdec6 libmpeg2encpp-2.1-0t64 libmplex2-2.1-0t64
libmysqlclient21 libneon27t64 libnice10
libopenh264-7 libopenni2-0 libpq5 libraptor2-0 libshout3
libsoundtouch1 libspandsp2t64 libsrtp2-1 libtag1v5 libtag1v5-vanilla
libvo-aacenc0 libvo-amrwbenc0
libwavpack1 libwildmidi2 libyajl2 libzbar0t64 libzxing3 mysql-common timgm6mb-soundfont
Use 'sudo apt autoremove' to remove them.
The following additional packages will be installed:
imagemagick-6.q16 libnetpbm11t64 netpbm
Suggested packages:
imagemagick-6-doc autotrace cups-bsd | lpr | lprng enscript gimp
gnuplot grads graphviz hp2xx html2ps libwmf-bin mplayer povray radiance
sane-utils texlive-base-bin
transfig libraw-bin xdg-utils
The following NEW packages will be installed:
imagemagick imagemagick-6.q16 libnetpbm11t64 netpbm
0 upgraded, 4 newly installed, 0 to remove and 43 not upgraded.
Need to get 2,436 kB of archives.
After this operation, 9,727 kB of additional disk space will be used.
Do you want to continue? [Y/n] y🆑
ー略ー
スクリーンショット比較テスト
- 今回はリモートから接続しているのでDISPLAY環境変数を使っている.
- スクリーンショットを取得.
ujpadmin@namba:~$ DISPLAY=:0 import -window root /tmp/signage_now.png🆑
ujpadmin@namba:~$
- 画面を変更(何かウインドウを開くなど)したあと,2階目のスクリーンショットを取る.
ujpadmin@namba:~$ DISPLAY=:0 import -window root /tmp/signage_now2.png🆑
ujpadmin@namba:~$
ujpadmin@namba:~$ compare -metric RMSE /tmp/signage_now2.png /tmp/signage_now.png /tmp/diff.png 2>&1🆑
4678 (0.0713816)
ujpadmin@namba:~$
- 画像の差分が出た.コンかテストでは,画面上に表示されている時計部分が変わっただけの状態.
- 4678がピクセル単位のRMS数.括弧内の数値が正規化RMSの値.
- 正規化RMS数値については次のように考えられる.
- 0 に近いほど「完全に同じ画像」
- 0.001 以下 → ほぼ変化なし(ハングアップ疑い)
- 0.005 以上 → 画面が変化している(正常)
- 数値的な過程では次のように考えられる.
実際のサイネージでの典型値
| 状況 | compare の RMSE 値 | 判定 |
|---|
| 完全に同じフレーム | 0.00000〜0.00010 | 固定画面 | | 1px の変化(時計の点滅など) | 0.00010〜0.00050 | ほぼ固定 | | ページの自動更新・軽微なアニメ | 0.001〜0.005 | 正常 | | 明確に画面が変わっている | 0.01〜0.5 | 正常 | | 全く別の画面 | 0.2〜1.0 | 正常 |
ハングアップ検出スクリプト
-
スクリーンショットでハングアップを検出し,指定されたメールアドレスにスクリーンショットと共にメールを送信する.
ujpadmin@namba:~$ sudo vi /usr/local/bin/check_signage.sh🆑
ujpadmin@namba:~$ cat /usr/local/bin/check_signage.sh🆑
#!/bin/bash
export DISPLAY=:0
IMG_NOW="/tmp/signage_now.png"
IMG_PREV="/tmp/signage_prev.png"
DIFF="/tmp/signage_diff.png"
THRESHOLD=0.001
MAIL_TO="メール@アドレス"
send_alert_mail() {
local diff_value="$1"
local hostname=$(hostname)
local now=$(date '+%Y-%m-%d %H:%M:%S')
local boundary="=====BOUNDARY_$(date +%s)==="
{
echo "To: ${MAIL_TO}"
echo "Subject: [Signage Alert] Chromium hang detected on ${hostname}"
echo "MIME-Version: 1.0"
echo "Content-Type: multipart/mixed; boundary=\"$boundary\""
echo ""
echo "--$boundary"
echo "Content-Type: text/plain; charset=UTF-8"
echo ""
echo "Signage hang detected."
echo "Host: ${hostname}"
echo "Time: ${now}"
echo "Diff value: ${diff_value}"
echo ""
echo "Screenshot is attached."
echo "System will reboot now."
echo ""
echo "--$boundary"
echo "Content-Type: image/png"
echo "Content-Disposition: attachment; filename=\"signage_now.png\""
echo "Content-Transfer-Encoding: base64"
echo ""
base64 "$IMG_NOW"
echo ""
echo "--$boundary--"
} | /usr/sbin/sendmail -t
}
# ---- スクリーンショット撮影 ----
import -window root "$IMG_NOW"
# 初回は比較せず終了
if [ ! -f "$IMG_PREV" ]; then
cp "$IMG_NOW" "$IMG_PREV"
exit 0
fi
# ---- 差分計算 ----
DIFF_VALUE=$(compare -metric RMSE "$IMG_PREV" "$IMG_NOW" "$DIFF" 2>&1 | awk '{print $2}' | tr -d '()')
# 数値比較
awk -v diff="$DIFF_VALUE" -v th="$THRESHOLD" 'BEGIN { exit (diff < th ? 0 : 1) }'
IS_HUNG=$?
if [ $IS_HUNG -eq 0 ]; then
echo "Signage appears frozen. Sending alert mail and rebooting..."
send_alert_mail "$DIFF_VALUE"
sleep 3
systemctl reboot
else
echo "Signage OK. Updating previous image."
cp "$IMG_NOW" "$IMG_PREV"
fi
$ sudo chmod +x /usr/local/bin/check_signage.sh🆑
ujpadmin@namba:~$
- 動作テストのために,THRESHOLDをTHRESHOLD=0.05などに変更してコマンドを実行してみる.
- 次のようなメールが来る.
サービスとして登録
ujpadmin@namba:~$ sudo vi /etc/systemd/system/check_signage.service🆑
ujpadmin@namba:~$ cat /etc/systemd/system/check_signage.service🆑
[Unit]
Description=Check signage hangup
[Service]
Type=oneshot
ExecStart=/usr/local/bin/check_signage.sh
ujpadmin@namba:~$
ujpadmin@namba:~$ sudo vi /etc/systemd/system/check_signage.timer🆑
ujpadmin@namba:~$ cat /etc/systemd/system/check_signage.timer🆑
[Unit]
Description=Run signage check every 5 minutes
[Timer]
OnBootSec=1min
OnUnitActiveSec=5min
[Install]
WantedBy=timers.target
ujpadmin@namba:~$
ujpadmin@namba:~$ sudo systemctl daemon-reload🆑
ujpadmin@namba:~$ sudo systemctl enable --now check_signage.timer🆑
Created symlink /etc/systemd/system/timers.target.wants/check_signage.timer → /etc/systemd/system/check_signage.timer.
ujpadmin@namba:~$
|
|