A taste of Troubleshooting Automation on F5 boxes using Python
This article is like a getting started guide for those unfamiliar with troubleshooting automation in Python on BIG-IP.
We're going to create a very simple script that checks CPU usage of a given process and:
- If CPU > 90%, it prints a message saying that CPU is high
- Otherwise, it prints a message saying that CPU is OK
The idea of a simple script is so you don't get distracted with the script itself and follow along my thought as I add more features.
The following command prints out the current CPU usage of a given process (tmm.0) in this case:
Creating a function that returns CPU usage
Python has a dynamic prompt known as REPL where we can test our code in real time and all we need to do on BIG-IP is to type keyword python:
So, functions in Python abstracts a more complex task and returns a result.
Functions are defined like this:
Before we create our function to return CPU usage from a particular daemon, we need to know how to execute Linux commands using Python:
Now, we can finally create our function that returns CPU usage of a given daemon by storing above command's output into a variable and returning it:
Keep above function handy!
Creating a loop to check if CPU is high
Now we're going to add above function to a loop.
Why? Because we want our script to flag to us when CPU usage is above 90%, remember?
One solution is to use a while loop. If you don't know what's a while loop then that's a very simple example that shows you that the loop keeps going until a certain condition we define is satisfied.
For example, in this case here we set a variable number = 0 and while number is not yet 10, we keep increasing number by 1 and print it:
PS: number += 1 is the same as number = number + 1
For our loop, we can just store the value from our previous function into a variable called actualusage and use an if/else clause to print out a message when CPU is high and a different one when it's not:
PS: while True would just run an infinite loop. The only way to leave such a loop would be to explicitly use break keyword when a condition we specify is satisfied inside our loop..
Adding 1 second break interval to loop
Notice that previous loop will probably eat up a lot of CPU resources so we're better off waiting at least 1 second before each check using time.sleep as seen below:
Now our script will wait for 1 second between checks.
Bundling our script up together
Now let's bundle it up together and see what we've got up to now:
We're importing commands and time so we can use commands.getoutput() and time.sleep() functions respectively.
Notice I've added a path to python executable in the first line of our script above.
This will allow us to execute our script using ./script.py rather than python script.py.
Isn't it better?
Let's test it:
Lovely. Our script seems to be working fine. I pressed Ctrl+C to exit the loop.
Making our script accept process name as argument
Up to now, we've been passing the process name (tmm.0) directly to our script.
Wouldn't it be better if we added process name as an argument like ./check-cpu-usage.py <process name>?
The simplest way to add arguments in Python is to use sys.argv.
Here's an example:
Note that sys.argv always returns script's name and sys.argv the first parameter we typed in.
Yes, if we wanted to return a second parameter it would be sys.argv and so on.
The idea here is to store whatever we type in as argument into a variable and copy that variable to checkcpu() function:
Now let's confirm it works:
Much better, eh?
Let's create a simple sillyscript.sh to eat up a lot of CPU cycles deliberately and finish up our test:
If you're a beginner in Python's world, you can stop here and try the script with a few other processes and play with it.
Otherwise, I'd suggest going through Appendix sections.
Appendix 1: Making our script return an error when no argument is passed to it
Let's add the ability to return an error if we accidentally execute the script without any arguments.
For this we can use try and except clause:
Basically, sys.argv (our first argument) is copied to a variable named argument. Therefore, if we execute the script without any arguments, except clause is triggered printing an error message.
Now, we can incorporate that to our script:
Appendix 2: Making our script automatically stop after 5 seconds
We can also add a timer for the script to automatically finish after a certain amount of time.
Here's how we do it:
If we run the above code, we'll see nothing going on for 5 seconds and script will stop and print a message:
We can do something similar to our script and make it exit after 5 seconds by storing the time our script started (in start variable) and testing if current time.time() is ever higher than start + 5 (notice I stored 5 into a variable named MAX_TIME_RUNNING):
Now, let's confirm it works
The command prompt returned after 5 seconds and there was no need to press Ctrl+C.
We could fine tune and improve our script even further but this is enough to give you a taste of Python programming language.