rockmountain has asked for the wisdom of the Perl Monks concerning the following question:

There is a critical service in my machine which crashes once in a month. I want to write an application which monitors that process and if that crashes sends email, or SMS or if possible restarts the service.

I am trying with Enumerating Process. But that doesn't seem to be the solution. Also, any inputs for writing windows services in perl will be a great help.

cheers Rock

Replies are listed 'Best First'.
Re: Monitoring a process
by NetWallah (Canon) on Feb 01, 2005 at 05:18 UTC
    Here is some code that can help get you started with WIn32 services: Of course, it needs to be run with appropriate priviledges.

        ..."I don't know what the facts are but somebody's certainly going to sit down with him and find out what he knows that they may not know, and make sure he knows what they know that he may not know, and that's a good thing. I think it's a very constructive exchange," --Donald Rumsfeld

Re: Monitoring a process
by saintmike (Vicar) on Feb 01, 2005 at 06:55 UTC
    There's two different approaches to tackle this problem:
    • You write a wrapper program that launches the to-be-monitored program and detects if the latter crashes.
    • Have a separate application which periodically pings the to-be-monitored program. In the Unix world, there are readily available applications like nagios, specializing in this kind of thing. Comes with the benefit that you can draw nice "uptime graphs" to show to management.

    Implementation details are different for different services. A web application can be monitored by running HTTP requests, other applications can be "ping"ed on a port or checked via SNMP.

Re: Monitoring a process
by ZlR (Chaplain) on Feb 01, 2005 at 10:38 UTC
    Hello,

  • Use Win32::Service::GetStatus to check state.

  • Compare to known runing value and do something if needed.

  • Sleep for sometime or re-schedule with AT .

    Here's how i check state :

    Win32::Service::GetStatus( $server, $service_name, \%ServHash ) if ( $ServHash{CurrentState} != 4 ) { It_s_not_runing_do_something() } ;

    Sometimes it's not enough to GetStatus, for example if you're trying to monitor something that is launched by a running service. In that case you may have to check for the value of a key in the registry. This is done with Win32::TieRegistry.

    ZlR

Re: Monitoring a process
by Anonymous Monk on Feb 01, 2005 at 13:31 UTC
    I believe you may be over thinking. What do you WANT to do? Scan a list of processes? *I* would do that as something like $retval = `ps ax`; Then look in $retval for your process, and if it's not there, do the actions you're interested in... Too vague?

      *I* would do that as something like $retval = `ps ax`;

      Well, seeing as he's prolly on a Win32 box because he mentions "Also, any inputs for writing windows services in perl will be a great help." sort of leaves ps ax out don't you think?

      -- vek --
        That was foolish on part of me, not to mention the platform. I apologize for the error and appreciate the wisdom shown by you monks. Now I realize that Perl not just a language. It is a way of life.

        Having said that, "Can I use perl for embedded application?" I mean I am asking from efficiency point of you.

        While debugging application I find that "this" pointer thing is present in Perl also. But one thing surprised me, Virtual function.

        In C++ there is a particular situation where we have to think about Virtual Function, while in Perl I am in dark about it. Can you guys refer me to some links which tells me in structures manner about Virtual Table and Virtual Pointer in Perl , so that I can look forward perl as a language to implement COM classes.

        cheers Rock
Re: Monitoring a process
by Anonymous Monk on Feb 01, 2005 at 15:53 UTC
    If it's on Unix, and it's a critical service that needs to be restarted you could write a wrapper script that's basically an infinite loop in which the service is called. Something like:
    while (1) { system "/path/to/service", @args; ... do something with $? ... }
    But then, what if the wrapper crashes (or is killed)?

    An alternative is to have init start the service, and have it respawn automatically. For instance, by putting the following line in /etc/inittab:

    name:345:respawn:/path/to/service
    Or to a wrapper script that starts the service, and mails the admin if the service fails (no loop needed in this wrapper script).

    If the service is critical, and you're running Windows, good luck to you. I wouldn't run critical services on Windows. I guess one crash a month isn't too bad for Windows.