Monitor Mikrotik log by Telegram

Hey, If you want to monitor your Mikrotik log’s Specific event’s like : excessive broadcast,loop,link down,fcs errors,and even failure login attempts to your server

this method is going to help you as it helped me to monitor +40 Mikrotik server under my control for more than one year in a perfect experiment :sunglasses:

you can filter your log’s parameters and this method will send all event’s about it to your telegram group like a notification :astonished:

Now here is a simple Script with an auto scheduler running every one minute (you can edit it as you like)

Here is the steps:
1-add new script with name “LogFilter”
2-Copy and past the code below
3-edit setup section to your own telegram bot and chat id
4-run the script for first time by your self allowing it to run every one minute

# LOG FILTER TO TELEGRAM BY AHMED MOUSELLY
# BEGIN SETUP Edit Here
:local myserver ([/system identity get name])
:local scheduleName "LogFilter"
:local bot "your bot id"
:local ChatID "-your chat id"
:local startBuf [:toarray [/log find message~" failure" || message~"loop" || message~"down" || message~"fcs" || message~"excessive"]]

# END SETUP

# warn if schedule does not exist
:if ([:len [/system scheduler find name="$scheduleName"]] = 0) do={
  /log warning "[LogFilter] Alert : Schedule does not exist. Creating schedule ...."

 /system scheduler add name=$scheduleName interval=60s start-date=Jul/05/2019 start-time=startup on-event=LogFilter

  /log warning "[LogFilter] Alert : Schedule created ."
}

# get last time
:local lastTime [/system scheduler get [find name="$scheduleName"] comment]
# for checking time of each log entry
:local currentTime
# log message
:local message
 
# final output
:local output

:local keepOutput false
# if lastTime is empty, set keepOutput to true
:if ([:len $lastTime] = 0) do={
  :set keepOutput true
}

:local counter 0
# loop through all log entries that have been found
:foreach i in=$startBuf do={
 
# loop through all removeThese array items
  :local keepLog true
  :foreach j in=$removeThese do={
#   if this log entry contains any of them, it will be ignored
    :if ([/log get $i message] ~ "$j") do={
      :set keepLog false
    }
  }
  :if ($keepLog = true) do={
   
   :set message [/log get $i message]

#   LOG DATE
#   depending on log date/time, the format may be different. 3 known formats
#   format of jan/01/2002 00:00:00 which shows up at unknown date/time. Using as default
    :set currentTime [ /log get $i time ]
#   format of 00:00:00 which shows up on current day's logs
   :if ([:len $currentTime] = 8 ) do={
     :set currentTime ([:pick [/system clock get date] 0 11]." ".$currentTime)
    } else={
#     format of jan/01 00:00:00 which shows up on previous day's logs
     :if ([:len $currentTime] = 15 ) do={
        :set currentTime ([:pick $currentTime 0 6]."/".[:pick [/system clock get date] 7 11]." ".[:pick $currentTime 7 15])
      }
   }
    
#   if keepOutput is true, add this log entry to output
   :if ($keepOutput = true) do={
     :set output ($output.$currentTime." %0A%0A ".$message."\r\n")
   }

    :if ($currentTime = $lastTime) do={
     :set keepOutput true
     :set output ""
   }
  }
  :if ($counter = ([:len $startBuf]-1)) do={
   :if ($keepOutput = false) do={    
     :if ([:len $message] > 0) do={
        :set output ($output.$currentTimer." ".$message."\r\n")
      }
    }
  }
  :set counter ($counter + 1)
}

if ([:len $output] > 0) do={
  /system scheduler set [find name="$scheduleName"] comment=$currentTime
  /tool fetch url="https://api.telegram.org/bot$bot/sendmessage?chat_id=$ChatID&text=$myserver%0A%0A$output" keep-result=no;
}

Note 1: This code will not repeat the same event twice, it takes the last date of the event and saves it and remember to not repeat it again till it appears again in log.

Note 2: Quoted and modified code
Regards.

