calculate down time

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
agaswoodstock
Posts: 7
Joined: 03 Sep 2013 21:33

calculate down time

#1 Post by agaswoodstock » 03 Sep 2013 22:27

how to calculate total time of network down using bat

example 8.00 am, status: request time out
9.00 am status: reply

total time out = 1 hour

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: calculate down time

#2 Post by penpen » 04 Sep 2013 07:34

Assumed the needed information is in a textfile "netDown.txt" and has this format:

Code: Select all

8.00 am, status: request time out
9.00 am, status: reply
And assumed that the entries are the key events specifying the netdowntime,
Additionally assuming the downtime is lesser than 24 hours (as there is no date given),
and finally assuming that 12 am is midnight, this may help you:

Code: Select all

@echo off
set "diffmins="
for /F "tokens=1-3 usebackq delims=., " %%a in ("netDown.txt") do (
   if not defined diffmins (
      set /A "diffmins=0-(((%%a)%%12)*60+%%b)"
      if "%%c" == "pm"  set /A "diffmins-=720"
   ) else (
      set /A "diffmins+=(((%%a)%%12)*60+%%b)"
      if "%%c" == "pm"  set /A "diffmins+=720"
   )
)
if %diffmins% LSS 0 set "diffmins+=1440"
set /A "diffhours=diffmins/60"
set /A "diffmins=diffmins%%60"

if %diffhours% GTR 1 ( set "delta=%diffhours% hours "
) else if %diffhours% GTR 0 set "delta=%diffhours% hour "

if %diffmins% == 1 ( set "delta=%delta%%diffmins% minute"
) else set "delta=%delta%%diffmins% minutes"

echo total time out = %delta%

penpen

agaswoodstock
Posts: 7
Joined: 03 Sep 2013 21:33

Re: calculate down time

#3 Post by agaswoodstock » 04 Sep 2013 18:57

Sorry penpen about the lack of information, it is check by date actually..meaning to say daily check,
but currently there are two text file for refer.
As the main purpose was to find the internet down access more than 30 minute.
It is to make report from what time till what time (Start till End) the down time.

example:

1st file 13/08 start at >= 1700 till 14/08 =< 0800
2nd file 14/08 start at >= 0800 till 14/08 =< 1700

agaswoodstock
Posts: 7
Joined: 03 Sep 2013 21:33

Re: calculate down time

#4 Post by agaswoodstock » 04 Sep 2013 19:30

example: it check the process every minute

***ABC (server name)
30-Aug-2013 7:42:57.83

Pinging 999.999.99.77 with 32 bytes of data:
Request timed out.
Request timed out.
Request timed out.
Request timed out.

*** ABC
30-Aug-2013 16:29:34.98

Pinging 999.999.99.77 with 32 bytes of data:
Reply from 999.999.99.77: bytes=32 time=9ms TTL=248
Reply from 999.999.99.77: bytes=32 time=10ms TTL=248
Reply from 999.999.99.77: bytes=32 time=9ms TTL=248
Reply from 999.999.99.77: bytes=32 time=9ms TTL=248

so total down time = 18 hour ?? minutes ?? seconds

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: calculate down time

#5 Post by penpen » 05 Sep 2013 09:38

If you use the code from the thread http://www.dostips.com/forum/viewtopic.php?f=3&t=4846, this may help you:

Code: Select all

@echo off
setlocal enableDelayedExpansion

call :GetInternational
call :processLog "netDown.txt"
call :printDowntimes

endlocal
goto :eof


