public inbox for linux-nfs@vger.kernel.org
 help / color / mirror / Atom feed
From: Chuck Lever <chuck.lever@oracle.com>
To: Lans Carstensen <Lans.Carstensen@dreamworks.com>
Cc: NFS list <linux-nfs@vger.kernel.org>
Subject: Re: [PATCH 4/4] nfs-utils: nfs-iostat.py autofs cleanup and option to sort by ops/s
Date: Wed, 26 Aug 2009 11:47:18 -0400	[thread overview]
Message-ID: <08E0F2AC-2747-4F98-9686-CF665490B0F1@oracle.com> (raw)
In-Reply-To: <4A954C4D.3060701@dreamworks.com>


On Aug 26, 2009, at 10:53 AM, Lans Carstensen wrote:

> Greetings!  Comments inline.  Chuck Lever wrote:
>> Hi Lans-
>> I was thinking about this feature a little more.  Would it be  
>> interesting to allow sorting by other metrics besides ops/s ?   
>> That's another feature that the "top" command has that this new  
>> option doesn't.
>> I also don't like the bare integer options.  What if, at some  
>> point, we want "-4" and "-6" for IPv6 support (not that we do, but  
>> what if)?  Plus, having the bare integers doesn't give any clues  
>> about what the number means.
>> In which case I propose:
>>  --sort=ops --list=<n>
>> which provides more flexibility and helps make the options more  
>> self-documenting.
>
> Again, thanks for looking this over.
>
> I had thought about the sorting a little bit, but decided that every  
> case we cared about devolved to sorting by ops/s.  We'd use a tool  
> like this in an operational group where they've lost control of a  
> particular rogue workload in the mix of thousands of other  
> workloads, and the operational group is trying to figure out what  
> workload is generating a disproportionate amount of traffic (ops/ 
> s).  If someone wanted to extend the implementation further where  
> leaving "--sort" unadorned sorts by ops and using "-- 
> sort=readdirplus" or somesuch, I'd be all for it - but it didn't  
> seem worth the work for our use.  So I'd encourage that to be  
> adopted as-is and if someone wants to put the extra effort into it  
> I'm all for it.

Well, the problem is once we choose a command line option, it's hard  
to change it later.  I think having two choices, like --sort=ops and -- 
sort=def[ault] would be fine for now, and give us room to grow later.

> For the bare integer options I was thinking in terms of the existing  
> "tail" and "head" implementations - that's what made the most sense  
> to me and the couple of others looking over this here.  Changing it  
> to "--list=<n>" is fine if that suites you and others more.  I can't  
> quite fathom going after IPv4 or IPv6 stats with this, as /proc/self/ 
> mountstats a) doesn't expose any relevant data that would be IPv4/ 
> IPv6 oriented, and b) really never would as that's at an  
> implementation layer below NFS ops.  So the existing patch makes  
> most sense to me, but if you and others want it changed I'd be fine  
> w/ doing it.

The modern command line option on head/tail is --lines=<n>, which is  
also an OK name for this option.

IPv4/IPv6 was just an example... some applications, like ssh, use "-4"  
and "-6" already, which makes the use of -<n> ambiguous, I think.

