Python | Monitor hard drive health with smartmontools

Python Methods and Functions

Smartmontools , an abbreviation for SMART Monitoring Tools , is a package that is used to manage and monitor computer storage systems using the SMART system (self-monitoring, analysis and reporting technologies) built into most modern (P) ATA, Serial ATA, SCSI /. SAS devices.
It contains 2 utilities: smartctl and smartd . These utilities issue warnings or warnings about disk degradation and crashes.
smartmontools can be used on any Unix / Linux based operating systems. This allows us to run various tests to check the health of the hard drive or SSD on your system.




SMART

Most modern hard drives use SMART (Self Monitoring, Analysis and Reporting Technology) to evaluate them state to determine if there is something wrong with the device. This allows the user to view SMART data on the hard drive and take the necessary action to repair or replace the device.

In this article, we will look at smartmontools and get information about the hard drives and SSDs in the system. We will also write a Python script to parse smartmontools output and save the results to an Excel sheet.




Installs —

 sudo pip3 install pandas sudo apt-get install smartmontools 

After installing smartmontools, we can use terminal or command line to get detailed information about hard drives.




Device Information —

To check if your device supports monitoring SMART, and get other information like device model, capacity, serial number, etc., We use the following command:

 sudo smartctl -i / dev / sda 

If not enabled, the following command enables SMART monitoring:

 sudo smartctl -s on / dev / sda 




Device health check

To display the general state of the disk, we use the following command:

 sudo smartctl -H / dev / sda 

This displays the status of your hard drive. If it displays any errors, there may be some problems with your hard drive and you should consider backing up your data.




Tests —

To run a short test:

 sudo smartctl --test = short / dev / sda 

The purpose of the short test — quick identification of a faulty hard drive. Therefore, the maximum execution time for a short test is 2 minutes.

To run a long test:

 sudo smartctl --test = long / dev / sda  

Long tests also detect defects, but there is no time limit. The test is more thorough.

To check the test results:

 sudo smartctl -l selftest / dev / sda 




Example —

We can use Python to automate this process and generate a report. To do this, we will use Pandas to save the result in Excel tables and the os module to run commands.

# import libraries

import os

import pandas as pd

from pandas import ExcelWriter

  
# class to store all
# device details

class Device ():

 

  def __ init __ ( self ):

 

self . device_name = None

self . info = {}

self . results = []

 

# get device information

  def get_device_name ( self ):

  

  cmd = `smartctl --scan`

  

data = os.popen (cmd )

res = data.read ()

temp = res.split ( `` )

  

  temp = temp [ 0 ]. split ( `/` )

name = temp [ 2 ]

self . device_name = name

 

 

# get device information (sda or sdb )

def get_device_info ( self ):

 

cmd = ` smartctl -i / dev / ` + self . device_name

 

data = os.popen (cmd)

 

res = data.read (). splitlines ()

 

device_info = {}

 

for i in range ( 4 , len (res) - 1 ):

line = res [i]

temp = line.split ( `:` )

  device_info [temp [ 0 ]] = temp [ 1 ]

 

self . info = device_info

  

  # save results as Excel file

def save_to_excel ( self ):

 

try :

  os.mkdir ( `outputs` )

  except (Exception):

pass

 

os.chdir ( `outputs` )

  

col1 = list ( self . info.keys ())

col2 = list ( self . info. values ​​())

 

output = pd.DataFrame ()

output [ `Name` ] = col1

output [ `Info ` ] = col2

 

writer = ExcelWriter ( `Device_info.xlsx` )

output.to_excel (writer, `Info_report` , index = False )

 

workbook = writer.book

  worksheet = writer.sheets [ ` Info_report` ]

 

# Invoice information columns

worksheet.set_column ( `A: A` , 35 )

  # State column

worksheet.set_column ( `B: B` , 55 )

# Zip code

# worksheet.set_column (& # 39; F: F & # 39 ;, 10)

writer.save ()

os.chdir ( `..` )

  

# health check function

Device #

def check_device_health ( self ):

 

cmd = `smartctl -H / dev /` + self . device_name

 

data = os.popen (cmd) .read ()

res = data.splitlines ()

health = res [ 4 ]. split ( `:` )

  print (health [ 0 ] + `:` + health [ 1 ])

 

 

# function to run a short test

def run_short_test ( self ):

 

cmd = `smartctl --test = short / dev /` + self . device_name

data = os.popen (cmd) .read (). splitlines ()

 

  

# function to get results

Test #.

def get_results ( self ):

 

cmd = `smartctl -l selftest / dev /` + self . device_name

data = os.popen (cmd) .read ()

res = data.splitlines ()

 

# stores column names

columns = res [ 5 ]. split ( ` ` )

columns = `` . join (columns)

columns = columns.split ( )

 

info = [columns]

 

# iterate over important

  # 0-5 lines are not required

for i in range ( 6 , len (res)):

 

line = res [i]

 

line = `` . join (line.split ())

row = line.split ( ` ` )

  info.append ( row)

 

# save results

self .results = info

  

 

# function to convert

  # test results for

# Excel file and save it

  def save_results_to_excel ( self ):

 

  # create a folder to store results

try :

os.mkdir ( `outputs` )

  except (Exception):

pass

 

  os.chdir ( `outputs` )

 

  # get columns

columns = self . results [ 0 ]

 

# create data frame for storage

# Excel result

outputs = pd.DataFrame ()

 

col1, col2 , col3, col4 = [], [], [], []

  

  l = len ( self .results [ 1 ])

  

# iterate over all lines and save

# this is in the dataframe

for i in range ( 1 , len ( self . results) - 1 ):

 

if ( len ( self . results [i]) = = l):

  col1.append ( ` ` . join ( self . results [i] [ 2 : 4 ]))

  col2.append ( ` ` . join ( self . results [i] [ 4 : 7 ]))

col3.append ( self . results [i] [ 7 ])

col4.append ( self . results [ i] [ 8 ]) 

else :

 

col1.append ( `` . join ( self . results [i] [ 1 : 3 ]))

  col2.append ( ` ` . join ( self . results [i] [ 3 : 6 ]))

  col3.append ( self . results [i] [ 6 ])

col4.append ( self . results [i] [ 7 ]) 

 

# store columns that we

# т required in the data frame

outputs [columns [ 1 ]] = col1

outputs [columns [ 2 ]] = col2

outputs [columns [ 3 ]] = col3

outputs [columns [ 4 ]] = col4

 

# Excel object Writer to save as Excel.

writer = ExcelWriter ( ` Test_results.xlsx` )

 

# required in data frame

outputs [columns [ 1 ]] = col1

outputs [columns [ 2 ]] = col2

outputs [columns [ 3 ]] = col3

  outputs [columns [ 4 ]] = col4

 

# an Excel Writer object to save as Excel.

writer = ExcelWriter ( `Test_results.xlsx` )

 

# required in data frame

outputs [columns [ 1 ]] = col1

outputs [columns [ 2 ]] = col



Get Solution for free from DataCamp guru