:processLog
::   %~1 log file name
::   assumed: prior the server is logged the first time, it is not down
   set "server="
   set "timestamp="
   set "reply=true"

   verify >nul
   (dir "%~1" /B /A:-D 2>nul) >nul

   if not "%errorlevel%" == "0" (
      echo No log file: "%~1".
      goto :eof
   )

   for /F "tokens=1,2* usebackq" %%a in ("%~1") do (

      if "%%~a" == "***" (
         if defined server (

            if not defined !server!.timestamp (
               set "!server!.timestamp=!timestamp!"
               set "!server!.reply=!reply!"
               set "!server!.downtime=0"
            ) else (
               for /F "tokens=* delims=" %%A in ("!server!") do (
                  set "downtime=!%%~A.downtime!"

                  call :formatTimestamp "%%~A.timestamp"
                  call :formatTimestamp "timestamp"

                  call :GetSecs !%%~A.timestamp! secondsOutStart
                  call :GetSecs !timestamp! secondsOutStop

                  set /A "downtime+=(secondsOutStop - secondsOutStart)"

                  set "%%~A.timestamp=!timestamp!"
                  set "%%~A.reply=!reply!"
                  set "%%~A.downtime=!downtime!"
               )
            )
         )

         set "server=server["%%~b"]"
         if not defined !server!.reply (
            set "!server!.timestamp="
         )

         set "timestamp="
         set "reply=false"

      ) else if not defined timestamp (
         set "timestamp="%%~a" "%%~b""
      ) else if "%%~a" == "Reply" (
         if not "!reply!" == "true" (
            set "reply=true"
         )
      ) 
   )


   if defined server (
      if not defined !server!.timestamp (
         set "!server!.reply=!reply!"
         set "!server!.timestamp=!timestamp!"
         set "!server!.downtime=0"
      ) else (
         for /F "tokens=* delims=" %%A in ("!server!") do (
            set "downtime=!%%~A.downtime!"

            call :formatTimestamp "%%~A.timestamp"
            call :formatTimestamp "timestamp"

            call :GetSecs !%%~A.timestamp! secondsOutStart
            call :GetSecs !timestamp! secondsOutStop

            set /A "downtime+=(secondsOutStop - secondsOutStart)"

            set "%%~A.timestamp=!timestamp!"
            set "%%~A.reply=!reply!"
            set "%%~A.downtime=!downtime!"
         )
      )
   )

   goto :eof


:formatTimestamp
::   %~1 variable that stores the string with timestamp to format
   setlocal enableDelayedExpansion
   set "string=!%~1!"
   set "string=!string:Jan=01!"
   set "string=!string:Feb=02!"
   set "string=!string:Mar=03!"
   set "string=!string:Apr=04!"
   set "string=!string:May=05!"
   set "string=!string:Jun=06!"
   set "string=!string:Jul=07!"
   set "string=!string:Aug=08!"
   set "string=!string:Sep=09!"
   set "string=!string:Oct=10!"
   set "string=!string:Nov=11!"
   set "string=!string:Dec=12!"
   endlocal & set "%~1=%string%"
   goto:eof


:printDowntimes
   for /F "tokens=1-4 delims=[]=" %%a in ('set server[') do (
      if "%%~a" == "server" if "%%~c" == ".downtime" (
         if defined server["%%~b"].downtime (
            set "downtime=!server["%%~b"].downtime!"
            set /A "hours=downtime/3600", "minutes=(downtime%%3600)/60", "seconds="minutes=downtime%%60"
            echo Server %%~b total down time = !hours!:!minutes!:!seconds!
         )
      )
   )
   goto :eof