>> On Aug 26, 2009, at 12:59 AM, Lans Carstensen wrote:
>>> commit 062577877bd3f1d8da1edeb889a09d380da83364
>>> Author: Lans Carstensen <Lans.Carstensen@dreamworks.com>
>>> Date:   Tue Aug 25 21:53:54 2009 -0700
>>>
>>>   Adds --sort option to display mount point stats sorted by ops/s
>>>   Adds -<n> option to only display stats for first <n> mount points
>>>   E.g. the use of "--sort -1" should be useful in seeing stats for
>>>   only the mountpoint with the highest ops/s.
>>>
>>> diff --git a/tools/nfs-iostat/nfs-iostat.py b/tools/nfs-iostat/nfs- 
>>> iostat.py
>>> index 9f3b3eb..5df9bfb 100644
>>> --- a/tools/nfs-iostat/nfs-iostat.py
>>> +++ b/tools/nfs-iostat/nfs-iostat.py
>>> @@ -20,7 +20,7 @@ along with this program; if not, write to the  
>>> Free Software
>>> Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  
>>> 02111-1307 USA
>>> """
>>>
>>> -import sys, os, time
>>> +import sys, os, time, re
>>>
>>> Iostats_version = '0.3'
>>>
>>> @@ -353,6 +353,12 @@ class DeviceData:
>>>        print '\t%7.3f' % rtt_per_op,
>>>        print '\t%7.3f' % exe_per_op
>>>
>>> +    def ops(self, sample_time):
>>> +        sends = float(self.__rpc_data['rpcsends'])
>>> +        if sample_time == 0:
>>> +            sample_time = float(self.__nfs_data['age'])
>>> +        return (sends / sample_time)
>>> +
>>>    def display_iostats(self, sample_time, which):
>>>        """Display NFS and RPC stats in an iostat-like way
>>>        """
>>> @@ -421,6 +427,11 @@ def print_iostat_help(name):
>>>    print ' If one or more <mount point> names are specified,  
>>> statistics for only these'
>>>    print ' mount points will be displayed.  Otherwise, all NFS  
>>> mount points on the'
>>>    print ' client are listed.'
>>> +    print
>>> +    print ' You can also specify "--sort" to sort the NFS mount  
>>> points by ops/second,'
>>> +    print ' and specify a number of mount points to return with - 
>>> <num>, e.g. -1.'
>>> +    print ' For example, use of "--sort -1" will iterate only  
>>> showing you the stats'
>>> +    print ' for the mount point with the highest ops/second.'
>>>
>>> def parse_stats_file(filename):
>>>    """pop the contents of a mountstats file into a dictionary,
>>> @@ -446,7 +457,10 @@ def parse_stats_file(filename):
>>>
>>>    return ms_dict
>>>
>>> -def print_iostat_summary(old, new, devices, time, ac):
>>> +def print_iostat_summary(old, new, devices, time, ac, sortbyops,  
>>> entrycount):
>>> +    diff_stats = {}
>>> +    count = 1
>>> +
>>>    if old:
>>>        # Trim device list to only include intersection of old and  
>>> new data,
>>>        # this addresses umounts due to autofs mountpoints
>>> @@ -455,15 +469,34 @@ def print_iostat_summary(old, new, devices,  
>>> time, ac):
>>>        devicelist = devices
>>>
>>>    for device in devicelist:
>>> +        count += 1
>>>        stats = DeviceData()
>>>        stats.parse_stats(new[device])
>>>        if not old:
>>>            stats.display_iostats(time, ac)
>>> +            if (count>entrycount):
>>> +                return
>>>        else:
>>>            old_stats = DeviceData()
>>>            old_stats.parse_stats(old[device])
>>> -            diff_stats = stats.compare_iostats(old_stats)
>>> -            diff_stats.display_iostats(time, ac)
>>> +            diff_stats[device] = stats.compare_iostats(old_stats)
>>> +            if not sortbyops:
>>> +                diff_stats[device].display_iostats(time, ac)
>>> +                if (count>entrycount):
>>> +                    return
>>> +
>>> +    if old and sortbyops:
>>> +        # We now have compared data and can print a comparison
>>> +        # ordered by mountpoint ops per second
>>> +        count = 1
>>> +
>>> +        devicelist.sort(key=lambda x: diff_stats[x].ops(time),  
>>> reverse=True)
>>> +
>>> +        for device in devicelist:
>>> +            count += 1
>>> +            diff_stats[device].display_iostats(time, ac)
>>> +            if (count>entrycount):
>>> +                return
>>>
>>> def list_nfs_mounts(givenlist, mountstats):
>>>    """return a list of NFS mounts given a list to validate or
>>> @@ -497,6 +530,8 @@ def iostat_command(name):
>>>    which = 0
>>>    interval_seen = False
>>>    count_seen = False
>>> +    sortbyops = False
>>> +    entrycount = sys.maxint
>>>
>>>    for arg in sys.argv:
>>>        if arg in ['-h', '--help', 'help', 'usage']:
>>> @@ -507,6 +542,19 @@ def iostat_command(name):
>>>            print '%s version %s' % (name, Iostats_version)
>>>            return
>>>
>>> +        if arg in ['-s', '--sort', 'sort']:
>>> +            sortbyops = True
>>> +            # sorted display infers a loop, default to 1 second
>>> +            if not interval_seen:
>>> +                interval = 1
>>> +                interval_seen = True
>>> +            continue
>>> +
>>> +        stop_re = re.compile('-[0-9]+')
>>> +        if stop_re.match(arg):
>>> +            entrycount = int(arg.lstrip('-'))
>>> +            continue
>>> +
>>>        if arg in ['-a', '--attr']:
>>>            which = 1
>>>            continue
>>> @@ -546,12 +594,12 @@ def iostat_command(name):
>>>    sample_time = 0.0
>>>
>>>    if not interval_seen:
>>> -        print_iostat_summary(old_mountstats, mountstats, devices,  
>>> sample_time, which)
>>> +        print_iostat_summary(old_mountstats, mountstats, devices,  
>>> sample_time, which, sortbyops, entrycount)
>>>        return
>>>
>>>    if count_seen:
>>>        while count != 0:
>>> -            print_iostat_summary(old_mountstats, mountstats,  
>>> devices, sample_time, which)
>>> +            print_iostat_summary(old_mountstats, mountstats,  
>>> devices, sample_time, which, sortbyops, entrycount)
>>>            old_mountstats = mountstats
>>>            time.sleep(interval)
>>>            sample_time = interval
>>> @@ -562,7 +610,7 @@ def iostat_command(name):
>>>            count -= 1
>>>    else:
>>>        while True:
>>> -            print_iostat_summary(old_mountstats, mountstats,  
>>> devices, sample_time, which)
>>> +            print_iostat_summary(old_mountstats, mountstats,  
>>> devices, sample_time, which, sortbyops, entrycount)
>>>            old_mountstats = mountstats
>>>            time.sleep(interval)
>>>            sample_time = interval
>>>
>>>
>>>
>>> -- 
>>> To unsubscribe from this list: send the line "unsubscribe linux- 
>>> nfs" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> -- 
>> Chuck Lever
>> chuck[dot]lever[at]oracle[dot]com
>

--
Chuck Lever
chuck[dot]lever[at]oracle[dot]com




  reply	other threads:[~2009-08-26 15:47 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-08-26  4:59 [PATCH 4/4] nfs-utils: nfs-iostat.py autofs cleanup and option to sort by ops/s Lans Carstensen
2009-08-26 14:37 ` Chuck Lever
2009-08-26 14:53   ` Lans Carstensen
2009-08-26 15:47     ` Chuck Lever [this message]
2009-08-26 16:57       ` Trond Myklebust
2009-08-26 17:24         ` Chuck Lever
  -- strict thread matches above, loose matches on Subject: below --
2009-09-15  4:57 Lans Carstensen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=08E0F2AC-2747-4F98-9686-CF665490B0F1@oracle.com \
    --to=chuck.lever@oracle.com \
    --cc=Lans.Carstensen@dreamworks.com \
    --cc=linux-nfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox