IOSTAT Plotter V3

Introduction

I wrote iostat plotter to plot output from iostat when I ran some tests. I had several requests for improvements and this latest version, v3, incorporates these suggestions. I’ve made a few changes to the basic code since the article:


  • Moved the lengend outside the plot to the top right
  • Shrunk the size of the legend so you can plot more devices
  • The command option “-c” was added so you could combine the devices onto a single plot (total of 11 plots)
  • The code can read either sysstat v9.x or sysstat v10.x format for iostat (the output is slightly diffferent).
  • The legend labels are auto-sized based on the string length (it’s a heuristic algorithm).
  • A simple “-h” option as added that produces a small help output.

The changes were pretty simple and I hope they prove useful.

This tool, iostat_plotter_v3.py simply takes the output from iotstat, parsers the data to some degree, and creates plots and an HTML report. The intent is to allow plot the time history of the IO rather than have to stare at numbers flashing by on the command line.

This version is covered under the GPLv2 license.

With this version of the iostat plotting tool, you can either plot the iostat output from a single device or as many devices as you want. If you run iostat_plotter_v3.py without any options it will create a series of 11 plots for each device. If you have 5 devices it will create a total of 55 plots (11 * 5). If you run it with the “-c” option, if will “combine” the devices into the plots resulting in a total of 11 plots regardless of the number of the number of devices in the iostat output.

To begin, you need to get the iostat output using a command such as:

[laytonj@home8 IOSTAT]$ iostat -c -d -x -t -m /dev/sda 1 180 > iostat.out


which targets a single device. Or you can run,

[laytonj@home8 IOSTAT]$ iostat -c -d -x -t -m  1 180 > iostat.out


Both examples capture the output every second for a total of 180 seconds. Most importantly, the output is in MB/s via the “-m” option. If you change the output to something other than MB/s, you will need to change the plot labels (this isn’t hard to do but just remember that you have to do this).

After running iostat you then run iostat_plotter_v3.py to create the HTML document with the plots. The command is,

[laytonjb ~]$ iostat_plotter_v3.py iostat.out


where “iostat.out” is the output from iostat. The code is written in Python (obviously) and uses the shlex, time, os, and matplotlib modules. If you run it this way, a set of 11 plots for each device will be created. If you want to combined the devices into a single set of plots, then you use the following command:

[laytonjb ~]$ iostat_plotter_v3.py -c iostat.out


The “-c” option will “combine” the devices.

When iostat_plotter_v3 is done it will create a subdirectory “HTML_REPORT” that contains the plots and an html file “report.html”. Open that html file in a browser or word processor and you will see the plots and a small write-up about them. Feel free to modify the code but please send back changes since others might like to see what you have done.

If you want to get the help output just run the application as,

[laytonjb ~]$ iostat_plotter_v3.py -h


An example of the html output is here. It combines several devices together into one set of plots. You can download the file using this link (sorry – I have to use Dropbox because WordPress does not allow .py files).

Advertisements

