2

I wrote this simple Munin plugin to graph average fan speed and I want to redo it to OOP - strictly as a learning exercise. Don't have a clue where to start though. Anyone feel like offering some guidance or even an example of what this script should look like when done. I will use it to redo some other scripts into an OOP style as well; again for learning purposes.

import sys
import subprocess

CMD = "/usr/sbin/omreport chassis fans".split()

# Munin populates sys.argv[1] with "" (an empty argument), lets remove it.
sys.argv = [x for x in sys.argv if x]

if len(sys.argv) > 1:
    if sys.argv[1].lower() == "autoconfig":
        print "autoconfig"
    elif sys.argv[1].lower() == "config":
        print "graph_title Average Fan Speed"
        print "graph_args --base 1000 -l 0"
        print "graph_vlabel speed (RPM)"
        print "graph_category Chassis"
        print "graph_info This graph shows the average speed of all fans"
        print "graph_period second"
        print "speed.label speed"
        print "speed.info Average fan speed for the five minutes."
else:
    try:
        data = subprocess.Popen(CMD,stdout=subprocess.PIPE).stdout.readlines()
    except OSError, e:
        print >> sys.stderr, "Error running '%s', %s" % (" ".join(cmd), e)
        sys.exit(1)

    count = total = 0
    for item in data:
        if "Reading" in item:
            # Extract variable length fan speed, without regex.
            total += int(item.split(":")[1].split()[0])
            count += 1
    # Sometimes omreport returns zero output if omsa services aren't started.
    if not count or not total:
        print >> sys.stderr, 'Error: "omreport chassis fans" returned 0 output.'
        print >> sys.stderr, 'OMSA running? Try: "srvadmin-services.sh status".'
        sys.exit(1)

    avg = (total / count)
    print "speed.value %s" % avg
1

1 Answer 1

3

You remake it in OOP by identifying code and data that goes together. These you then merge into "classes".

You actual data above seems to be the output of a process. The code is iterating over it. I guess you can make a class out of that if you want to, but it's a bit silly. :)

So, something like this (obviously completely untested code):

import sys
import subprocess

class Fanspeed(object):

    def __init__(self, command):
        self.command = command.split()

    def average_fan_speed(self):
        data = subprocess.Popen(CMD,stdout=subprocess.PIPE).stdout.readlines()

        count = total = 0
        for item in data:
            if "Reading" in item:
                # Extract variable length fan speed, without regex.
                total += int(item.split(":")[1].split()[0])
                count += 1
        # Sometimes omreport returns zero output if omsa services aren't started.
        if not count or not total:
            raise ValueError("I found no fans. Is OMSA services started?"

        avg = (total / count)
        return % avg

if __main__ == '__main__':
    # Munin populates sys.argv[1] with "" (an empty argument), lets remove it.
    sys.argv = [x for x in sys.argv if x]

    if len(sys.argv) > 1:
        if sys.argv[1].lower() == "autoconfig":
            print "autoconfig"
        elif sys.argv[1].lower() == "config":
            print "graph_title Average Fan Speed"
            print "graph_args --base 1000 -l 0"
            print "graph_vlabel speed (RPM)"
            print "graph_category Chassis"
            print "graph_info This graph shows the average speed of all fans"
            print "graph_period second"
            print "speed.label speed"
            print "speed.info Average fan speed for the five minutes."
    else:
        try:
            cmd = "/usr/sbin/omreport chassis fans"
            fanspeed = Fanspeed(cmd)
            average = fanspeed.average_fan_speed()
        except OSError, e:
            print >> sys.stderr, "Error running '%s', %s" % (cmd, e)
            sys.exit(1)
        except ValueError, e:
            # Sometimes omreport returns zero output if omsa services aren't started.
            print >> sys.stderr, 'Error: "omreport chassis fans" returned 0 output.'
            print >> sys.stderr, 'OMSA running? Try: "srvadmin-services.sh status".'
            sys.exit(1)

But YMMV. It's perhaps a bit clearer.

Sign up to request clarification or add additional context in comments.

1 Comment

With only a few minor modifications this worked perfectly. It's really helpful to see a script I wrote redone in this manner. I know it's probably not a best use case for OOP so thanks for playing along. ;) I have another plugin that is incredibly similar but for chassis temps. I'm going to attempt to combine them now. Thanks again!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.