rem code from http://www.dostips.com/forum/viewtopic.php?f=3&t=4846
:GetInternational
for /f "tokens=1,2*" %%a in ('reg query "HKCU\Control Panel\International"^|find "REG_SZ" ') do set "%%a=%%c"
exit /b
:GetSecs "dateIn" "timeIn" secondsOut
setlocal
set "dateIn=%~1"
for /f "tokens=2" %%i in ("%dateIn%") do set "dateIn=%%i"
for /f "tokens=1-3 delims=%sDate%" %%a in ("%dateIn%") do (
if %iDate%==0 set /a mm=100%%a%%100,dd=100%%b%%100,yy=10000%%c%%10000
if %iDate%==1 set /a dd=100%%a%%100,mm=100%%b%%100,yy=10000%%c%%10000
if %iDate%==2 set /a yy=10000%%a%%10000,mm=100%%b%%100,dd=100%%c%%100
)
for /f "tokens=1-3 delims=%sTime%%sDecimal% " %%a in ("%~2") do (
set "hh=%%a"
set "nn=%%b"
set "ss=%%c"
)
if 1%hh% lss 20 set hh=0%hh%
if "%nn:~2,1%" equ "p" if "%hh%" neq "12" (set "hh=1%hh%" &set /a hh-=88)
if "%nn:~2,1%" equ "a" if "%hh%" equ "12" set "hh=00"
if "%nn:~2,1%" geq "a" set "nn=%nn:~0,2%"
set /a hh=100%hh%%%100,nn=100%nn%%%100,ss=100%ss%%%100
set /a z=14-mm,z/=12,y=yy+4800-z,m=mm+12*z-3,j=153*m+2,j=j/5+dd+y*365+y/4-y/100+y/400-2472633,j=j*86400+hh*3600+nn*60+ss
endlocal &set "%~3=%j%"
exit /b
Edit: I have bugfixed the code above, it should work now. You may have to change the procedure :formatTimestamp if the system time/date format differs from that in the logfile.

In addition, if the whole downtime is the only information you wanted to know, you may log per server in such a way:

Code: Select all

@echo off
call :pinglog "%date% %time%" "serverlogs\ABC.2013.09.05.txt" "999.999.99.77"
call :pinglog "%date% %time%" "serverlogs\Google.2013.09.05.txt" "www.google.de"
:: ...

:: i think i even would not use a date then, and would backup them once per month, or so
rem call :pinglog "%date% %time%" "serverlogs\ABC.txt" "999.999.99.77"
rem call :pinglog "%date% %time%" "serverlogs\Google.txt" "www.google.de"
rem :: ...

goto :eof


:pinglog
::   %~1 timestamp
::   %~2 logfile
::   %~3 to ping
   (
      ping "%~3"
   ) && (
      (echo Server ABC available at %~1) >> "%~2"
   ) || (
      (echo Server ABC unavailable at %~1) >> "%~2"
   )
   goto :eof
I think i would even

penpen
Edit: Bugfixed the first code above, it should work now, see the note below the code.
Last edited by penpen on 09 Sep 2013 10:11, edited 1 time in total.

agaswoodstock
Posts: 7
Joined: 03 Sep 2013 21:33

Re: calculate down time

#6 Post by agaswoodstock » 05 Sep 2013 19:18

@echo off
call :pinglog "%date% %time%" "serverlogs\ABC.2013.09.05.txt" "999.999.99.77"
call :pinglog "%date% %time%" "serverlogs\Google.2013.09.05.txt" "www.google.de"
:: ...

:: i think i even would not use a date then, and would backup them once per month, or so
rem call :pinglog "%date% %time%" "serverlogs\ABC.txt" "999.999.99.77"
rem call :pinglog "%date% %time%" "serverlogs\Google.txt" "www.google.de"
rem :: ...

goto :eof


:pinglog
:: %~1 timestamp
:: %~2 logfile
:: %~3 to ping
(
ping "%~3"
) && (
(echo Server ABC available at %~1) >> "%~2"
) || (
(echo Server ABC unavailable at %~1) >> "%~2"
)
goto :eof

Had done this part and extract the data into text file. So from this file using the data to calculate if there are downtime.

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: calculate down time

#7 Post by penpen » 06 Sep 2013 09:03

If you use the code from the thread viewtopic.php?f=3&t=4846, this may help you:

Code: Select all

@echo off
cls
setlocal

call :GetInternational

call :processServerLog "serverlogs\ABC.2013.09.05.txt"
call :processServerLog "serverlogs\Google.2013.09.05.txt"

endlocal
goto :eof


