5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Datadog ダッシュボードを壁紙にして監視する

Last updated at Posted at 2022-11-14

はじめに

弊社のサービスF-Portal/M-Manageの運用監視のためにDatadogを導入しました。
Datadogのダッシュボードにシステムの監視項目をいろいろ設定し、便利に使っています。
しかしこのダッシュボード、当たり前のことなのですがわざわざブラウザでアクセスしないと見ることができません。
不要なPCがあれば、適当なディスプレイに表示させっぱなしにしておけばよいのですが、在宅勤務などで適当な表示環境を用意できないことがあります。

そこで、ダッシュボードのキャプチャ画像をWinowsの壁紙にして、定期的に更新していくようにすれば、作業の合間にチラ見できて便利なのでは。と思いやってみました。

構成

ファイル 役割 説明
C:\適当な場所\datadogWallpaper\
  datadogWallpaper.vbs datadogWallpaper.pyを呼び出す
  datadogWallpaper.py 処理本体
  datadogWallpaper.log ログ(実行後生成)
  dashboard.png 壁紙画像(実行後生成)
  setup.bat スケジューラにセットするバッチ
  setup.xml.template setup.batで利用
  setup.xml setup.batを実行すると生成される

ファイルの解説

datadogWallpaper.py

メイン処理。ダッシュボードを画像化して壁紙にセット。

datadogWallpaper.py
# datadogのdashboardを壁紙化する
import ctypes
import datetime
import os
import time
from datetime import datetime
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager

# ローカル設定
WALLPAPER_SIZE = [1920/1.25, 1080/1.25]  # 1920x1080の125%表示
WAIT = 10  # 描画が終わるまでの待機時間(秒)

# グローバル設定
DATADOG_URL = 'https://p.datadoghq.com/sb/xxxxx?from_ts=0&to_ts=86400000&tv_mode=true&theme=dark'


def main():
    print(f"start {datetime.now()}")
    print(f"WALLPAPER_SIZE={WALLPAPER_SIZE}")
    print(f"WAIT={WAIT}")
    print(f"DATADOG_URL={DATADOG_URL}")

    # 画像取得
    img_file = capture_dashboard()

    # 壁紙に設定
    change_wallpaper(img_file)

    print(f"end {datetime.now()}")
    return


# Datadogの公開ダッシュボードをキャプチャ
def capture_dashboard():
    print("----- capture_dashboard -----")
    img_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), "dashboard.png")
    # print(f"img_file={img_file}")
    # Selenium初期化
    option = Options()
    option.add_argument("--headless")
    option.add_argument("--hide-scrollbars")
    option.add_argument("--incognito")  # シークレッドモード。閲覧履歴を残さないため
    option.add_argument("--disable-extensions")
    option.add_argument(f"--window-size={WALLPAPER_SIZE[0]:.0f},{WALLPAPER_SIZE[1]:.0f}")
    option.add_experimental_option('excludeSwitches', ['enable-logging'])  # debugポートを開けない
    
    driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=option)

    # 公開ダッシュボードに接続してキャプチャ
    driver.get(DATADOG_URL)
    time.sleep(WAIT)  # 描画が終わるまで待機
    driver.save_screenshot(img_file)

    driver.quit()
    return img_file


# 画像を壁紙にセットする
def change_wallpaper(img_file):
    print("----- change_wallpaper -----")
    SPI_SETDESKWALLPAPER = 20  # 壁外変更の定数
    ctypes.windll.user32.SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, img_file , 0)
    return


main()

ソースコード中の設定について

WALLPAPER_SIZE = [1920/1.25, 1080/1.25]  # 1920x1080の125%表示
WAIT = 10  # 描画が終わるまでの待機時間(秒)

WALLPAPER_SIZEは自PCの画面解像度を入力します。
100%で利用しているなら解像度の値そのままですが、125%表示などにしている場合は例のように入力します。

WAITは描画が終わるまでの待機時間です。
Datadogのダッシュボードにアクセスしてもグラフの描画に時間がかかる場合があります。
そのための待ち時間です。
お使いの環境に合わせて適当な値を設定してください。

DATADOG_URL = 'https://p.datadoghq.com/sb/xxxxx?from_ts=0&to_ts=86400000&tv_mode=true&theme=dark'

ダッシュボードを公開したURLを入力します。
パラメータとして
?from_ts=0&to_ts=86400000&tv_mode=true&theme=dark
も付与しています。
to_tsの値によって表示期間を調整することができます。
1日間表示したい場合は86400000ミリ秒(=24時間60分60秒*1000ミリ秒)を設定します。

キャプチャ処理

chrome.exe でキャプチャをするだけならseleniumを使わなくても
chrome.exe –-headless ––screenshot=c:\temp.png http://example.com
で実行することも可能です。
ただ、その場合アクセス完了と同時にキャプチャされてしまうようで、Datadogダッシュボードでは描画待ちの画像になってしまいました。
--virtual-time-budgetのオプションでうまく回避できないかと試したのですが、今回の場合はダメでした。

そのため、seleniumでアクセスして、途中でWAIT秒スリープすることで完全に描画されたものをキャプチャするようにしています。
もっとスマートに描画完了を判断する方法があるのかもしれないですが、このあたりは知識が薄くて調べていません。

chromeの起動オプション

chromeをバックグラウンドで動かすためにheadlessモードで動かすサンプルを探しているとdisable-gpuも指定されているものが多く見つかります。
以前はWindows環境でheadlessを使うときはエラーになるので必須だったようなのですが
これは現在では不要になり、つけなくても動くようになっています。
https://github.com/rails/rails/pull/32488

Seleniumドライバ

Seleniumを使うときにはchromeのバージョンとdriverのバージョンとを一致させる必要があります。
バージョンが一致していないと
This version of ChromeDriver has not been tested with Chrome version XXX
といったエラーになってしまいます。
そこでwebdriver_managerを使うことで自動的にバージョンを合わせるようにしています。
ちなみにこのツールを最初に作った時は、Windows標準環境のままで動かせるようPowerShellで作ったのですが、
このバージョン一致問題をうまく解決する方法がわからず、このライブラリで回避することにしました。

datadogWallpaper.vbs

datadogWallpaper.py をバックグラウンドで動かすためのラッパー。
タスクスケジューラからこれを呼び出します。

datadogWallpaper.vbs
Dim ws
set ws = CreateObject("Wscript.Shell")
ws.CurrentDirectory = createObject("Scripting.FileSystemObject").getParentFolderName(WScript.ScriptFullName)
ws.run "cmd /C python ./datadogWallpaper.py >./datadogWallpaper.log ", 0, True
set ws = Nothing

setup.bat, setup.xml.template

GUIで設定することもできるのですが、定型の設定なのでbatで設定しています

setup.bat
: タスクスケジューラにタスクを設定する

: 設定
INTERVAL=PT5M
WORKINGDIRECTORY=%~dp0

: setup.xmlの生成
echo "" > setup.xml
for /f "delims=" %%line in (setup.xml.template) do (
    set line = %%line
    set line = !line:__INTERVAL__=%INTERVAL%!
    set line = !line:__WORKINGDIRECTORY__=%WORKINGDIRECTORY%!
    echo !line! >> setup.xml
)
SCHTASKS /Create /TN Datadog壁紙 /XML setup.xml

setup.xml.template の __INTERVAL__ , __WORKINGDIRECTORY__ を置換してsetup.xmlを作成し、
それをもとにタスクスケジューラを設定します。

INTERBAL=PT5M は5分間隔の意味です。
WORKINGDIRECTORY=%~dp0 はbatの実行ディレクトリを取得しています。

setup.xml.template(見るべきところがなく、長いので折りたたんでいます)
setup.xml.template
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <Triggers>
    <TimeTrigger>
      <Repetition>
        <Interval>__INTERVAL__</Interval>
        <StopAtDurationEnd>false</StopAtDurationEnd>
      </Repetition>
      <StartBoundary>2022-01-01T00:00:00</StartBoundary>
      <Enabled>true</Enabled>
    </TimeTrigger>
  </Triggers>
  <Principals>
    <Principal>
      <LogonType>InteractiveToken</LogonType>
      <RunLevel>LeastPrivilege</RunLevel>
    </Principal>
  </Principals>
  <Settings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <StartWhenAvailable>false</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <IdleSettings>
      <StopOnIdleEnd>true</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>false</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>PT72H</ExecutionTimeLimit>
    <Priority>7</Priority>
  </Settings>
  <Actions Context="Author">
    <Exec>
      <Command>wscript.exe</Command>
      <Arguments>datadogWallpaper.vbs</Arguments>
      <WorkingDirectory>__WORKINGDIRECTORY__</WorkingDirectory>
    </Exec>
  </Actions>
</Task>

使い方

環境

Windows10環境にて検証しています。

Datadogでの準備

ダッシュボードを作成し、公開します。
生成されたURLを DATADOG_URL に設定します。

このダッシュボードURLには接続元のIP制限をかけることもできます。

自PCでの準備

Pythonをインストールします。
今回はPython3.10を使っていますが3.xxであれば動くと思います。

pipで以下をインストールします。

pip install selenium
pip install webdriver_manager

なお、Windows環境ではpythonをインストールしただけではpipへのパスが通っていないことがあります。
以下を参考に環境変数PATHを設定します。
https://and-engineer.com/articles/YcJyaRAAACMAl3BX#heading3-7

ファイルの配置

ローカルの適当な場所に、上記構成のようにファイルを配置します。

タスクスケジューラへの設定

タスクスケジューラにdatadogWallpaper.vbsを5分間隔で起動するように設定をします。
GUI上で設定してもよいのですが、設定バッチ(setup.bat)を用意したのでそれを実行することで設定します。

課題

マルチディスプレイ環境の場合、すべて同じ壁紙がセットされます。
こちら↓のようにすれば、別々のものを設定できるようです。
壁紙を変更する (マルチディスプレイ対応版)

Pythonで動かすため、WindowsにPython環境をインストールする必要があります。
seleniumドライバのところにも記載しましたが、PowerShell等を使って、追加で実行環境をインストールすることなくできればベター。

おわりに

この設定をしてから、Datadogのダッシュボードを目にする機会が圧倒的に増え、
いつもよりもアクセス数が多いなどの細かな変化に気が付けるようになりました。

今回はDatadogのダッシュボードを壁紙化しましたが、株価表示などほかにも応用できると思います。
ぜひお試しあれ!

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?