Ask HN: A simple tcp monitor ?
I'm sure I can whip up something simple but my experience is that such simple things tend to get more complicated than you expect once you start building.
The intended platform is linux.
I'm sure I can whip up something simple but my experience is that such simple things tend to get more complicated than you expect once you start building.
The intended platform is linux.
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <netdb.h>
int main(int argc, char ** argv)
{
struct hostent * he;
struct sockaddr_in sa = { AF_INET };
unsigned int port;
int foo, sk;
if (argc != 3)
return 1; /* Syntax error */
if (sscanf(argv[2], "%u%n", &port, &foo) != 1 ||
strlen(argv[2]) != foo ||
port > 65535)
return 1; /* Syntax error */
he = gethostbyname(argv[1]);
if (! he)
return 2; /* DNS error,OS error or syntax error */
sa.sin_addr.s_addr = *(unsigned long*)he->h_addr;
sa.sin_port = htons(port);
sk = socket(AF_INET, SOCK_STREAM, 0);
if (sk < 0)
return 3; /* OS error */
if (connect(sk, (void*)&sa, sizeof sa) < 0)
return 4; /* TCP error */
return 0;
}
To build: gcc tcp-check.c -o tcp-check
To use: ./tcp-check yahoo.com 80; echo $?
0 is OK, 1 - syntax error, 2 - DNS error, 3 - OS error, 4 - TCP error. Call it from a shell script, look at the return value and, if it's non-zero, dispatch your message. Then stick the script itself into a cron schedule, and you are done.The trick will be just limiting it to simple functionality. Easy for these types of apps to get out of hand.
About ten years ago I wanted to write a windows app that allowed text to appear as a window -- no rectangular frame, menu, or close button. Just text. The text was the window, and there was nothing else but the text.
I figured out how to do it, and ended up writing something that had a properties page that looked like it could launch Trident Missiles. Fun project, but definitely overkill for what I needed.
Nagios will do the job but it's total overkill. Ideally a simple solution such as:
./monitor http://localhost:someport/ 60 "/etc/init.d/someservice restart"
should do the trick (resource, checkinterval, action)And that's exactly why you don't roll these things on your own unless you have a very good reason. Making sure a cronjob doesn't stack up reliably is non-trivial and becomes extremely hairy when the network gets involved. Many people think "I'll just use a lockfile" - think again.
Since for monitoring scripts this kind of reliability is the whole point, I strongly suggest to use something like monit where someone else has already worked out all the little corner cases.
I still think a smart wrapper around check_tcp is the way to do this. Perhaps not out of cron, it can instead be a long running process in a sleep/fork/exec(check_tcp)/waitpid loop.
I use it in a medium to high volume production environment [2], and it has done a very good job at getting our lighttpd and nginx back up on the air whenever we experience peaks above the normal workload.