Schedule a schedule?

Hi All

I have a schedule that runs a check of the logs every 5 minutes for an knock attemp that has shown up in the logs over the last 5 minutes, which I then get an email. For some reason the knock that was found at say may be 9am will between 12am and 1am sends me about 15 emails all 5 mins apart with this knock event that happened earlier in the day, which it should not.

Is there anyway I can schedule a schedule to only run between certain hours every 5 mins?

Thanks

What you can do is running your set of checks/statements in a script, where you put some check after that you have sent the first email, so that you are not sending such email every single time, but after another condition that you will set to reset such block.
Then you can control better how to trigger an event and relate an action like sending an email based on some additional control to avoid being bombarded by the same email every 5 minutes.

Armando.

Hi Armando

I only get the email at the time within that 5 minute range. If only if there was an event then between 12am and 1am it sends the email about 12 times but not other time

Thanks

Glenn

Hi Glenn,
OK, I understand now your point.
So you can manage it in couple of ways giving you different level of flexibility.
One way could be making the main code that runs every 5 min (analyzing the log) to be executed as a loop, without using a scheduler for that.
In this way the main execution will be done by the script itself every 5 minutes; inside this you can code the portion that is triggered only between the defined time to send email.
Otherwise you can keep using the schedule to run your script every 5 minutes, but you still need to integrate a portion of code that is triggered on the time window that you want to send emails.
In case of the schedule you can use the comment field to write down each execution time, so that you can use that to avoid duplicates when sending out the desired event (email or any other type of notification).
Just to give you some ideas to play with… but you will have to put your hands into your main script to achieve this.
Otherwise to use only schedulers you might have to split your code in 2 parts; the main to collect info every 5 min and another one to send emails between your time window based on the related schedule and you will have to collect info somewhere (global variable, file, etc) to feed the email preparation.

Armando.

Glenn,
I have a script that does essentially exactly what you want. I fully admit that I got most of the script from a post here several years ago and modified it for my own purposes. In my case, I am checking for login, logout, login failure, and several port knock conditions. The script writes a comment for the script as to when it ran, and reads that comment the next time it runs in order to know how far back to go in the log the next time it runs. The script sends the E-Mails to two different addresses. The scheduler runs the script every minute. I am posting the entire script with only a couple redactions. Fortunately, the original author included many comments which helped me edit the script for my purposes.

