skip to Main Content

I have a script that is running continuously in the server, in this case a PHP script, like:

php path/to/my/index.php.

It’s been executed, and when it’s done, it’s executed again, and again, forever.

I’m looking for the best way to be notified if that event stop running(been executed).

There are many reasons why it stops been called, like server memory, new deployment, human error… etc.

I just want to be notified(email, sms, slack…) if that script was not executed for certain amount of time(like 1 hour, 1 day, etc…)

My server is Ubuntu living in AWS.

An idea:
I was thinking on having an index in REDIS/MEMCACHED/ETC with a TTL. Every time the script run, renovate that TTL for this index.

If the script stop working for that TTL time, this index will expire. I just need a way to trigger a notification when that expiration happen, but looks like REDIS/MEMCACHED are not prepared for that

2

Answers


  1. register_shutdown_function might help, but might not… https://www.php.net/manual/en/function.register-shutdown-function.php

    I can’t say i’ve ever seen a script that needs to run indefinitely in PHP. Perhaps there is another way to solve the problem you are after?

    Login or Signup to reply.
  2. Update – Following your redis idea, I’d look at keyspace notifications. https://redis.io/topics/notifications

    I’ve not tested the idea since I’m not actually a redis user. But it may be possible to subscribe to capture the expiration event (perhaps from another server?) and generate your notification.


    There’s no ‘best’ way to do this. Ultimately, what works best will boil down to the specific workflow you’re supporting.

    tl;dr version: Find what constitutes success and record the most recent time it happened. Use that for your notification trigger in another script.

    Long version:

    That said, persistent storage with a separate watcher is probably the most straight-forward way to do this. Record the last successful run, and then check it with a cron job every so often.

    For what it’s worth, for scripts like this I generally monitor exit codes or logs produced by the script in question. This isolates the error notification process from the script itself so a flaw in the script (hopefully) doesn’t hamper the notification.

    For a barebones example, say we have a script to invoke the actual script… (This is very much untested pseudo-code)

    <?php
    //Run and record.
    exec("php path/to/my/index.php", $output, $return_code);
    //$return_code will be 255 on fatal errors. You can use other return codes
    //with exit in your called script to report other fail states.
    if($return_code == 0) {
      file_put_contents('/path/to/folder/last_success.txt', time());
    } else {
      file_put_contents('/path/to/folder/error_report.json', json_encode([
        'return_code' => $return_code,
        'time' => time(),
        'output' => implode("n", $output), 
          //assuming here that error output isn't silently logged somewhere already.
      ], JSON_PRETTY_PRINT));
    }
    

    And then a watcher.php that monitors these files on a cron job.

    <?php
    //Notify us immediately on failure maybe?
    //If you have a lot of transient failures it may make more sense to
    //aggregate and them in a single report at a specific time instead.
    if(is_file('/path/to/folder/error_report.json')) {
      //Mail details stored in JSON here.
    
      //rename file so it's recorded, but we don't receive it again.
      rename('/path/to/folder/error_report.json', '/path/to/folder/error_report.json'.'-sent-'.date('Y-m-d-H-i-s'));
    } else {
      if(is_file('/path/to/folder/last_success.txt')) {
        $last_success = intval(file_get_contents('/path/to/folder/last_success.txt'));
        if(strtotime('-24 hours') > $last_success) {
          //Our script hasn't run in 24 hours, let someone know.
        }
      } else {
        //No successful run recorded. Might want to put code here if that's unexpected.
      }
    }
    

    Notes: There are some caveats to the specific approach displayed above. A script can fail in a non-fatal way and if you’re not checking for it this example could record that as a successful run. For example, permissions errors causing warnings but the script still runs it’s full course and exits normally without hitting an exit call with a specific return code. Our example invoker here would log that as a successful run – even though it isn’t.

    Another option is to log success from your script and only check for error exits from the invoker.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search