16 Responses to IOSTAT Plotter V3

  1. Pingback: IOSTAT Plotter V2 | clusterbuffer

  2. Pingback: IOSTAT Plotter V2 – Update | clusterbuffer

  3. Pingback: IOSTAT Plotter and NFSiostat plotter updates (V3!) | clusterbuffer

  4. Amihay Gonen says:

    I got this error
    Cannot find matplotlib – this is needed for this application.
    after digging and runing via the python console I got this :
    >>> import matplotlib.pyplot as plt;
    Traceback (most recent call last):
    File “”, line 1, in ?
    ….
    import gtk; gdk = gtk.gdk
    File “/usr/lib64/python2.4/site-packages/gtk-2.0/gtk/__init__.py”, line 76, in ?
    _init()
    File “/usr/lib64/python2.4/site-packages/gtk-2.0/gtk/__init__.py”, line 64, in _init
    _gtk.init_check()
    RuntimeError: could not open display
    >>> exit

    Which let me to understating it is X issue (I hope it will save time for others uses)

    • I think you are correct – it looks like X is not installed on the node where you tried plotting. I ran into this problem on a different project that used matplotlib.

      I don’t know of any other solution except copying the data to a node that is running X.

      Good luck!

      Jeff

    • Amihay,

      Apologies for taking so long to reply. Yes – I believe for matplotlib to work you need the gtk libs installed. You might try installing them with yum or apt-get and the dependencies for matplotlib should pop up.

      Jeff

  5. Thank you for this very helpfull tool! Just had 1 issue:

    parsing iostat-data recorded within my default server locales (LANGUAGE=en_US and LC_TIME=de_DE.UTF-8) fails. Setting locales to ‘C’ or ‘en_US.UTF-8’ before recording data fixes this.

    btw. I forked your code on a git repo (https://github.com/s3h10r/iostat-plotter) for being able to play with it. hope this is ok for you? otherwise i delete this public repo. (just could not find any other ressource than a dropbox link.)

    • Sven,

      Apologies for the late (really late) reply. I hate to say it but I’m not sure about locales and how to correct it. I’m afraid I can’t help you there.

      Feel free to fork the code and go crazy with it!

      Jeff

  6. Thomas says:

    Hi,

    I’m new to the tool, when trying to run it I get:

    python iostat_plotter_v3.py secondrun
    combined_plots = 0
    iostat plotting script

    input filename: secondrun

    reading iostat output file …
    Traceback (most recent call last):
    File “iostat_plotter_v3.py”, line 2279, in
    system_info[“cores”] = currentline[5][1:];
    IndexError: list index out of range

    Platform is OSX, Python 2.7.8 :: Anaconda 2.1.0 (x86_64)

    the iostat data have been collected using iostat -c -d -x -t -m 2 5000 > file

    I don’t get it why the script is looking for Cores .. Any hints what I’m doing wrong or how to get around/fix this?

    thanks Thomas

    • Thomas,

      I’m not exactly sure what this is happening. I’ve never tried it with OSX so that is likely part of the problem (I don’t have an OSX box). Can you check the output of “iostat -V”? That should indicate the version.

      Thanks!

      Jeff

  7. Jeya says:

    Use this. It won’t try to display
    import matplotlib
    matplotlib.use(“agg”)
    import matplotlib.pyplot as plt

  8. gdrub13 says:

    Hi,

    $ /usr/local/bin/iostat -V
    sysstat version 11.1.2
    (C) Sebastien Godard (sysstat orange.fr)

    $ /usr/local/bin/iostat -c -d -x -t -m /dev/sda1 2 12 > iostat.out

    $ sudo python iostat_plotter_v3.py iostat.out
    [sudo] password for XXXXX:
    combined_plots = 0
    iostat plotting script

    input filename: iostat.out

    reading iostat output file …
    Traceback (most recent call last):
    File “iostat_plotter_v3.py”, line 2252, in
    if (currentline[2] == “PM”):
    IndexError: list index out of range

    $ head -n9 iostat.out
    Linux 3.13.0-24-generic (mc-ab) 30/12/2014 _x86_64_ (2 CPU)

    30/12/2014 09:23:01
    avg-cpu: %user %nice %system %iowait %steal %idle
    14,31 0,10 1,96 0,49 0,00 83,13

    Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
    sda1 0,04 0,00 0,01 0,00 0,00 0,00 52,37 0,00 12,57 12,54 14,86 6,80 0,00

    How can I fix it ?

    Thx so much.

  9. Hello, thank’s for the script, i want to use to troubleshoot a nas dsik performance

    I get the following error

    [root@qnap1 stat]# ./iostat_plotter_v3.py -c io.out
    combined_plots = 1
    iostat plotting script

    input filename: io.out

    reading iostat output file …
    Finished reading 20 data points for 0 devices.
    Creating plots and HTML report
    Traceback (most recent call last):
    File “./iostat_plotter_v3.py”, line 2304, in
    ts = time.mktime(time.strptime(junk1, ‘%Y-%m-%d %H:%M:%S’));
    File “/usr/lib64/python2.7/_strptime.py”, line 467, in _strptime_time
    return _strptime(data_string, format)[0]
    File “/usr/lib64/python2.7/_strptime.py”, line 325, in _strptime
    (data_string, format))
    ValueError: time data ’15-23-01 10:40:57′ does not match format ‘%Y-%m-%d %H:%M:%S’
    [root@hp6981 stat]#

    Also on my system (a qnap nas) i dont have the same option in iostat.

    iostst -h gave me the following

    [~] # iostat –h
    iostat: invalid option — –
    iostat v2.2, (C) 1999-2005 by Greg Franks, Zlatko Calusic, Rick Lindsley, Arnaud Desitter
    Distributed under the terms of the GPL (see LICENSE file)
    Usage: iostat [-cdDpPxh] [disks…] [interval [count]]
    options:

    c – print cpu usage info
    d – print basic disk info
    D – print disk utilization info
    p – print partition info also
    P – print partition info only
    x – print extended disk info
    h – this help

    [~] #

    Thank you for your help.

    • Albert,

      Try running “iostat -V” to see the version.

      Jeff

      • I had a time format error I’ve fixed it. But I realise that the Iostat version on the Qnap is V2.2 and the options are not the same. How to make the script works with that version of iostat ? Thank you

        iostat -V
        iostat: invalid option — V
        iostat v2.2, (C) 1999-2005 by Greg Franks, Zlatko Calusic, Rick Lindsley, Arnaud Desitter
        Distributed under the terms of the GPL (see LICENSE file)
        Usage: iostat [-cdDpPxh] [disks…] [interval [count]]
        options:

        c – print cpu usage info
        d – print basic disk info
        D – print disk utilization info
        p – print partition info also
        P – print partition info only
        x – print extended disk info
        h – this help

        iostat -x gives the following

        [~] # iostat -x
        extended device statistics
        device mgr/s mgw/s r/s w/s kr/s kw/s size queue wait svc_t %b
        sdb 6 88 236.2 102.0 8785.8 3599.3 36.6 0.7 2.0 0.2 6
        sda 6 86 235.9 102.7 8808.5 3548.4 36.5 0.3 1.0 0.1 5
        sdc 41 89 74.2 24.0 2654.2 444.9 31.5 0.0 0.4 1.9 19
        sde 42 89 72.8 22.1 2649.4 442.7 32.6 1.9 19.3 2.3 22
        sdf 41 89 72.8 22.0 2646.7 442.1 32.6 1.4 15.0 2.3 21
        sdd 40 89 76.3 24.0 2663.1 448.8 31.0 0.1 0.7 1.9 19
        sdg 40 89 74.0 23.8 2654.6 447.1 31.7 0.0 23.0 1.9 19
        sdh 42 89 72.9 22.8 2654.1 445.8 32.4 1.4 14.1 2.2 21
        sdi 42 89 72.8 23.4 2652.0 449.1 32.2 1.4 14.1 2.2 21
        sdj 41 89 72.9 22.2 2648.9 443.6 32.5 1.4 14.6 2.2 21
        sdk 40 88 74.0 23.5 2647.7 445.0 31.7 2.2 22.9 1.9 18
        sdl 0 1 0.2 1.2 12.2 9.5 15.3 0.0 5.9 4.4 1
        sdn 0 0 15.9 0.0 1019.5 0.1 64.0 1.0 63.1 0.4 1
        sdo 0 0 15.9 0.1 1019.6 0.4 63.5 2.1 133.5 0.5 1
        sdp 0 0 15.9 0.2 1019.6 4.7 63.6 1.5 91.9 0.5 1
        sdq 0 10 16.5 3.4 1031.3 58.4 54.9 1.5 77.0 1.0 2
        sdr 0 10 16.5 3.8 1032.0 59.8 53.7 2.0 99.6 1.1 2
        sds 0 0 17.5 0.1 1030.0 0.3 58.4 0.9 51.7 0.4 1
        sdt 0 0 17.3 0.1 1025.0 0.2 58.9 1.3 73.9 0.4 1
        sdu 0 0 15.9 0.2 1019.6 4.8 63.5 1.4 86.9 0.5 1
        sdv 0 0 17.2 0.1 1024.8 0.3 59.0 0.8 47.3 0.4 1
        sdw 0 0 15.9 0.1 1019.6 0.3 63.5 1.1 65.9 0.5 1
        sdx 0 0 15.9 0.1 1019.6 0.3 63.5 0.1 7.0 0.5 1
        sdy 0 10 16.5 3.7 1039.7 58.2 54.2 1.7 84.3 0.9 2
        sdz 0 0 15.9 0.2 1019.6 4.7 63.5 2.1 128.8 0.5 1
        sdaa 0 0 15.9 0.1 1019.6 0.2 63.5 1.3 81.8 0.5 1
        sdab 0 0 15.9 0.1 1019.6 0.2 63.5 1.0 65.4 0.4 1
        sdm 0 10 18.4 3.8 1049.1 56.8 49.8 1.4 60.9 1.0 2
        sdac 0 0 0.0 0.0 0.1 0.0 57.8 0.0 7.5 2.9 0
        md9 0 0 0.4 1.7 1.8 6.9 4.1 0.0 0.0 0.0 0
        md13 0 0 1.8 0.1 139.0 0.3 75.8 0.0 0.0 0.0 0
        md256 0 0 0.6 0.0 2.3 0.2 4.0 0.0 0.0 0.0 0
        md258 0 0 0.4 0.0 1.6 0.0 4.0 0.0 0.0 0.0 0
        md1 0 0 574.4 631.8 21868.6 2532.6 20.2 0.0 0.0 0.0 0
        md2 0 0 505.5 374.3 17568.1 7128.6 28.1 0.0 0.0 0.0 0
        dm-1 0 0 1.0 0.1 3.8 0.5 3.9 0.0 19.3 12.1 1
        dm-2 0 0 571.6 631.7 21855.1 2532.1 20.3 2.2 1.8 0.3 33
        dm-3 0 0 571.6 631.7 21855.1 2532.1 20.3 2.2 1.8 0.3 33
        dm-4 0 0 0.0 0.0 0.0 0.0 45.7 0.0 3.0 2.6 0
        dm-5 0 0 322.9 317.5 11212.9 4239.1 24.1 1.2 1.9 0.3 19
        dm-6 0 0 248.6 311.8 10641.6 2384.5 23.2 0.7 1.2 0.3 20
        dm-7 0 0 0.0 2.3 0.1 8.8 3.8 0.1 28.0 9.8 2
        dm-8 0 0 0.1 3.8 0.4 14.7 3.9 0.1 30.4 6.9 3
        dm-10 0 0 503.6 374.3 17558.7 7128.6 28.1 1.9 2.1 0.1 7
        dm-0 0 0 0.0 0.0 0.0 0.0 41.0 0.0 0.6 0.6 0
        dm-9 0 0 322.9 317.3 11212.9 4239.1 24.1 1.3 1.9 0.3 19
        dm-17 0 0 748.0 304.4 27958.4 2355.5 28.8 0.4 0.3 0.2 21
        dm-18 0 0 0.0 2.2 0.1 8.8 4.0 0.1 29.7 10.4 2
        dm-19 0 0 0.1 3.7 0.4 14.7 4.1 0.1 31.5 7.1 3
        dm-20 0 0 0.0 2.4 0.1 2252.8 947.0 0.0 12.8 0.2 0
        dm-21 0 0 0.0 2.4 0.1 2252.8 947.0 0.0 12.8 0.2 0
        md3 0 0 3.6 26.2 68.5 111.7 6.0 0.0 0.0 0.0 0
        md4 0 0 1.5 0.0 6.0 0.0 4.0 0.0 0.0 0.0 0
        dm-11 0 0 0.0 0.0 0.0 0.1 3.6 0.0 26.8 10.2 0
        dm-12 0 0 2.0 26.2 62.0 111.6 6.2 0.5 17.9 0.5 1
        dm-13 0 0 2.0 26.2 62.0 111.6 6.2 0.5 17.9 0.5 1
        dm-14 0 0 0.0 0.0 0.0 0.0 41.0 0.0 2.5 2.5 0
        dm-15 0 0 2.0 28.1 62.0 2125.4 72.5 0.9 30.8 0.5 1
        dm-16 0 0 2.0 28.0 62.0 2125.4 72.8 0.9 30.9 0.5 1
        md5 0 0 1.3 0.0 5.4 0.0 4.0 0.0 0.0 0.0 0
        md6 0 0 1.3 0.0 5.2 0.0 4.0 0.0 0.0 0.0 0
        md321 0 0 0.0 0.0 0.0 0.0 13.7 0.0 0.0 0.0 0
        dm-22 0 0 0.0 0.0 0.0 0.0 4.1 0.0 28.2 1.4 0
        dm-23 0 0 0.0 0.0 0.0 0.0 24.0 0.0 3.1 3.1 0
        [~] #

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: