Wednesday, October 30, 2013

Simple Website Monitor with C#

I was recently asked to evaluate some Website monitoring tools for a small client of mine.  While there is no shortage of Website monitoring services available, ranging from free to infinitely elaborate and expensive (and sometimes worth it, depending on the company's size and needs), I ultimately decided to just build one from scratch.  This way, the client would not be at the mercy of SaaS outages, and would be fully in control with the code on-premise.  This solution can be expanded as needed with a UI and possibly a database back-end, but following KISS, I took a simple approach, using a console app with settings in app.config, running it using a scheduled task.  Here are the details:

1. Create a new Console Application project.

2. Using the project's Settings file, create a setting called "SitesToMonitor" of type System.Collections.Specialized.StringCollection.  This allows you to enter a list of strings, using the ellipsis in the Value column.  The list is saved to the app.config file as an xml ArrayOfString, and can be easily accessed, strongly typed, from your C# code. Enter the list of urls you want to monitor. The resulting config item looks like the following:

3. Create a class with a single method accepting a StringCollection, which iterates through them, attempting to retrieve a response from each, along with a method to do whatever your standard logging is when a site returns a negative status code or throws an exception:

4. Add a single line of code to Program.Main to kick off the process:

5. Create a scheduled task to periodically kick it off, and voila!, you have your very own simple, easy-to-configure Website monitor.

Monday, July 29, 2013

Worst-Smelling Code

I love cleanliness.  I can say that, even as the far reaches of my desk have accumulated an unhealthy layer of dust.  What I'm really talking about here is code.  I have an affinity for clean, concise, logically separated code.  Which means, as you can imagine, when I see messy, duplicated, bloated code, I feel like throwing something (or someone).

In the software development world, we call this "Code Smell".  I wanted to share what I consider to be some of the smelliest (think bad cheese) code.  Keep your code linen fresh, and avoid these:

Duplicated Code.  Sure, it may be a lot faster and easier to just copy those 20 awesome lines of code, and use it everywhere else you need the same logic.  But, you're just hurting yourself (or whoever has to maintain the code).  The disadvantages of copy / paste are obvious: if you need to change the logic due to a business rule change, you'll end up having to change it in all the places you copied it.  However, there are other forms of duplication, where code is copied and then tweaked.  This is even worse, as now you need to multiply the difficulty of reading the code by the number of times it's copied and tweaked.  In this case, for goodness' sake, create a method with parameters!

God Objects.  A "god object" is an object that knows or does too much.  We've all seen examples of this (and are probably guilty of doing it) in the real world.  One of the worst offenders I've seen is a classic ASP app where there was a single .asp page, whose single code path was a huge case statement which, depending on the combination of querystring variables (all integers) would decide where to navigate or what logic to run. It also handled any session variables and caching.

Aside from being a debugging nightmare, god objects go against the time-tested object-oriented tenets of "single responsibility", decoupling and separation of concerns.

My suggestion for breaking up an existing god object is to start from scratch. Document the requirements and properly separate functionality.  Think high cohesion, and low coupling.

Methods with too many parameters.  This is another easy way to create a debugging debacle and maintenance nightmare.  In my opinion, when you get to around 5 parameters, you may want to rethink your approach.  A couple of options would be to 1) create a struct or class to pass instead of the parameter list or 2) rethink the method altogether and consider splitting it up into multiple methods.

Contrived Complexity (See KISS).  Too often, developers either try to follow a pattern which isn't suited for what they're building, or they attempt to create elaborate "frameworks" to make their code flexible to the Nth degree, when the Bth or Cth degree is all that's really needed.  YAGNI is another rule of thumb that directly applies here (You aren't gonna need it).  If we try to anticipate what we might need 2 or 3 years from now and bake it into our code, we create unnecessary complexity, which means code with more room for error and more difficult to test and maintain.  Please, build what you need when you need it, and allow the software to evolve naturally in an agile manner.

Go get rid of that stench!