:processServerLog
::   %~1 server log filename
   if not exist "%~1" echo Server log "%~1" is not available.& goto :eof

   setlocal enableDelayedExpansion
   set "input="
   set /P "input=" < "%~1"

   if "%input:~-36,1%" == "n" (
      set "server=!input:~7,-38!"
      set "state=!input:~-37,-26!"
   ) else (
      set "server=!input:~7,-36!"
      set "state=!input:~-35,-26!"
   )
   set "timestamp=!input:~-22!"
   set /A "downtime=0"

   for /F "tokens=* usebackq delims=" %%a in ("%~1") do (
      set "line=%%~a"
      set "line=!line:Server %server% =!"
      for /F "tokens=1-4 delims= " %%A in ("!line!") do (
         if not "%%~A" == "!state!" (
            if "!state!" == "unavailable" (
               call :GetSecs "!timestamp: =" "!" secondsOutStart
               call :GetSecs "%%~C" "%%~D" secondsOutStop
               set /A "downtime+=(secondsOutStop - secondsOutStart)"
            )
            set "state=%%~A"
            set "timestamp=%%~C %%~D"
         )
      )
   )

   for /F "tokens=1-4 delims= " %%A in ("!line!") do (
      if "!state!" == "unavailable" (
         call :GetSecs "!timestamp: =" "!" secondsOutStart
         call :GetSecs "%%~C" "%%~D" secondsOutStop
         set /A "downtime+=(secondsOutStop - secondsOutStart)"
      )
   )

   set /A "hours=downtime/3600", "minutes=(downtime%%3600)/60", "seconds=downtime%%60"
   if %hours% LSS 10 set "hours=0%hours%"
   if %minutes% LSS 10 set "minutes=0%minutes%"
   if %seconds% LSS 10 set "seconds=0%seconds%"

   echo Server %server% total downtime in %~1: %hours%:%minutes%:%seconds% hour(s)
   goto :eof


rem code from http://www.dostips.com/forum/viewtopic.php?f=3&t=4846
:GetInternational
for /f "tokens=1,2*" %%a in ('reg query "HKCU\Control Panel\International"^|find "REG_SZ" ') do set "%%a=%%c"
exit /b
:GetSecs "dateIn" "timeIn" secondsOut
setlocal
set "dateIn=%~1"
for /f "tokens=2" %%i in ("%dateIn%") do set "dateIn=%%i"
for /f "tokens=1-3 delims=%sDate%" %%a in ("%dateIn%") do (
if %iDate%==0 set /a mm=100%%a%%100,dd=100%%b%%100,yy=10000%%c%%10000
if %iDate%==1 set /a dd=100%%a%%100,mm=100%%b%%100,yy=10000%%c%%10000
if %iDate%==2 set /a yy=10000%%a%%10000,mm=100%%b%%100,dd=100%%c%%100
)
for /f "tokens=1-3 delims=%sTime%%sDecimal% " %%a in ("%~2") do (
set "hh=%%a"
set "nn=%%b"
set "ss=%%c"
)
if 1%hh% lss 20 set hh=0%hh%
if "%nn:~2,1%" equ "p" if "%hh%" neq "12" (set "hh=1%hh%" &set /a hh-=88)
if "%nn:~2,1%" equ "a" if "%hh%" equ "12" set "hh=00"
if "%nn:~2,1%" geq "a" set "nn=%nn:~0,2%"
set /a hh=100%hh%%%100,nn=100%nn%%%100,ss=100%ss%%%100
set /a z=14-mm,z/=12,y=yy+4800-z,m=mm+12*z-3,j=153*m+2,j=j/5+dd+y*365+y/4-y/100+y/400-2472633,j=j*86400+hh*3600+nn*60+ss
endlocal &set "%~3=%j%"
exit /b
Currently untested, the algorithm should be correct, but there may be flaws in this code.

penpen

agaswoodstock
Posts: 7
Joined: 03 Sep 2013 21:33

Re: calculate down time

#8 Post by agaswoodstock » 08 Sep 2013 18:27

seems it cannot calculate the downtime as in my text file there are several server (4 server) data included.

agaswoodstock
Posts: 7
Joined: 03 Sep 2013 21:33

Re: calculate down time

#9 Post by agaswoodstock » 08 Sep 2013 21:45

*** ABC
30-Aug-2013 8:11:16.67

Pinging 999.999.99.77 with 32 bytes of data:
Request timed out.
Request timed out.
Request timed out.
Request timed out.

Ping statistics for 999.999.99.77:
Packets: Sent = 4, Received = 0, Lost = 4 (100% loss),

Pinging 999.999.99.78 with 32 bytes of data:
Request timed out.
Request timed out.
Request timed out.
Request timed out.

Ping statistics for 999.999.99.78:
Packets: Sent = 4, Received = 0, Lost = 4 (100% loss),

Pinging 999.888.2.1 with 32 bytes of data:
Reply from 999.999.200.86: TTL expired in transit.
Reply from 999.999.200.86: TTL expired in transit.
Reply from 999.999.200.86: TTL expired in transit.
Reply from 999.999.200.86: TTL expired in transit.

Ping statistics for 999.888.2.1:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),

UNTIL

ABC
30-Aug-2013 16:31:31.35

Pinging 999.999.99.77 with 32 bytes of data:
Reply from 999.999.99.77: bytes=32 time=9ms TTL=248
Reply from 999.999.99.77: bytes=32 time=10ms TTL=248
Reply from 999.999.99.77: bytes=32 time=9ms TTL=248
Reply from 999.999.99.77: bytes=32 time=9ms TTL=248

Ping statistics for 999.999.99.77:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 9ms, Maximum = 10ms, Average = 9ms

Pinging 999.999.99.78 with 32 bytes of data:
Reply from 999.999.99.78: bytes=32 time=10ms TTL=247
Reply from 999.999.99.78: bytes=32 time=10ms TTL=247
Reply from 999.999.99.78: bytes=32 time=12ms TTL=247
Reply from 999.999.99.78: bytes=32 time=10ms TTL=247

Ping statistics for 999.999.99.78:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 10ms, Maximum = 12ms, Average = 10ms

Pinging 999.888.2.1 with 32 bytes of data:
Reply from 999.888.2.1: bytes=32 time=11ms TTL=247
Reply from 999.888.2.1: bytes=32 time=12ms TTL=247
Reply from 999.888.2.1: bytes=32 time=10ms TTL=247
Reply from 999.888.2.1: bytes=32 time=10ms TTL=247

Ping statistics for 999.888.2.1:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 10ms, Maximum = 12ms, Average = 10ms

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: calculate down time

#10 Post by penpen » 09 Sep 2013 10:28

agaswoodstock wrote:@echo off
call :pinglog "%date% %time%" "serverlogs\ABC.2013.09.05.txt" "999.999.99.77"
call :pinglog "%date% %time%" "serverlogs\Google.2013.09.05.txt" "www.google.de"
:: ...

:: i think i even would not use a date then, and would backup them once per month, or so
rem call :pinglog "%date% %time%" "serverlogs\ABC.txt" "999.999.99.77"
rem call :pinglog "%date% %time%" "serverlogs\Google.txt" "www.google.de"
rem :: ...

goto :eof


:pinglog
:: %~1 timestamp
:: %~2 logfile
:: %~3 to ping
(
ping "%~3"
) && (
(echo Server ABC available at %~1) >> "%~2"
) || (
(echo Server ABC unavailable at %~1) >> "%~2"
)
goto :eof

Had done this part and extract the data into text file. So from this file using the data to calculate if there are downtime.
I misunderstood your post and thought you are using then this code, so i've posted a batch script,
that work on that format, too. It has the advantage that all servers are logged in their own logfile,
with a minimum of readable information. This version should work, so i haven't changed it.

But if you are still using the first given format of the logfile, then my second posted batch script should do it.
I've bugfixed it, it should work now. Maybe you have to slightly modify the procedure :formatTimestamp
to meet your system settings.

If your logfile format differs from the above, please post it.
I'm not sure if your last post contains a valid logfile, as its format is dofferent from the above.
Post the full format: all special cases should be contained.

penpen

Post Reply