HI katem07, I used to rely on your great script (vanilla) for almost a year now but yesterday it stopped working all of a sudden without me having changed any settings: script counter is increasing and no error message is being logged but no message is being delivered, I tried reboot/upgrade with no luck, sadly…BTW I get no problem in sending a message manually via browser URL or ROS console…any hint?

Thanks in advance!

I tested the script on my RB750 GR3, the script filters logs perfectly, but I finished it a little with the 6.46 ROS update. Adding an updated version.

# LOG FILTER TO TELEGRAM BY AHMED MOUSELLY//UPD.09.07.2020BergDev
# BEGIN SETUP Edit Here
:local myserver ([/system identity get name])
:local scheduleName "LogFilter"
:local bot "WRITE YOUR BOTID"
:local ChatID "WRITE YOUR CHAT ID"
#Here you can specify which events from the logs you need to send.
:local startBuf [:toarray [/log find message~" failure" || message~"loop"|| message~"sent" || message~"down" || message~"fcs" || message~"excessive"]]

# END SETUP

# warn if schedule does not exist
:if ([:len [/system scheduler find name="$scheduleName"]] = 0) do={
  /log warning "[LogFilter] Alert : Schedule does not exist. Creating schedule ...."

 /system scheduler add name=$scheduleName interval=60s start-date=Jul/09/2020 start-time=startup on-event=LogFilter

  /log warning "[LogFilter] Alert : Schedule created ."
}

# get last time
:local lastTime [/system scheduler get [find name="$scheduleName"] comment]
# for checking time of each log entry
:local currentTime
# log message
:local message
 
# final output
:local output

:local keepOutput false
# if lastTime is empty, set keepOutput to true
:if ([:len $lastTime] = 0) do={
  :set keepOutput true
}

:local counter 0
# loop through all log entries that have been found
:foreach i in=$startBuf do={
 
# loop through all removeThese array items
  :local keepLog true
  :foreach j in=$removeThese do={
#   if this log entry contains any of them, it will be ignored
    :if ([/log get $i message] ~ "$j") do={
      :set keepLog false
    }
  }
  :if ($keepLog = true) do={
   
   :set message [/log get $i message]

#   LOG DATE
#   depending on log date/time, the format may be different. 3 known formats
#   format of jan/01/2002 00:00:00 which shows up at unknown date/time. Using as default
    :set currentTime [ /log get $i time ]
#   format of 00:00:00 which shows up on current day's logs
   :if ([:len $currentTime] = 8 ) do={
     :set currentTime ([:pick [/system clock get date] 0 11]." ".$currentTime)
    } else={
#     format of jan/01 00:00:00 which shows up on previous day's logs
     :if ([:len $currentTime] = 15 ) do={
        :set currentTime ([:pick $currentTime 0 6]."/".[:pick [/system clock get date] 7 11]." ".[:pick $currentTime 7 15])
      }
   }
    
#   if keepOutput is true, add this log entry to output
   :if ($keepOutput = true) do={
     :set output ($output.$currentTime." %0A%0A ".$message."\r\n")
   }

    :if ($currentTime = $lastTime) do={
     :set keepOutput true
     :set output ""
   }
  }
  :if ($counter = ([:len $startBuf]-1)) do={
   :if ($keepOutput = false) do={    
     :if ([:len $message] > 0) do={
        :set output ($output.$currentTimer." ".$message."\r\n")
      }
    }
  }
  :set counter ($counter + 1)
}

if ([:len $output] > 0) do={
  /system scheduler set [find name="$scheduleName"] comment=$currentTime
  /tool fetch url="https://api.telegram.org/bot$bot/sendMessage\?chat_id=$ChatID&text=$myserver%0A%0A$output" keep-result=no;
}

I noticed a bug in the script, notifications from the log are not parsed immediately, but with a delay, or they are not parsed at all, I will try to fix it.

I have other scripts to downloaded txt files and which leaves “downloaded” in log. How can I ignore “downloaded” but keep “down” in the monitor script?