add dont-require-permissions=no name="Send login alert" owner=Manager \
    policy=ftp,read,write,policy,test,password,sensitive source="# BEGIN SETUP\
    \r\
    \n:local scheduleName \"Send Login alert\"\r\
    \n:local emailAddress1 \"redacted@gmail.com\"\r\
    \n:local emailAddress2 \"jim@redacted.com\"\r\
    \n:local startBuf [:toarray [/log find message~\"logged in\" || message~\"\
    login failure\" || message~\"logged out\" || message~\"Short Port Knock st\
    ep 2\" || message~\"Long Port Knock step 4\" || message~\"Single Internet \
    only Port Knock step 6\"]]\r\
    \n:local removeThese {\"zippo\";\"whatever string you want to ignore\"}\r\
    \n# END SETUP\r\
    \n\r\
    \n# warn if schedule does not exist\r\
    \n:if ([:len [/system scheduler find name=\"\$scheduleName\"]] = 0) do={\r\
    \n  /log warning \"[LOGMON] ERROR: Schedule does not exist. Create schedul\
    e and edit script to match name\"\r\
    \n}\r\
    \n\r\
    \n# get last time\r\
    \n:local lastTime [/system scheduler get [find name=\"\$scheduleName\"] co\
    mment]\r\
    \n# for checking time of each log entry\r\
    \n:local currentTime\r\
    \n# log message\r\
    \n:local message\r\
    \n \r\
    \n\r\
    \n# final output\r\
    \n:local output\r\
    \n\r\
    \n:local keepOutput false\r\
    \n# if lastTime is empty, set keepOutput to true\r\
    \n:if ([:len \$lastTime] = 0) do={\r\
    \n  :set keepOutput true\r\
    \n}\r\
    \n\r\
    \n\r\
    \n:local counter 0\r\
    \n# loop through all log entries that have been found\r\
    \n:foreach i in=\$startBuf do={\r\
    \n \r\
    \n\r\
    \n# loop through all removeThese array items\r\
    \n  :local keepLog true\r\
    \n  :foreach j in=\$removeThese do={\r\
    \n#   if this log entry contains any of them, it will be ignored\r\
    \n    :if ([/log get \$i message] ~ \"\$j\") do={\r\
    \n      :set keepLog false\r\
    \n    }\r\
    \n  }\r\
    \n  :if (\$keepLog = true) do={\r\
    \n   \r\
    \n   :set message [/log get \$i message]\r\
    \n\r\
    \n#   LOG DATE\r\
    \n#   depending on log date/time, the format may be different. 3 known for\
    mats\r\
    \n#   format of jan/01/2002 00:00:00 which shows up at unknown date/time. \
    Using as default\r\
    \n    :set currentTime [ /log get \$i time ]\r\
    \n#   format of 00:00:00 which shows up on current day's logs\r\
    \n   :if ([:len \$currentTime] = 8 ) do={\r\
    \n     :set currentTime ([:pick [/system clock get date] 0 11].\" \".\$cur\
    rentTime)\r\
    \n    } else={\r\
    \n#     format of jan/01 00:00:00 which shows up on previous day's logs\r\
    \n     :if ([:len \$currentTime] = 15 ) do={\r\
    \n        :set currentTime ([:pick \$currentTime 0 6].\"/\".[:pick [/syste\
    m clock get date] 7 11].\" \".[:pick \$currentTime 7 15])\r\
    \n      }\r\
    \n   }\r\
    \n    \r\
    \n\r\
    \n#   if keepOutput is true, add this log entry to output\r\
    \n   :if (\$keepOutput = true) do={\r\
    \n     :set output (\$output.\$currentTime.\"  \".\$message.\"\\r\\n\\n\")\
    \r\
    \n   }\r\
    \n#   if currentTime = lastTime, set keepOutput so any further logs found \
    will be added to output\r\
    \n#   reset output in the case we have multiple identical date/time entrie\
    s in a row as the last matching logs\r\
    \n#   otherwise, it would stop at the first found matching log, thus all f\
    ollowing logs would be output\r\
    \n    :if (\$currentTime = \$lastTime) do={\r\
    \n     :set keepOutput true\r\
    \n     :set output \"\"\r\
    \n   }\r\
    \n  }\r\
    \n\r\
    \n#   if this is last log entry\r\
    \n  :if (\$counter = ([:len \$startBuf]-1)) do={\r\
    \n#   If keepOutput is still false after loop, this means lastTime has a v\
    alue, but a matching currentTime was never found.\r\
    \n#   This can happen if 1) The router was rebooted and matching logs stor\
    ed in memory were wiped, or 2) An item is added\r\
    \n#   to the removeThese array that then ignores the last log that determi\
    ned the lastTime variable.\r\
    \n#   This resets the comment to nothing. The next run will be like the fi\
    rst time, and you will get all matching logs\r\
    \n   :if (\$keepOutput = false) do={\r\
    \n#     if previous log was found, this will be our new lastTime entry    \
    \_ \r\
    \n     :if ([:len \$message] > 0) do={\r\
    \n        :set output (\$output.\$currentTime.\" \".\$message.\"\\r\\n\")\
    \r\
    \n      }\r\
    \n    }\r\
    \n  }\r\
    \n  :set counter (\$counter + 1)\r\
    \n}\r\
    \n\r\
    \n\r\
    \n# If we have output, save new date/time, and send email\r\
    \nif ([:len \$output] > 0) do={\r\
    \n  /log info \"[LOGMON] New login or logout logs found, sending E-Mail.\"\
    \r\
    \n  /system scheduler set [find name=\"\$scheduleName\"] comment=\$current\
    Time\r\
    \n  /tool e-mail send to=\"\$emailAddress1\" subject=\"MikroTik RB750Gr3 #\
    1 Log in or out alert \$currentTime\" body=\"Sent from Microtik RB750Gr3 #\
    1 \\n \\n \$output\"\r\
    \n  /tool e-mail send to=\"\$emailAddress2\" subject=\"MikroTik RB750Gr3 #\
    1 Log in or out alert \$currentTime\" body=\"Sent from Microtik RB750Gr3 #\
    1 \\n \\n \$output\"\r\
    \n  /log info \"Login / Logout update E-Mail sent.\"\r\
    \n}\r\
    \n"

@k6ccc

Many thanks for that, I will take a good look.

@accarda

Many thanks for your suggestions

No problem.
And if you want to stick with the easy scheduler, you can use 3 in total; 2 to trigger the start/stop and the one that you already have.

scheduler 1 to run at 12am only once, no repetition to start triggering the email to be sent:

:global sendEmail true

Scheduler 2 to run at 1am only once, no repetition to stop triggering the email:

:global sendEmail false

The other scheduler is the one that you already have.
Inside the code, where you have the portion to send the email, just put it inside an IF condition:

if ($sendEmail) do={
 the portion of code to send email
}

Done, now the email is sent only between 12am to 1am.
Armando.