LoginSignup
1
0

More than 1 year has passed since last update.

Flaskでラズパイの状態を確認するWebアプリを作ってみた(其の三)

Posted at

今回導入した機能

  • テンプレート継承の導入
  • メモリ・CPU・IOの状態を確認できるように freevmstat コマンドを追加
  • ユーザーログイン認証 (其の四で紹介)
  • SQLite3でのユーザーデータ管理 (其の四で紹介)

index.png

ファイル構成

RaspiApp 
  ├─ static
  |    ├─ css
  |    |   └─ style.css
  |    └─ images
  |        └─ raspi-logo.png
  ├─ templates
  |      ├─ base.html
  |      ├─ get_disk.html
  |      ├─ get_ip_addr.html
  |      ├─ get_mem.html
  |      ├─ get_route.html
  |      ├─ get_socket.html
  |      ├─ get_temp.html
  |      ├─ get_vmstat.html
  |      ├─ index.html
  |      └─ login.html
  └─ raspi_app.py

テンプレート継承の導入

ベース(継承元)となるテンプレート base.htmlを作成する

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>{% block title %} Diagnosis of Raspberry Pi {% endblock %}</title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=M+PLUS+Rounded+1c&family=Ubuntu+Mono&display=swap"
        rel="stylesheet">
    <link rel=stylesheet type=text/css href="{{ url_for('static', filename='css/style.css') }}">
</head>

<body>
    <div class="header">
        <div class="header-img">
            <a href="https://www.raspberrypi.com/" target="_blank" rel="noopener noreferrer"><img
                    src="{{ url_for('static', filename='images/raspi-logo.png') }}" alt="Raspi Logo"></a>
        </div>
        <div class="header-logo">
            Raspberry Pi
        </div>
        {% block headerlist %}
        <div class="header-list">
            <ul>
                <li><a href="{{ url_for('logout') }}">LOGOUT</a></li>
                <li><a href="https://www.raspberrypi.com/documentation/" target="_blank"
                        rel="noopener noreferrer">LINK</a></li>
                <li><a href="{{ url_for('index') }}">HOME</a></li>
            </ul>
        </div>
        {% endblock %}
    </div>

    <div class="main">
        {% block main %}

        <!-- input a code for each file -->

        {% endblock %}
    </div>

    <div class="footer">
        <div class="footer-copyright">
            "Raspberry Pi is a trademark of Raspberry Pi Ltd”<br>
            Software Copyright @CannuWorks
        </div>
    </div>
</body>

</html>

ポイント

  • {% block 任意の文字 %} 継承先ごとで異なる内容 {% endblock %} が基本
    例:{% block title %} Diagnosis of Raspberry Pi {% endblock %}
  • 以下3箇所のブロックを作る
    • <head>内のタイトルの表示 {% block title %}
    • <body>内のヘッダーの表示 {% block header-list %}
    • <main>内のget_xxxメソッドごとの表示テーブルフォーム {% block main %}

継承先のファイルを作成する

例 : index.html
{% extends "base.html" %}      <!-- 継承元のファイル base.htmlを読み込む -->

{% block title %}                  <!-- タイトルを修正 -->
    Diagnosis of Raspberry Pi
{% endblock %}

{% block headerlist %}      <!-- {{ super() }} を使って継承元のブロックの内容をそのまま利用 -->
    {{ super() }}
{% endblock %}

{% block main %}            <!-- 各HTMLファイル毎に表示フォーマットを最適化する -->
    <h2> Diagnosis of Raspberry Pi </h2>
    <ul>
        <h3><a href="{{ url_for('get_ip_addr') }}">Interface IP Address</a></h3>
        <h3><a href="{{ url_for('get_socket') }}">Socket</a></h3>
        <h3><a href="{{ url_for('get_route') }}">IP Routing Table</a></h3>
        <h3><a href="{{ url_for('get_temp') }}">Temparature</a></h3>
        <h3><a href="{{ url_for('get_disk') }}">Disk Usage</a></h3>
        <h3><a href="{{ url_for('get_mem') }}">Memory Usage</a></h3>
        <h3><a href="{{ url_for('get_vmstat') }}">Vmstat</a></h3>
    </ul>
{% endblock %}

例 : get_ip_addr.html
{% extends "base.html" %}   <!-- 継承元のファイル base.htmlを読み込む -->

{% block title %}                  <!-- タイトルを修正 -->
    Interface IP Address
{% endblock %}

{% block headerlist %}      <!-- {{ super() }} を使って継承元のブロックの内容をそのまま利用 -->
    {{ super() }}
{% endblock %}

