파이썬을 이용한 디스크 SMART 정보 표시 웹페이지 만들기

하드디스크를 오래 사용하다 보면 전기적, 물리적 충격이나 노화에 따라 건강이 나빠질 수 있다.
건강이 나쁘다는 말은 배드 섹터가 생긴다는 말과 같은데, 배드 섹터가 생기기 시작하면 데이터가 유실될 우려가 있으므로 즉시 디스크를 교체해야 한다.
이러한 하드디스크의 건강 상태를 알려주는 정보를 S.M.A.R.T. 라고 한다.
보통은 CrystalDiskInfo나 GM HDD Scan을 이용해서 확인할 수 있다.

하지만, 회사 워크스테이션 등에 들어가는 HDD는 인터페이스가 SAS인 경우가 있는데, 이들은 이러한 프로그램들로 SMART를 볼 수가 없다.
그래서 좀 찾아본 결과, smartctl이란 유틸리티를 이용하면 SAS HDD의 정보를 볼 수 있음을 알게 되었다.
하나 문제는, 콘솔 화면에 정보를 뿌려주기 때문에 보기에 영 불편하고, 매번 명령어를 입력해야 한다는 것이다.
이를 해결하기 위해 파이썬을 이용하였다.

Flask를 이용해서 간단한 웹 서버를 돌리고, 디스크 선택 드롭다운 메뉴와 그에 따른 SMART 정보를 동적으로 띄워주는 페이지 템플릿을 만들었다.
한편, smartctl을 powershell 상에서 실행해서 디스크 목록을 가져와서 웹페이지로 전달하고, 선택된 디스크에 대해서 SMART 정보를 json으로 출력하게 한 뒤, 이를 html로 바꿔서 다시 웹페이지로 전달한다.

코드는 다음과 같다.

import subprocess
import json2html
import json

from flask import Flask, render_template, request, Markup


def get_smart(drive_selected):
    try:
        out = subprocess.Popen(
            ["smartctl", "--json", "-a", drive_selected], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        stdout = out.communicate()[0]
        output = Markup(json2html.json2html.convert(
            json=json.loads(stdout.decode("utf-8"))))
    except subprocess.CalledProcessError:
        return "smartctl failed"
    except Exception as e:
        return e

    return output


def get_drives():
    drives = []
    out = subprocess.Popen(["powershell", "smartctl", "--scan"],
                           stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    output = out.communicate()[0].decode("euc-kr")
    print(output)
    listedOutput = output.split("\n")
    for devinfo in listedOutput:
        drives.append(devinfo.strip("\r").split(" ")[0])
    return drives


app = Flask(__name__)


@app.route('/', methods=['POST', 'GET'])
def view_smart():
    drives = get_drives()
    try:
        drive_selected = request.form['drive_selected']
    except:
        drive_selected = "/dev/sda"

    result = get_smart(drive_selected)
    print(result)

    return render_template('./smart.html', drives=drives, msg=result, drive_selected=drive_selected)


#app.run(debug=True)
app.run()

웹페이지 템플릿은 아래와 같다.

<html>
    <head>
        <title>SMART VIEW PAGE</title>
    </head>
    <body>
        <form method='POST' action='/'>
            <p align=center>
                Select Drive: 
                <select name="drive_selected" id="drive_selected" onchange="this.form.submit()">
                    <option value="" selected disabled hidden>Drive</option>
                    {%- for drive in drives %}
                    <option value={{drive}}>{{drive}}</option>
                    {%- endfor %}
                </select>
            </p>
            <p align=center>
                selected drive: {{drive_selected}}
                <br>
                {{msg}}
            </p>
        </form>
    </body>
</html>

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다