Thanks for your effort!

Can I let User determine the script execution schedule? =)
And do not create it to run once a minute.

...
:if ([:len [/system scheduler find name="$scheduleName"]] = 0) do={
  /log warning "[LOGMON] ERROR: Schedule does not exist. Create schedule and edit script to match name: $scheduleName"
}

# delete this /system scheduler add name=$scheduleName interval=60s start-date=Jul/09/2020 start-time=startup on-event=LogFilter
# delete this /log warning "[LogFilter] Alert : Schedule created ."
 

...

I tried it on HEX works fine and thank you
But I put the same settings on CCR 1036 It didn’t work
is there a solution

Nice script. I am using it in multiple devices and works like a charm


Sent from my iPhone using Tapatalk

Yes, they wrote me about this bug, I’m currently checking the script on different hardware.

The script execution schedule directly depends on the time when the log is sent to the telegram chat. you can try changing the script execution time.

Find any solution to this .?

Does not work on rb4011

Why make a script that has to create a scheduler to launch the script that then one of the two doesn’t work and you waste time figuring out where the problem is ???

The script simply puts itself off the scheduler instead of doing all this ping-pong and checking if the scheduler exists or not.

You have a script that can send logs to a telegram, similar to this? To select which criteria to send (example: critical, failure, warning)…

I do not make script what I can not test.
I do not have telegram,
but if you SEARCH my previous posts I already helped other authors to fix script for similar manner.

Can you help me with this one? On RB4011 do not work... =((

LOG FILTER TO TELEGRAM

BEGIN SETUP Edit Here

:local myserver ([/system identity get name])
:local scheduleName "LogFilter"
:local bot "941325023:AAH-pNTxLr021Av_C7bc9IGVdZDchDlwGb0"
:local ChatID "-262862011"
#Here you can specify which events from the logs you need to send.
:local startBuf [:toarray [/log find message~" failure" || message~"loop" || message~"critical" || message~"error" || message~"fcs" || message~"excessive"]]

END SETUP

warn if schedule does not exist

:if ([:len [/system scheduler find name="$scheduleName"]] = 0) do={
/log warning "[LogFilter] Alert : Schedule does not exist. Creating schedule ...."

/system scheduler add name=$scheduleName interval=300s start-date=Jul/09/2020 start-time=startup on-event=LogFilter

/log warning "[LogFilter] Alert : Schedule created ."
}

get last time

:local lastTime [/system scheduler get [find name="$scheduleName"] comment]

for checking time of each log entry

:local currentTime

log message

:local message

final output

:local output

:local keepOutput false

if lastTime is empty, set keepOutput to true

:if ([:len $lastTime] = 0) do={
:set keepOutput true
}

:local counter 0

loop through all log entries that have been found

:foreach i in=$startBuf do={

loop through all removeThese array items

:local keepLog true
:foreach j in=$removeThese do={

if this log entry contains any of them, it will be ignored

:if ([/log get $i message] ~ "$j") do={
:set keepLog false
}
}
:if ($keepLog = true) do={

:set message [/log get $i message]

LOG DATE

depending on log date/time, the format may be different. 3 known formats

format of jan/01/2002 00:00:00 which shows up at unknown date/time. Using as default

:set currentTime [ /log get $i time ]

format of 00:00:00 which shows up on current day's logs

:if ([:len $currentTime] = 8 ) do={
:set currentTime ([:pick [/system clock get date] 0 11]." ".$currentTime)
} else={

format of jan/01 00:00:00 which shows up on previous day's logs

:if ([:len $currentTime] = 15 ) do={
:set currentTime ([:pick $currentTime 0 6]."/".[:pick [/system clock get date] 7 11]." ".[:pick $currentTime 7 15])
}
}

if keepOutput is true, add this log entry to output

:if ($keepOutput = true) do={
:set output ($output.$currentTime." %0A%0A ".$message."\r\n")
}

:if ($currentTime = $lastTime) do={
:set keepOutput true
:set output ""
}
}
:if ($counter = ([:len $startBuf]-1)) do={
:if ($keepOutput = false) do={
:if ([:len $message] > 0) do={
:set output ($output.$currentTimer." ".$message."\r\n")
}
}
}
:set counter ($counter + 1)
}

if ([:len $output] > 0) do={
/system scheduler set [find name="$scheduleName"] comment=$currentTime
/tool fetch url="https://api.telegram.org/bot$bot/sendmessage?chat_id=$ChatID&text=$myserver%0A%0A$output" keep-result=no;
}

doesn’t work on CCR1036 , any new updates for this script. Please?

Same on ccr-1009

Someone help the user, please.

I do not have telegram (and I do not want have it)


# LOG FILTER TO TELEGRAM
# BEGIN SETUP Edit Here
:local myserver ([/system identity get name])
:local scheduleName "LogFilter"
:local bot "941325023:AAH-pNTxLr021Av_C7bc9IGVdZDchDlwGb0"
:local ChatID "-262862011"
#Here you can specify which events from the logs you need to send.
:local startBuf [:toarray [/log find message~" failure" || message~"loop" || message~"critical" || message~"error" || message~"fcs" || message~"excessive"]]

# END SETUP

# warn if schedule does not exist
:if ([:len [/system scheduler find name="$scheduleName"]] = 0) do={
  /log warning "[LogFilter] Alert : Schedule does not exist. Creating schedule ...."

 /system scheduler add name=$scheduleName interval=300s start-date=Jul/09/2020 start-time=startup on-event=LogFilter

  /log warning "[LogFilter] Alert : Schedule created ."
}

# get last time
:local lastTime [/system scheduler get [find name="$scheduleName"] comment]
# for checking time of each log entry
:local currentTime
# log message
:local message
 
# final output
:local output

:local keepOutput false
# if lastTime is empty, set keepOutput to true
:if ([:len $lastTime] = 0) do={
  :set keepOutput true
}

:local counter 0
# loop through all log entries that have been found
:foreach i in=$startBuf do={
 
# loop through all removeThese array items
  :local keepLog true
  :foreach j in=$removeThese do={
#   if this log entry contains any of them, it will be ignored
    :if ([/log get $i message] ~ "$j") do={
      :set keepLog false
    }
  }
  :if ($keepLog = true) do={
   
   :set message [/log get $i message]

#   LOG DATE
#   depending on log date/time, the format may be different. 3 known formats
#   format of jan/01/2002 00:00:00 which shows up at unknown date/time. Using as default
    :set currentTime [ /log get $i time ]
#   format of 00:00:00 which shows up on current day's logs
   :if ([:len $currentTime] = 8 ) do={
     :set currentTime ([:pick [/system clock get date] 0 11]." ".$currentTime)
    } else={
#     format of jan/01 00:00:00 which shows up on previous day's logs
     :if ([:len $currentTime] = 15 ) do={
        :set currentTime ([:pick $currentTime 0 6]."/".[:pick [/system clock get date] 7 11]." ".[:pick $currentTime 7 15])
      }
   }
    
#   if keepOutput is true, add this log entry to output
   :if ($keepOutput = true) do={
     :set output ($output.$currentTime." %0A%0A ".$message."\r\n")
   }

    :if ($currentTime = $lastTime) do={
     :set keepOutput true
     :set output ""
   }
  }
  :if ($counter = ([:len $startBuf]-1)) do={
   :if ($keepOutput = false) do={    
     :if ([:len $message] > 0) do={
        :set output ($output.$currentTimer." ".$message."\r\n")
      }
    }
  }
  :set counter ($counter + 1)
}

if ([:len $output] > 0) do={
  /system scheduler set [find name="$scheduleName"] comment=$currentTime
  /tool fetch url="https://api.telegram.org/bot$bot/sendmessage\?chat_id=$ChatID&text=$myserver%0A%0A$output" keep-result=no;
}