UJP - 技術情報1

Life is fun and easy!

不正IP報告数

Okan Sensor
 
メイン
ログイン
ブログ カテゴリ一覧

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)

  • aptでインストール.
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:~$
  • 5分ごとに実行するタイマーを設定.
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:~$
  • これで終了.

広告スペース
Google