{% block main %}            <!-- 各HTMLファイル毎に表示フォーマットを最適化する -->
    <h2>Interface IP Address</h2>
    <ul>
        {% for if, addr in result.items()%}
        <h4><li>{{ if }} : {{ addr }}</li></h4>
        {% endfor %}
    </ul>
{% endblock %}

追加したFlaskコード

実行Linuxコマンド

コマンド 内容
free メモリの使用量・空き容量
vmstat 仮想メモリ・CPU・ディスクI/Oの統計情報

メモリの使用量・空き容量

get_mem.png

get_mem.py
# Get memory info via "free --mega -w" command
@app.route('/get_mem')
def get_mem():
    ''' Get memory info via "free --mega -w" command '''

    if not session.get('login'):
        return redirect(url_for('login'))
    else:
        get_socket = subprocess.run(['free', '--mega', '-w'],
                                    stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        cmd_result = get_socket.stdout.decode('utf-8')

        result_list = []

        cmd_result0 = cmd_result.splitlines()
        for line in cmd_result0:
            line0 = line.split()
            result_list.append(line0)

        result_list[0].insert(0, '')
        result_list[2].extend(['', '', '', ''])

        return render_template('get_mem.html', result=result_list)
get_mem.html

<!--- "main"部分のみ記載 --->
{% block main %}

<h2>Memory Usage</h2>
<div class="main-list">
    <ul>
        <table>
            <thead>
                <tr>
                    <div class="main-list">
                        <th colspan="8">Memory (mega byte)</th>
                    </div>
                </tr>
            </thead>
            <tbody>
                {% for i in result %}
                <tr>
                    <div class="main-list">
                        <td>{{ i[0] }}</td>
                        <td>{{ i[1] }}</td>
                        <td>{{ i[2] }}</td>
                        <td>{{ i[3] }}</td>
                        <td>{{ i[4] }}</td>
                        <td>{{ i[5] }}</td>
                        <td>{{ i[6] }}</td>
                        <td>{{ i[7] }}</td>
                    </div>
                </tr>
                {% endfor %}
            </tbody>
        </table>
    </ul>
</div>

{% endblock %}

仮想メモリ・CPU・ディスクI/Oの統計情報

get_vmstat.png

get_vmstat.py
# Get statistics of CPU, Mem, IO
@app.route('/get_vmstat')
def get_vmstat():
    ''' Get statistics of CPU, Mem, IO '''

    if not session.get('login'):
        return redirect(url_for('login'))
    else:
        get_socket = subprocess.run(['vmstat'],
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
        cmd_result = get_socket.stdout.decode('utf-8')

        result_list = []

        cmd_result0 = cmd_result.splitlines()
        for read_line in cmd_result0:
            read_line0 = read_line.split()
            result_list.append(read_line0)

        del result_list[0]

        return render_template('get_vmstat.html', result=result_list)
get_vmstat.html
{% block main %}

<h2>vmstat</h2>
<div class="main-list">
    <ul>
        <table>
            <thead>
                <tr>
                    <div class="main-list">
                        <th colspan="2">Proc</th>
                        <th colspan="4">memory</th>
                        <th colspan="2">swap</th>
                        <th colspan="2">io</th>
                        <th colspan="2">system</th>
                        <th colspan="5">cpu</th>
                    </div>
                </tr>
            </thead>
            <tbody>
                {% for i in result %}
                <tr>
                    <div class="main-list">
                        <td>{{ i[0] }}</td>
                        <td>{{ i[1] }}</td>
                        <td>{{ i[2] }}</td>
                        <td>{{ i[3] }}</td>
                        <td>{{ i[4] }}</td>
                        <td>{{ i[5] }}</td>
                        <td>{{ i[6] }}</td>
                        <td>{{ i[7] }}</td>
                        <td>{{ i[8] }}</td>
                        <td>{{ i[9] }}</td>
                        <td>{{ i[10] }}</td>
                        <td>{{ i[11] }}</td>
                        <td>{{ i[12] }}</td>
                        <td>{{ i[13] }}</td>
                        <td>{{ i[14] }}</td>
                        <td>{{ i[15] }}</td>
                        <td>{{ i[16] }}</td>
                    </div>
                </tr>
                {% endfor %}
            </tbody>
        </table>
    </ul>
</div>

{% endblock %}

まとめ

  • コマンドの追加作業は一旦終了
  • GitHubで公開できるよう準備
1
0
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
1
0