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

## 今回導入した機能

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


![index.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699739/324a3457-43e3-d309-d45c-53c580ad46c6.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を作成する

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

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

##### 例 : index.html
```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
```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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699739/541574e7-9a8b-5d99-1991-93f599ef1ef9.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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699739/a1f532f6-4f36-9bab-bcf7-60ea01ba15e8.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で公開できるよう準備