Thanks Rich,
I was indeed checking for NULL but not the profile.state 
The code is now functioning as I expected and provides an hourly check that rules are being run.
DIAG RULE
///////////////////////////////////////////////////
// Actions scheduled ever 60 minutes
rule "Scehuled 60 minute diagnostics check"
when
Time cron "30 1 * ? * *"
then
logInfo("diags-auto.rules", "Scheduled 1 hour diagnostic check.")
RulesLastRun.members.forEach[ profile |
var _rule = profile.name.split("_").get(0)
if (profile.state == NULL) {
logInfo("diags-auto.rules","somethings wrong with "+profile.name)
sendMail("me@example.com", "Rule Diag Check.", "The rule "+_rule+" rule has not ran successfully in the last hour.")
return;
}
try {
var _LastSeen = (now.millis - (new DateTime(profile.state.toString).millis)) /1000
if (_LastSeen > 3600 || _LastSeen==NULL || _LastSeen==UNDEF ) {
logInfo("diags-auto.rules","somethings wrong with "+_rule)
sendMail("me@example.com", "Rule Diag Check.", "The rule "+_rule+" has not ran successfully in the last hour.")
} else {
logInfo("diags-auto.rules","rule running successfully: "+_rule)
}
logInfo("diags-auto.rules", " Rule: "+profile.name+" Timer: "+_LastSeen)
}
catch(Throwable t) {
logError("ReadPodID", "Error was caught: {}", t)
sendMail("me@example.com", "Rule Diag Check error thrown.", "Error: "+t)
}
]
end
The rule is in a file on its own so less likely to be caught out with a typo, and is setup to use a group and an item file as suggested by @RolfV
ITEMS
// Group definition
Group RulesLastRun
// files to check rules are loaded ok
DateTime alexa_Rules_LastRun (RulesLastRun)
DateTime appliances_Rules_LastRun (RulesLastRun)
DateTime asterisk_Rules_LastRun (RulesLastRun)
DateTime astro_Rules_LastRun (RulesLastRun)
As @rikoshak quite rightly pointed out this is not the ideal solution, it was not that easy to setup and requires ongoing maintenance AND only looks after rule files.
I selected the check to be made in each Rule file like the example one below every hour.
Individual RULE file entry
// perform diag check every 60 minutes.
rule "Check 60 minute diags alexa"
when
Time cron "20 0 * * * ?"
then
alexa_Rules_LastRun.postUpdate(new DateTimeType)
end```
Now the alternative solution proposed by Rich is to use an external application or script to parse the openhab log file, I am sure there are some great utilities out there to do this with style, but in the end I chose a simple approach.
I run the bash script below three times a day using a crontab entry.
**CRONTAB**
```csv
0 6,16,23 * * * /etc/openhab2/scripts/chk_log
And the script chk_log
#!/bin/bash
# Checks openhablog for errors by Paul Miller 2019
# Revisions: 0.1 - 29/04/2019 Initial Release 0.1 -
logger "***********************************************"
logger "Script $0 has been executed."
logger "***********************************************"
##set your email address
EMAIL="me@example.com"
## set the openhab log filename and full path
LOG=/var/log/openhab2/openhab.log
#### DO NOT CHANGE anything BELOW ####
MESSAGE="$(grep "error\|Refreshing" $LOG)"
SUBJECT="Log check $(hostname) $(date) "
echo " $MESSAGE " | mail -s "$SUBJECT" "$EMAIL"
Remembering to set the file to be executable
and then check your emails for the interesting log snippets.
The patterns to be matched can be increased I only have two showing “error|Refreshing”.
I also have this running.
As it really takes some time to get these setup exactly as you like I suggest a couple weeks trial before I make drastic changes.
I hope this helps some one else and once again thanks for the suggestions.
Regards
Paul