Skip to main content

How to Log Ping Results Over Time in Batch Script

Monitoring network stability isn't about a single snapshot; it's about seeing "trends." If your internet connection drops for 5 seconds every hour, a standard one-time ping won't catch it. By creating a Batch script that pings a target continuously and logs the timestamped results to a file, you can build a historical record of your network's uptime. This data is invaluable for proving intermittent connectivity issues to an ISP or identifying exactly when a remote server went offline.

This guide will explain how to create a persistent ping logger.

Method 1: The "Continuous Monitor" Script

This script keeps running in the background, logging every success or failure to a CSV file.

@echo off
setlocal enabledelayedexpansion

:: -----------------------------
:: Configurable parameters
:: -----------------------------
set "Host=8.8.8.8"
set "LogFile=%USERPROFILE%\network_uptime.csv"
set "Interval=10"

echo [MONITOR] Watching %Host%...
echo Logging to: %LogFile%
echo Interval: %Interval% seconds
echo Press CTRL+C to stop.
echo.

:: -----------------------------
:: Create header if file is new
:: -----------------------------
if not exist "%LogFile%" (
echo Date,Time,Target,Status,Latency >> "%LogFile%"
)

:Loop
:: -----------------------------
:: Reset variables for each iteration
:: -----------------------------
set "stat=FAIL"
set "latency=N/A"

:: -----------------------------
:: Perform a single ping
:: -----------------------------
for /f "delims=" %%L in ('ping -n 1 -w 1000 %Host% 2^>nul ^| find "TTL="') do (
set "stat=OK"
set "line=%%L"

:: Extract latency (supports both "time=12ms" and "time<1ms")
for /f "tokens=1,2 delims==<ms " %%a in ("!line:*time=!") do (
if "%%a"=="time" (
set "latency=%%b"
) else (
set "latency=%%a"
)
)
)

:: -----------------------------
:: Write to the log
:: -----------------------------
echo !date!,!time!,%Host%,!stat!,!latency! >> "%LogFile%"

:: -----------------------------
:: Display live output
:: -----------------------------
if "!stat!"=="OK" (
echo [!time!] %Host% - OK (!latency! ms)
) else (
echo [!time!] %Host% - FAIL
)

:: -----------------------------
:: Wait before next check
:: -----------------------------
timeout /t %Interval% >nul
goto :Loop
Why enabledelayedexpansion?

Variables like stat and latency are set inside a code block and then used in the same iteration. Without delayed expansion, %stat% would show whatever value it had before the loop started, meaning every line in your log would show the same result.

Method 2: Log ONLY Failures

If you are monitoring a stable server, logging "OK" every 10 seconds creates a massive, useless file. This method only records when the connection is lost and when it recovers.

@echo off
setlocal enabledelayedexpansion

:: -----------------------------
:: Configurable parameters
:: -----------------------------
set "Target=192.168.1.1"
set "LogFile=%USERPROFILE%\outage_log.txt"
set "Interval=5"
set "WasDown=0"

echo [MONITOR] Watching %Target% for outages only...
echo Log: %LogFile%
echo Press CTRL+C to stop.
echo.

:Loop
:: -----------------------------
:: Ping once with 1-second timeout
:: -----------------------------
ping -n 1 -w 1000 %Target% >nul 2>&1

:: -----------------------------
:: Check if ping failed
:: -----------------------------
if errorlevel 1 (
:: Connection failed
if !WasDown! equ 0 (
:: First failure - log the start of outage
echo [!date! !time:~0,8!] OUTAGE START - Connection lost to %Target% >> "%LogFile%"
echo [ALERT] !time:~0,8! - Connection lost to %Target%!
set "WasDown=1"
)
) else (
:: Connection succeeded
if !WasDown! equ 1 (
:: Was previously down - log recovery
echo [!date! !time:~0,8!] RECOVERED - Connection restored to %Target% >> "%LogFile%"
echo [OK] !time:~0,8! - Connection restored to %Target%.
set "WasDown=0"
)
)

:: -----------------------------
:: Wait before next check
:: -----------------------------
timeout /t %Interval% >nul
goto :Loop

Method 3: Visual Graphing (Text-Based)

A simple screen-based monitor that shows a visual indicator for each ping result. Each character represents one sample.

@echo off
setlocal enabledelayedexpansion

set "Host=8.8.8.8"
set "Interval=1"
set "Count=0"

echo [MONITOR] Visual ping graph for %Host%
echo [.] = OK [X] = FAIL
echo Press CTRL+C to stop.
echo.

:: Print timestamp at the start of each line
<nul set /p "=[!time!] "

:Loop
ping -n 1 -w 500 %Host% >nul 2>&1

if !errorlevel! equ 0 (
<nul set /p "=."
) else (
<nul set /p "=X"
)

set /a Count+=1

:: Start a new line every 60 samples for readability
if !Count! geq 60 (
echo.
set "Count=0"
<nul set /p "=[!time!] "
)

timeout /t %Interval% >nul
goto :Loop
Why add line breaks?

Without wrapping, the dots and X's form a single line that scrolls off-screen and becomes unreadable. Wrapping every 60 characters (representing 60 seconds at 1-second intervals) creates a readable grid where each row is one minute of monitoring.

Method 4: Multi-Target Monitor (Gateway + Internet)

To truly diagnose where a problem lies, ping both your local gateway and a public address simultaneously. This tells you whether the issue is your local network (Wi-Fi/Ethernet) or your ISP.

@echo off
setlocal enabledelayedexpansion

set "Gateway=192.168.1.1"
set "Internet=8.8.8.8"
set "LogFile=%USERPROFILE%\dual_monitor.csv"
set "Interval=10"

echo [MONITOR] Dual-target network monitor
echo Gateway: %Gateway%
echo Internet: %Internet%
echo Log: %LogFile%
echo Press CTRL+C to stop.
echo.

:: CSV header
if not exist "%LogFile%" echo Date,Time,Gateway,Internet,Diagnosis >> "%LogFile%"

:Loop
set "gw_status=FAIL"
set "inet_status=FAIL"
set "diagnosis=UNKNOWN"

:: Ping gateway
ping -n 1 -w 1000 %Gateway% >nul 2>&1
if !errorlevel! equ 0 set "gw_status=OK"

:: Ping internet
ping -n 1 -w 1000 %Internet% >nul 2>&1
if !errorlevel! equ 0 set "inet_status=OK"

:: Determine diagnosis
if "!gw_status!"=="OK" if "!inet_status!"=="OK" set "diagnosis=ALL_CLEAR"
if "!gw_status!"=="OK" if "!inet_status!"=="FAIL" set "diagnosis=ISP_ISSUE"
if "!gw_status!"=="FAIL" if "!inet_status!"=="FAIL" set "diagnosis=LOCAL_NETWORK_DOWN"
if "!gw_status!"=="FAIL" if "!inet_status!"=="OK" set "diagnosis=GATEWAY_ISSUE"

:: Log and display
echo !date!,!time!,!gw_status!,!inet_status!,!diagnosis! >> "%LogFile%"

if "!diagnosis!"=="ALL_CLEAR" (
echo [!time!] Gateway: OK Internet: OK - All clear
) else (
echo [!time!] Gateway: !gw_status! Internet: !inet_status! - !diagnosis!
)

timeout /t %Interval% >nul
goto :Loop

How to read the diagnosis:

  • ALL_CLEAR: Both targets respond. Network is healthy.
  • ISP_ISSUE: Gateway responds but internet doesn't. Problem is your ISP or upstream.
  • LOCAL_NETWORK_DOWN: Neither responds. Your local connection (Wi-Fi/Ethernet/cable) is the problem.
  • GATEWAY_ISSUE: Rare. Internet works but gateway doesn't. Possible routing anomaly.

Method 5: Daily Log Rotation

For long-term monitoring, automatically create a new log file each day to prevent any single file from growing too large.

@echo off
setlocal enabledelayedexpansion

set "Host=8.8.8.8"
set "LogDir=%USERPROFILE%\PingLogs"
set "Interval=30"
set "CurrentDay="

:: Create log directory
if not exist "%LogDir%" mkdir "%LogDir%"

echo [MONITOR] Long-term ping logger with daily rotation
echo Target: %Host%
echo Log Dir: %LogDir%
echo Interval: %Interval% seconds
echo Press CTRL+C to stop.
echo.

:Loop
:: Get current date (YYYYMMDD) reliably
for /f "skip=1 tokens=1" %%D in ('wmic os get localdatetime') do (
if not defined DateTime set "DateTime=%%D"
)
set "Today=!DateTime:~0,8!"

:: Check for new day
if "!Today!" neq "!CurrentDay!" (
set "CurrentDay=!Today!"
:: Remove any invalid characters just in case
set "SafeLogFileName=!Today!"
set "LogFile=%LogDir%\ping_!SafeLogFileName!.csv"
if not exist "!LogFile!" (
echo Date,Time,Target,Status,Latency(ms^) >> "!LogFile!"
echo [INFO] New log file: !LogFile!
)
)

:: Ping target
set "stat=FAIL"
set "latency=N/A"
for /f "tokens=1,2,3,4,5 delims==<ms " %%A in ('ping -n 1 -w 1000 %Host% ^| find "TTL="') do (
set "stat=OK"
set "latency=%%E"
)

:: Log to file and console
echo !date!,!time!,%Host%,!stat!,!latency! >> "!LogFile!"
echo !date! !time! - %Host% - !stat! - !latency! ms

:: Wait and repeat
timeout /t %Interval% >nul
goto :Loop

How to Avoid Common Errors

Wrong Way: Logging to the Screen Only

If your script doesn't write to a file, you won't be able to review the results after the outage happens.

Correct Way: Always use the >> operator to append results to a text or CSV file. This ensures the data is persistent even if the script window is closed.

Wrong Way: Using %errorlevel% Without Delayed Expansion

Inside a goto :Loop construct, variables set in one iteration need delayed expansion to be read correctly in the same code block. Without it, %stat% and %errorlevel% will show stale values from before the loop began.

Correct Way: Enable delayed expansion and use !variable! syntax:

setlocal enabledelayedexpansion
:: ...
if !errorlevel! equ 0 ( set "stat=OK" ) else ( set "stat=FAIL" )
echo !stat!

Wrong Way: Logging Every Failure Repeatedly

If your target goes down for 10 minutes with a 5-second interval, logging every failure repeatedly would log 120 identical "Connection lost" lines, making the log noisy and hard to analyze.

Correct Way: Track state transitions. Log only when the connection changes from UP to DOWN (outage start) and from DOWN to UP (recovery):

if !WasDown! equ 0 (
echo OUTAGE START >> log.txt
set "WasDown=1"
)

Problem: Large Log Files

A script that pings every second will generate a 10MB+ text file in just a few days.

Solution: Use a reasonable interval (10–30 seconds) for long-term monitoring, or implement daily log rotation as shown in Method 5. This creates manageable files like ping_20250101.csv, ping_20250102.csv, etc.

Problem: Latency Parsing Inconsistency

The ping output format varies between Windows versions and locales. Some show time=12ms, others show time<1ms, and non-English systems may use different keywords entirely.

Solution: The find "TTL=" approach is more universal than parsing time= because TTL appears consistently in IPv4 replies across locales. For precise latency capture, validate your parsing against your specific Windows version.

Best Practices and Rules

1. Identify the Gateway

Don't just ping google.com. To truly troubleshoot an outage, ping your local router and a public address at the same time. Method 4 implements this dual-target approach, giving you instant diagnosis of where the problem lies.

2. CSV Formatting

Always include a header in your first line. This allows you to open the file in Excel or Google Sheets and create professional uptime graphs:

Date,Time,Target,Status,Latency

3. Handle Timeouts

Use the -w 1000 (wait 1 second) flag. If you don't set a timeout, a failed ping might wait for 4+ seconds, throwing off the timing of your interval-based logging.

4. Log File Location

Avoid using %CD% for log files because it depends on where the script is launched from and may point to a system directory or read-only location. Use %USERPROFILE% or a dedicated log directory for reliable write access.

5. Daily Log Rotation

For monitoring that runs for days or weeks, create a new log file each day. Method 5 demonstrates automatic rotation using date-stamped filenames.

6. Always Use setlocal / endlocal

Without setlocal, every variable your script creates persists in the parent shell session, causing potential conflicts when running multiple scripts in sequence.

Conclusions

Logging ping results over time transforms a simple networking tool into a powerful data-gathering engine. By moving from manual checks to an automated, timestamped history, you gain the evidence needed to diagnose complex, intermittent network failures. This professional monitoring approach ensures that you never miss an outage and always have the data required to maintain a highly available network environment.