Thursday, December 23, 2021

System changes and Dead Horse

Innocuous changes can have large results on a program.  They can take the form of some very simple changes.  


But not all those changes are easy or small.  And "the way things are" isn't always the best method of operation.  But that's the way the operation runs.  And many operations run this way for years without anyone changing the operational procedure. 


There's a meme running around with a person on a dead horse, complaining that businesses are stupid and are unaware the horse is dead.  It's not just businesses.  It's all people.   The pull of the familiar is universal, but that doesn't make it accurate or correct.  And realizing the events that are occurring in your life and of your creation are altogether more complicated.

How many people are out there right now causing drama on social media, wishing they had a drama free life?  

How many people are living paycheck to paycheck, without realizing their own behaviors are causing them to live paycheck to paycheck?


See: the noticing the dead horse is a lot more complicated than it seems.  And doing something different in the midst of "effective" solutions is exceptionally hard.


There are a lot of good books on why we don't notice these things.  Scarcity is one of them.  But that only deals with a portion of the problem.  Despite what people say, memes are just another political format.  Another way of getting that specific piece of knowledge that set in just a way to get a specific set of people to react.  To build up your base camp.  To get people to agree with you.

Even if it ignores the broader consequences and truth of what is going on.



Monday, December 20, 2021

A bit more Java here and there

 Some days, the cost of code is crazy.  The ability to build and code solutions to problems is not something everyone has the capability of.  But then when you see how little code it can take to solve a problem, you realize just how expensive code can be.  


With a bit of messing, I figured out how to write an event messenger in Python to handle a built in system integration.  It took me about 300 lines of code.  


Funny thing: a few weeks after I figured it out, a vendor offered me their solution.  For $15 per month, per site.  I kindly told them no.  At 20 sites, that's about $1 per month, per line of code.  Which is pretty nuts to say the least.

So I moved on, and decided I wanted something a bit more permanent.  My code runs as a nohup process on an old Ubuntu box that is acting as a syslog receiver.  Which made me think: why can't I write my own syslog receiver?  


Nothing really prevented me from doing it, but I didn't have a decent IDE in order to do what I wanted.  I've used syslog collectors from SolarWinds and Graylog.  Both were functional for what they do, but that don't do what I want them to do.  Alerting is part of it.  Data collection is another part.  But there's so much more that I think should be and could there.  Somehow that blend of SIEM and syslog collector always seems to appeal to me.  That gathering of "EVEN MORE DATA".  And I do understand that more data doesn't necessarily mean better decisions.  It just means more data to sort though.  And the need for more algorithms that handle that data, so the alerts generated off that data can be reduced from the thousands to individuals.  


But like I said, no IDE.  Microsoft makes a good one, but it's not free.  I like Visual Studio.  I just wish they gave it away for free until you get to a certain level.  Like the SQL Express model.  So I quit using their stuff.  And I moved to Eclipse.  


Eclipse is pretty decent.  The autocomplete makes me mad here and there.  But it's functional, and it allows me to build complex, multi-hundred lines of code applications.


Like my syslog collector.   That I finally wrote in Java.  

And that's about all it does right now is collect syslogs.  But I've got plans for that sucker.  Because eventually I'm going to take that 300 lines of Python code and turn it into Java.   And I'm going to attach a SQLExpress database to it, along with an IIS front end for a web application view of the mess I'm creating in the background.  Why?  Because I like web front ends.  

And because I want to learn more about SQLExpress and IIS.  And that's generally a good enough reason for most of these projects.  Or at least I think so.


Friday, August 6, 2021

Continuations

 

So you have decided you want to produce something.  Great.  You are half way down the road to a sustainable stream of income.  And then the question arises: what do I produce?  

You are going to hate the answer.

Pick something.

Anything.  Doesn't matter what. 

Produce it.

Production done?  Good.   Now publish it.  

Where?  It doesn't matter.  Put it out somewhere for someone else to see.  Produce and publish.  That is your cycle for the rest of your life.  If you do not produce, you will not get paid.  If you do not publish, then you will not get paid.  Random great screen writer is not going to magically show up at your door and ask you about your next whatsit.  They just aren't.  

And if you run into one of them out and about on their daily lives, they really don't want to hear about it.  You are probably the fourth person that has come to show them the best script they've ever seen.  So what then?  

There are methods to get this type of thing accomplished.  But do you want to do it on the first thing you created?  Are you ready for that kind of criticism?  Or do you need some sort of small win that says "I can publish this".  I'd go for the second, so you can polish your chops.  

Remember: there are multiple types of people in the world.  There's everyone else, and there is Ferris Bueller.  Bueller, though fake, is the archetype of person that lives by an entirely different set of rules.  Whereas his friends follow the basic rules the rest of the known world follows, Bueller follows a collection of rules that aren't as easily knowable, and are rarely taught.  

If I knew those rules, I'd be writing about that.  Instead, I'm writing about producing something and throwing it to the wolves.  

And in general, do you know what is going to happen?  Nothing.  You will publish, it will be ignored, and life will go on.  But at least you published.  Because although in general nothing will happen, that isn't always the case.  If you can catch that kind of buzz with a few friends that think what you are doing is quality work, then they might pass it off of their friends, and their friends' friends.  It could be epic.

But it will never happen unless you publish.  That brilliant knowledge in your head won't ever come to life if you don't ever write anything.  The head is a terrible place for knowledge.  Get it out and get it on paper.  Get it to the place where people can examine and criticize.  You might not get a single sale or review.  No one might read it.  But at least you published, and that's more than the rest of the world can say.  

Don't be Al Bundy.  Don't live in the limelight of the idea of the person you were twenty years ago.  Go out and create something new.  Use what your limelight twenty years ago taught you.  Did it teach you hard work?  Discipline?  Dealing with popularity?  Dealing with being hated?  Take that.  Tear it apart.  Write about it.  Because there are others who have experienced the same thing as you.  And they want to hear from their kind.  Believe me.  We do. 

I read Echo In Ramadi by Scott A Huesing because I thought I might be in it.  I wasn't.  Some of the locations I remember were.  But people pick up things that speak to them.  That they think might interest them.  Maybe it makes them feel like a part of a tribe.  Maybe what you are writing appeals to that tribe.  You don't need a lot of people to read your stuff, you just need some people to read your stuff.  

They may hate it.  They may like it.  They may never finish it.  That all might happen.  

And it could make you the next J. K. Rowling.  But you'll never know unless you publish.  


Friday, July 23, 2021

More questioning thoughts

 

So the question is: what kind of content should I produce?  What do I know that other people don't know?  

What do I know that I can teach to other people? 

I spend most of my time trying to understand the choices I have made, and examining systems that will make better choices the next time.  Part of that is habit creation, and part of it is analysis.   Perhaps the real problem is that I haven't spent decent time in actual analysis of behaviors and choices.  

So what is the sufficient amount of time?  Right now, I go by the seat of my pants on making choices.  Bad experience compounded a lot o times to create answers that are generally correct.  But then generally correct is not always correct.

And there goes the perfectionist mentality in me, trying to find the perfect solution.  Whereas the trained brain portion says pick any solution.  So where is the distinction?  Probably in the question: does this decision matter in the next two years?  If its the difference between the chicken and the fish, then the decision won't matter twenty minutes from now.  

But aren't many of our decisions like that?  Many of them are very small and insignificant in their own right.  I've always been a skinny guy, and it doesn't matter what I eat.  So I don't have the problem that others have with weight.

On the other hand, I have a problem with weight.  I'd much rather add another 30 pounds of muscle.  Would I be happy if I did that?  I don't know.  That depends on whether I'm looking forward to where I want to be, or looking backwards to where I was.  

I heard a pretty good description of the subject form Dan Sullivan.  He described it like thus:  at the beginning of the period, you are a position A.  At the end, you are at position B.  Where you want to be is position C.  

Whether you are happy or not is what you do when standing on position B.  Do you look at C, and see how far you have to go?   Or do you look back at A and examine how far you have come?  The happy person stands at B and looks back towards A.  The unhappy person looks at C.  

It's all a question of expectation vs reality.  Did you always compare yourself to the expectation?  If so, you are comparing yourself to something you can never be.  Despite all your hard work, you will never meet that reality.  That image of what you want to be is something you are highly unlikely to ever reach.  Partly because the ideal is far away.

So how do you end up cultivating that on a regular basis?  And what makes us think that it's a good idea to avoid reality with such measures?  A lot of both probably comes from what we have been inadvertently taught wrong.  Gratitude is rarely taught in class, and it isn't something you see glorified on TV.  Telling people the way it is seems to be the main method of the day, though that has a tendency to aim and nothing and hit it every time.  

Perhaps the problem is not in either approach.  It's in not producing.  Realistically, the difference between success and failure is not gratitude or any other routine.  It is about producing versus consuming.  The more you produce, the more you grow.  You could think of production in the agricultural sense.  Production is planting seed that may or may not grow.  The more seed you plant, the more likely you are to get a giant crop. 

But most people plant no seed, and wonder why they don't get a crop.  Out of the 24 hours in a day, they spend 0 of them producing.  Of the things they do produce, they are producing for someone else.  But producing some product, no matter how bad, for ourselves?  Never.  Can't possibly do that.  

Success is not about what you want, it's about what you do.  And if you want to break out of what everyone else is doing, then you must create content.  It doesn't have to be original.  Let's face it: Motzart's first symphonies weren't original.  The beginnings never are.  But they are just those: beginnings.  You have to start and go somewhere or you will never end up anywhere.  

Tuesday, February 25, 2020

Upgrades break your stuff.... python 3.4 vs python 3.7

So...  The new version of PRTG rolled out and Python 3.4 is now deprecated and Python 3.7 is a thing. 

What does that mean for me? 

Everything I wrote before is now broke....

so...  that big chunk about paepy...  you can forget all that.

Luckily, I spent the time figuring out how to make all this work.


starting point...

result = []

result is going to hold our collection of strings that we'll add together prior to dumping into PRTG.


Next bit.. 

We need this bit to create the proper JSON format before we start dumping stuff in. 

 result.append(" { \"prtg\" :{ \"text\": \"OK\", \"result\":[")


Second bit... 
result.append("{\"channel\": \"name of the thingy\", \"unit\": \"Custom\", \"value\": " + value_of_importance + ", \"is_float\": \"True\"  , \"primary_channel\": \"True\", \"warning\":\"0\", \"is_limit_mode\": \"True\", \"limit_min_error\":\"0.5\", \"limit_max_error\":\"1.5\", \"limit_error_msg\":\"the message\"}")

So... you're going to have to escape a lot of quotes.  General stuff....  escaping quotes is \".   So if you want a quote (")  you need to write \" to get a quote and not finish the line.

It's a bit pain to say the least.

The not so much pain is that the end result can be dumped into a JSON validator and you can find what needs to be fixed and what is wrong.


Other web pages I found valuable:



Please use the previous article I wrote on troubleshooting to find the actual JSON output and dump that into a validator to make sure your JSON is good before pulling your hair out.  The big thing that is going to be a problem is adding the correct amount of commas after the channels.  

One comma at the end of each channel, except for the last one.

Use the len() command to solve that problem.

To be more specific.....   len() = blah.

Create another variable...

currentRun = 0

Increment variable at the end of the for statement.
if len() > currentRun:
    result.append(",")    #add a a comma

That should be sufficient...

Now....   One everything is done...  

Need to add this bit to the result so we can the end of the JSON.

result.append("]}}")

Ok... got that...  

Now everything is is stuffed into result, but we need to get rid of the commas that normally show up when you just add a bunch of strings together.....


So...

finalResult = ""
         for items in result:
             finalResult += items
    
print(finalResult)

And with that print statement, we're done.


We've got rid of commas in the wrong place, got rid of paepy, and upgraded from Python 3.4 to Python 3.7.....

Looks like we're good.

Monday, December 30, 2019

PRTG: solving your problems

So you wrote a nice custom script to monitor you Next Cool Thing, and it doesn't work.  Not only does it not work, you can't figure out what is wrong with it.

So how do you solve it?

First, turn on sensor debugging. 

Go to the sensor in question, then Settings.  Scroll down until you find this bit. 

Turn that on.




Got that?   Good.

Now the interesting part.  Where are my readings? 

C:\program data\Paessler\PRTG Network Monitor\Logs (Sensors)\

So there you have it.

Kind of.

You get two files for every sensor.   One file indicates all the stuff that was sent to the sensor via PRTG.  That's the file with the name "Result of Sensor XXXX.Data.txt"

The other file is the output after the script has been run.  That's "Result of Sensor XXXX.log"

From there, it's time to go read that second log file and try to figure out what the problem might be.  The big problem I have with troubleshooting Python scripts is the lack of an Idle interpreter in the default installation of PRTG. 

That's survivable.  Notepad is there.  It's just more annoying. 

The second part of reference is that the interesting bits about what failed is generally at the very end of the script output. 

Is this the perfect debugging scenario?  No.  But it does provide the information you need to figure out why your script isn't working.

You did write the script on a machine with better debugging utilities to try and make a good proof of concept, right? 

So best practice in my eyes: write the entire script except the output bits on a separate machine before transferring it to the remote probe and/or primary server.

So...   Have fun, and go squash some bugs.

Thursday, December 5, 2019

PRTG: Making Custom Sensors to monitor strange things with Python


#verion 1.0
#last modified 12/2/19
#
#v 1.0   initial revision / prtg integration
#
import sys
import json
import urllib.request

from paepy.ChannelDefinition import CustomSensorResult


if __name__ == "__main__":

    location = json.loads(sys.argv[1])
    
    parsed = "http://" + str(location['host']) + "whatever else in the url"
    
    page = urllib.request.urlopen(parsed).read()
    

    #data comes out as binary type.
    #convert from binary to normal string
    np = page.decode('utf-8')

    scrip = np.split('



    for lines in scrip:


    result = CustomSensorResult("OK")


         result.add_channel(channel_name="channel1", unit="Custom", value=status_value1, is_float=True, primary_channel=True, warning=0, is_limit_mode=True, limit_min_error=0.5, limit_max_error=1.5, limit_error_msg="channel1 failed") 
         result.add_channel(channel_name="channel2", unit="Custom", value=status_value2, is_float=True, is_limit_mode=True, warning=0, limit_min_error=0.5, limit_max_error=1.5, limit_error_msg="channel2 failed")


    print(result.get_json_result())


Base code for a python script sensor for PRTG.   

Using this method, you write a script to scrape a web page, and then present the information to PRTG as a JSON file.

The limits are used to define up/down/warning status.

In this case, I have outputs of a binary 1/0 for working not working.

So how does that work?   

Notice this bit.

result.add_channel(channel_name="channel1", unit="Custom", value=status_value1, is_float=True, primary_channel=True, warning=0, is_limit_mode=True, limit_min_error=0.5, limit_max_error=1.5, limit_error_msg="primary connection 

And breaking that apart, the section here
is_limit_mode=True, limit_min_error=0.5, limit_max_error=1.5, limit_error_msg="channel1 offline"

Let's break these down.

Note: these names aren't the same those expected or presented for EXE/Advanced sensors on the PRTG custom sensor page.

is_limit_mode = Sets PRTG to know that the output has acceptable ranges of input.   
limit_min_error  = This sets the lower limit that defines an error.  Depending on your output, there may not be one.  I'm using outputs of binary 0/1 in this case, so I set it to .5.   Therefore, a 0 output is defined as error state.
limit_max_error  = This set the upper limit that defines an error.   Depending on your output, there may not be one.  In my case, there is never an upper maximum error.   So I set it to 1.5.   
limit_erro_msg = The message you want on PRTG for any device that may be not working.


So, with these setting set correctly, PRTG will report an individual sensor is down based on the values you assign to status_value1 and status_value2.  So now, you can alert based on those settings using normal PRTG alerting.


What this base script doesn't currently do:
  1. Parse anything.  Parsing the web page is based entirely on what you are looking for.  The page I was looking at was all table based, so splitting the data into tables made sense.  You will have to handle that portion.
  2. Deal gracefully with urlib.urlrequest.open() errors.   You will get a JSON error in PRTG when you try to pull a web page you can't get.  That's a simple try/except statement.  Use this message in your except portion to report failure gracefully.

            result.add_error("Your Error Message Here")



Secondary important thing...   probably the most important.  

See this block? 

 location = json.loads(sys.argv[1])
    
    parsed = "http://" + str(location['host']) + "whatever else in the url"

This block accepts json data as input to the script.  
The second part location['host'] pulls the IP address setup on the sensor to feed that data into the script.   So this script can be written once and run on multiple devices.  That's what makes this script extendable.

Now...   

So, you've got the initial script working.

How in the world do I troubleshoot this thing when I suddenly get a bunch JSON errors when I deploy it?   

That's the subject of another discussion.