Community discussions

MikroTik App
 
User avatar
k6ccc
Forum Guru
Forum Guru
Topic Author
Posts: 1490
Joined: Fri May 13, 2016 12:01 am
Location: Glendora, CA, USA (near Los Angeles)
Contact:

Script output to a file

Fri Sep 16, 2022 9:55 pm

OK, I fully admit that I am VERY weak at Mikrotik scripting.
I have a script that does some ping floods and logs the results to the log. It is working just fine. However it is filling the log more than I would like. I would like to write the results to a file rather than the log. Then my daily backup script would send the file and delete it so as to not take up too much file space. This part, I know how to do already.
So what I am trying to do is modify this line so that it writes to a file instead of the log.
:log info "Average RTT to $IP1  $IP1n is:  $AvgRtt1  Alarm threshold is:  $ErrLvl1"

This is on a RB4011iGS+ running 6.49.6 (at least for now, will go to 7.x one of these days).
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Script output to a file

Fri Sep 16, 2022 10:42 pm

You are not weak, as long as you ask for help and help others.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Script output to a file  [SOLVED]

Fri Sep 16, 2022 10:49 pm

The log is cleared if the size exceded the maximum managed value from RouterOS (4095 Bytes)

The Function
:global addLogToFile do={
    :local filename "$1"
    :local fileext  ".txt" ; # can be only .txt !!!
    :local maxlen 4095
    /file
    :if ([:len [find where name="flash" and type="disk"]] = 1) do={:set filename "flash/$filename"}
    :local wkfilename "$filename$fileext"
    :if ([:len [find where name=$wkfilename]] = 0) do={print file="$wkfilename"; :delay 2s; set $wkfilename contents=""; :delay 1s}
    :local filecon [get $wkfilename contents]
    :local filelen [:len $filecon]
    :local addthis "$2\r\n"
    :local addlen  [:len $addthis]
    :if (($filelen + $addlen) > $maxlen) do={
        :set filecon ""
        :set filelen 0
        :delay 2s
    }
    :set filecon  "$filecon$addthis"
    set $wkfilename contents=$filecon
    :delay 1s
}

example code

# put the function at the start of the script and replace
:log info "Average RTT to $IP1  $IP1n is:  $AvgRtt1  Alarm threshold is:  $ErrLvl1"
# with
:local filename "test" ; # do not put any extension, only the filename
:local logthis  "Average RTT to $IP1  $IP1n is:  $AvgRtt1  Alarm threshold is:  $ErrLvl1"
[$addLogToFile $filename $logthis]
 
User avatar
k6ccc
Forum Guru
Forum Guru
Topic Author
Posts: 1490
Joined: Fri May 13, 2016 12:01 am
Location: Glendora, CA, USA (near Los Angeles)
Contact:

Re: Script output to a file

Sat Sep 17, 2022 1:42 am

Thank Rextended.

No workie
Inserted the function part at the top - actually below a remark about what the script does.
Inserted bottom part after the existing write to log entry (so temporarily, both the log entry and the file entry would write)
Script runs, but stops after the log entry, but does not create a file according to the file list in WinBox, and subsequent ping tests do not run (this test being run on the first of five in the script).
# Start the test for IP 1
/tool flood-ping $IP1 count=10 do={
:if ($sent = 10) do={
:set AvgRtt1 $"avg-rtt"
}}
:log info "Average RTT to $IP1  $IP1n is:  $AvgRtt1  Alarm threshold is:  $ErrLvl1"
    <<<<<====  Appears to stop here (obviously this note is not in the script).
:local filename "test";
:local logthis  "Average RTT to $IP1  $IP1n is:  $AvgRtt1  Alarm threshold is:  $ErrLvl1"
[$addLogToFile $filename $logthis]

# Start the test for IP 2

And as I read your instructions, I may want to make the file entry a bit less verbose so it does not exceed the 4095 bytes as fast. Once I see how quickly the file fills up will dictate how often I E-Mail it to me and delete the file...
 
User avatar
k6ccc
Forum Guru
Forum Guru
Topic Author
Posts: 1490
Joined: Fri May 13, 2016 12:01 am
Location: Glendora, CA, USA (near Los Angeles)
Contact:

Re: Script output to a file

Sat Sep 17, 2022 1:44 am

And yes, I will be picking this apart in order to help learn how it works - I learn something that way...
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Script output to a file

Sat Sep 17, 2022 2:09 am

I do not see the rest of the script, but this works for me

test code

# obviously here go the "addLogToFile" global function

{
# variables needed
:local IP1 127.0.0.1
:local IP1n 1
:local AvgRtt1 0
:local ErrLvl1 0

/tool flood-ping $IP1 count=10 do={
    :if ($sent = 10) do={
        :set AvgRtt1 $"avg-rtt"
    }
}

:log info "Average RTT to $IP1  $IP1n is:  $AvgRtt1  Alarm threshold is:  $ErrLvl1"

:local filename "test"
:local logthis  "Average RTT to $IP1  $IP1n is:  $AvgRtt1  Alarm threshold is:  $ErrLvl1"
[$addLogToFile $filename $logthis]
}
 
User avatar
k6ccc
Forum Guru
Forum Guru
Topic Author
Posts: 1490
Joined: Fri May 13, 2016 12:01 am
Location: Glendora, CA, USA (near Los Angeles)
Contact:

Re: Script output to a file

Sat Sep 17, 2022 8:31 pm

Thank you for your time sir!
Have not had time to play with it, but here is the entire script. It runs up to the log entry for the results of IP 1, but nothing after that (about half way down the page). Yea, the E-Mail part at the bottom is ugly, but it works (when the script gets that far).
# Ping address and send E-Mail if average RTT exceeds threshold.

:global addLogToFile do={
    :local filename "$1"
    :local fileext  ".txt" ; # can be only .txt !!!
    :local maxlen 4095
    /file
    :if ([:len [find where name="flash" and type="disk"]] = 1) do={:set filename "flash/$filename"}
    :local wkfilename "$filename$fileext"
    :if ([:len [find where name=$wkfilename]] = 0) do={print file="$wkfilename"; :delay 2s; set $wkfilename contents=""; :delay 1s}
    :local filecon [get $wkfilename contents]
    :local filelen [:len $filecon]
    :local addthis "$2\r\n"
    :local addlen  [:len $addthis]
    :if (($filelen + $addlen) > $maxlen) do={
        :set filecon ""
        :set filelen 0
        :delay 2s
    }
    :set filecon  "$filecon$addthis"
    set $wkfilename contents=$filecon
    :delay 1s
}

:log info "Starting AREDN ping test."

# :log info "Setting up variables."

# This section is setting up variables

# Set the monitored IP address for test 1
:local IP1 10.133.246.214;
# Set the monitored node name for test 1
:local IP1n W6BI-Shack-Node;

# Set the monitored IP address for test 2
:local IP2 10.108.103.15;
# Set the monitored node name for test 2
:local IP2n K6PVR-VC-Camarillo-Hills-SW-5G;

# Set the monitored IP address for test 3
:local IP3 10.98.158.62;
# Set the monitored node name for test 3
:local IP3n K6PVR-VC-West-SouthMtn-SE-5G;

# Set the monitored IP address for test 4
:local IP4 10.234.99.239;
# Set the monitored node name for test 4
:local IP4n K6PVR-VC-Sulphur-to-Oxnard-5G;

# Set the monitored IP address for test 5
:local IP5 10.162.170.94;
# Set the monitored node name for test 5
:local IP5n K6PVR-LA-Verdugo-S-Sector-5G;

# :log info "IPs and names set."

# Set the alarm threshhold times in mSec
:local ErrLvl1 100;
:local ErrLvl2 150;
:local ErrLvl3 200;
:local ErrLvl4 200;
:local ErrLvl5 150;

# Set up variables for average return times
:local AvgRtt1;
:local AvgRtt2;
:local AvgRtt3;
:local AvgRtt4;
:local AvgRtt5;

# :log info "Thresholds set."

# Set up variables for error E-Mails
:local Sub1 "Excessive AREDN ping time from Router #1."
:local Sub2 "Ping failure to"
:local Sub3 "from Router #1."
:local Bo1 "Test to IP: "
:local Bo2 "Average ping RTT: "
:local Bo3 "Threshhold: "

# :log info "E-Mail variables set"

# Start the test for IP 1
/tool flood-ping $IP1 count=10 do={
:if ($sent = 10) do={
:set AvgRtt1 $"avg-rtt"
}}
:log info "Average RTT to $IP1  $IP1n is:  $AvgRtt1  Alarm threshold is:  $ErrLvl1"
           <<<<<<<<<=======  This is where it is stopping.
:local filename "test";
:local logthis  "Average RTT to $IP1  $IP1n is:  $AvgRtt1  Alarm threshold is:  $ErrLvl1"
[$addLogToFile $filename $logthis]

# Start the test for IP 2
/tool flood-ping $IP2 count=10 do={
:if ($sent = 10) do={
:set AvgRtt2 $"avg-rtt"
}}
:log info "Average RTT to $IP2  $IP2n is:  $AvgRtt2  Alarm threshold is:  $ErrLvl2"

# Start the test for IP 3
/tool flood-ping $IP3 count=10 do={
:if ($sent = 10) do={
:set AvgRtt3 $"avg-rtt"
}}
:log info "Average RTT to $IP3  $IP3n is:  $AvgRtt3  Alarm threshold is:  $ErrLvl3"

# Start the test for IP 4
/tool flood-ping $IP4 count=10 do={
:if ($sent = 10) do={
:set AvgRtt4 $"avg-rtt"
}}
:log info "Average RTT to $IP4  $IP4n is:  $AvgRtt4  Alarm threshold is:  $ErrLvl4"

# Start the test for IP 5
/tool flood-ping $IP5 count=10 do={
:if ($sent = 10) do={
:set AvgRtt5 $"avg-rtt"
}}
:log info "Average RTT to $IP5  $IP5n is:  $AvgRtt5  Alarm threshold is:  $ErrLvl5"

# Send E-Mails if Average RTT exceeds threshhold

:if (($AvgRtt1 >= $ErrLvl1) || ($AvgRtt2 >= $ErrLvl2) || ($AvgRtt3 >= $ErrLvl3) || ($AvgRtt4 >= $ErrLvl4) || ($AvgRtt5 >= $ErrLvl5)) do={
:log err "Excessive ping time E-Mail is being sent";
# Send mail
/tool e-mail send to jim@<redacted> subject=$Sub1 body=("$Bo1 $IP1  $IP1n \n $Bo2 $AvgRtt1 mSec \n $Bo3 $ErrLvl1 mSec \n \n$Bo1 $IP2  $IP2n \n $Bo2 $AvgRtt2 mSec \n $Bo3 $ErrLvl2 mSec \n \n$Bo1 $IP3  $IP3n \n $Bo2 $AvgRtt3 mSec \n $Bo3 $ErrLvl3 mSec \n \n$Bo1 $IP4  $IP4n \n $Bo2 $AvgRtt4 mSec \n $Bo3 $ErrLvl4 mSec \n \n$Bo1 $IP5  $IP5n \n $Bo2 $AvgRtt5 mSec \n $Bo3 $ErrLvl5 mSec")
#  /tool e-mail send to jim@<redacted> subject=$Sub1 body=("$Bo1 $IP1  $IP1n \n $Bo2 $AvgRtt1 mSec \n $Bo3 $ErrLvl1 mSec \n \n$Bo1 $IP2  $IP2n \n $Bo2 $AvgRtt2 mSec \n $Bo3 $ErrLvl2 mSec \n \n$Bo1 $IP3  $IP3n \n $Bo2 $AvgRtt3 mSec \n $Bo3 $ErrLvl3 mSec \n \n$Bo1 $IP4  $IP4n \n $Bo2 $AvgRtt4 mSec \n $Bo3 $ErrLvl4 mSec \n \n$Bo1 $IP5  $IP5n \n $Bo2 $AvgRtt5 mSec \n $Bo3 $ErrLvl5 mSec")
}

# Send E-Mails if ping failure for test IP 1
:if ($AvgRtt1 = 0) do={
:log err "AREDN Ping failure to $IP1n E-Mail is being sent";
# Send mail
/tool e-mail send to jim@<redacted> subject=("$Sub2 $IP1n $Sub3") body=("$Bo1 $IP1  $IP1n \n $Bo2 $AvgRtt1 mSec")
#  /tool e-mail send to jim@<redacted> subject=("$Sub2 $IP1n $Sub3") body=("$Bo1 $IP1  $IP1n \n $Bo2 $AvgRtt1 mSec")
}

# Send E-Mails if ping failure for test IP 2
:if ($AvgRtt2 = 0) do={
:log err "AREDN Ping failure to $IP2n E-Mail is being sent";
# Send mail
/tool e-mail send to jim@<redacted> subject=("$Sub2 $IP2n $Sub3") body=("$Bo1 $IP2  $IP2n \n $Bo2 $AvgRtt2 mSec")
#  /tool e-mail send to jim@<redacted subject=("$Sub2 $IP2n $Sub3") body=("$Bo1 $IP2  $IP2n \n $Bo2 $AvgRtt2 mSec")
}

# Send E-Mails if ping failure for test IP 3
:if ($AvgRtt3 = 0) do={
:log err "AREDN Ping failure to $IP3n E-Mail is being sent";
# Send mail
/tool e-mail send to jim@<redacted> subject=("$Sub2 $IP3n $Sub3") body=("$Bo1 $IP3  $IP3n \n $Bo2 $AvgRtt3 mSec")
#  /tool e-mail send to jim@<redacted> subject=("$Sub2 $IP3n $Sub3") body=("$Bo1 $IP3  $IP3n \n $Bo2 $AvgRtt3 mSec")
}

# Send E-Mails if ping failure for test IP 4
:if ($AvgRtt4 = 0) do={
:log err "AREDN Ping failure to $IP4n E-Mail is being sent";
# Send mail
/tool e-mail send to jim@<redacted> subject=("$Sub2 $IP4n $Sub3") body=("$Bo1 $IP4  $IP4n \n $Bo2 $AvgRtt4 mSec")
#  /tool e-mail send to jim@<redacted> subject=("$Sub2 $IP4n $Sub3") body=("$Bo1 $IP4  $IP4n \n $Bo2 $AvgRtt4 mSec")
}

# Send E-Mails if ping failure for test IP 5
:if ($AvgRtt5 = 0) do={
:log err "AREDN Ping failure to $IP5n E-Mail is being sent";
# Send mail
/tool e-mail send to jim@<redacted> subject=("$Sub2 $IP5n $Sub3") body=("$Bo1 $IP5  $IP5n \n $Bo2 $AvgRtt5 mSec")
#  /tool e-mail send to jim@<redacted> subject=("$Sub2 $IP5n $Sub3") body=("$Bo1 $IP5  $IP5n \n $Bo2 $AvgRtt5 mSec")
}

:log info "End of AREDN ping test script"
 
User avatar
k6ccc
Forum Guru
Forum Guru
Topic Author
Posts: 1490
Joined: Fri May 13, 2016 12:01 am
Location: Glendora, CA, USA (near Los Angeles)
Contact:

Re: Script output to a file - Solved

Sun Sep 18, 2022 12:43 am

Problem solved! Script permissions. Originally all that the script had was Read and Test. Needed to add Write - Duh!
Thanks for the help Rextended
 
User avatar
k6ccc
Forum Guru
Forum Guru
Topic Author
Posts: 1490
Joined: Fri May 13, 2016 12:01 am
Location: Glendora, CA, USA (near Los Angeles)
Contact:

Re: Script output to a file

Sun Sep 18, 2022 8:59 pm

Well, almost there.
If you read the entire script posted in post #7, you can see that there are five ping tests being performed, and therefore five log entries that want to be written to the file. I have modified the script to add a timestamp to the file (which works), and the other four ping test results. During testing, I also added the timestamp to the beginning of each ping test result so I knew for sure which version I was looking at while testing).
What I have found is that no matter which of the file write sections exist (or are not REMed out), the first write to file works correctly, the second write to file works, but the script halts at that point. For testing, I have added a bunch of extra :log info lines so it's easy to see where it is halting.
And ideas?
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Script output to a file

Mon Sep 19, 2022 11:52 am

Before thinking about mails, check if this part work as expected:
:global addLogToFile do={
    :local filename "$1"
    :local fileext  ".txt" ; # can be only .txt !!!
    :local maxlen 4095
    /file
    :if ([:len [find where name="flash" and type="disk"]] = 1) do={:set filename "flash/$filename"}
    :local wkfilename "$filename$fileext"
    :if ([:len [find where name=$wkfilename]] = 0) do={print file="$wkfilename"; :delay 2s; set $wkfilename contents=""; :delay 1s}
    :local filecon [get $wkfilename contents]
    :local filelen [:len $filecon]
    :local addthis "$2\r\n"
    :local addlen  [:len $addthis]
    :if (($filelen + $addlen) > $maxlen) do={
        :set filecon ""
        :set filelen 0
        :delay 2s
    }
    :set filecon  "$filecon$addthis"
    set $wkfilename contents=$filecon
    :delay 1s
}

{ ; # start script
# do not put ; on last array element
:local arrIPs { { "IP"=10.133.246.214; "name"="W6BI-Shack-Node";                "ErrLvl"=100; "AvgRtt"=-1 };
                { "IP"=10.108.103.15;  "name"="K6PVR-VC-Camarillo-Hills-SW-5G"; "ErrLvl"=150; "AvgRtt"=-1 };
                { "IP"=10.98.158.62;   "name"="K6PVR-VC-West-SouthMtn-SE-5G";   "ErrLvl"=200; "AvgRtt"=-1 };
                { "IP"=10.234.99.239;  "name"="K6PVR-VC-Sulphur-to-Oxnard-5G";  "ErrLvl"=200; "AvgRtt"=-1 };
                { "IP"=10.162.170.94;  "name"="K6PVR-LA-Verdugo-S-Sector-5G";   "ErrLvl"=150; "AvgRtt"=-1 }
              }
:local filename "test"
:put "Start the tests, don't expect screen output in less than 14 seconds between tests."
:for index from=0 to=([:len $arrIPs] - 1) step=1 do={
    :set ($arrIPs->$index->"AvgRtt") ([/tool flood-ping ($arrIPs->$index->"IP") count=10 as-value]->"avg-rtt")
    :local IP        [:tostr ($arrIPs->$index->"IP")]
    :local name      [:tostr ($arrIPs->$index->"name")]
    :local ErrLvl    [:tostr ($arrIPs->$index->"ErrLvl")]
    :local AvgRtt    [:tostr ($arrIPs->$index->"AvgRtt")]
    :local logthis  "Average RTT to $IP ($name) is: $AvgRtt and Alarm threshold is: $ErrLvl"
    :put $logthis
    [$addLogToFile $filename $logthis]
} ; # end for
} ; # end script

Who is online

Users browsing this forum: No registered users and 17 guests