How to Calculate Time Spent Online using shell script

While every ISP offers relatively expensive unlimited-use dial-up accounts, you might not realize that many ISPs also have very low-cost monthly dial-up accounts if your usage stays below a certain number of hours of connect time in a given month. The problem is, how do you calculate your total connection time on a Unix system? Let's have a look. . . .

The Code

#!/bin/sh

# connecttime - Reports cumulative connection time for month/year entries
# found in the system log file. For simplicity, this is an awk program.

log="/var/log/system.log" # this is just /var/log/system on some machines
tempfile="/tmp/$0.$$"

trap "rm $tempfile" 0

cat << 'EOF' > $tempfile
BEGIN {
lastmonth=""; sum = 0
}
{
if ( $1 != lastmonth && lastmonth != "" ) {
if (sum > 60) { total = sum/60 " hours" }
else { total = sum " minutes" }
print lastmonth ": " total
sum=0
}
lastmonth=$1
sum += $8
}
END {
if (sum > 60) { total = sum/60 " hours" }
else { total = sum " minutes" }
print lastmonth ": " total
}
EOF

grep "Connect time" $log | awk -f $tempfile

exit 0

How It Works

On most Unixes, the system log file contains log entries from the PPP (Point-to-Point Protocol) daemon. Here's an example of a log snippet from a Mac OS X system, looking at /var/log/system.log:

$ grep pppd /var/log/system.log
Jul 12 10:10:57 localhost pppd[169]: Connection terminated.
Jul 12 10:10:57 localhost pppd[169]: Connect time 2.1 minutes.
Jul 12 10:10:57 localhost pppd[169]: Sent 15009 bytes, received 387811 bytes.
Jul 12 10:11:11 localhost pppd[169]: Serial link disconnected.
Jul 12 10:11:12 localhost pppd[169]: Exit.

There are a number of interesting statistics in this snippet, most importantly the actual connect time. Slice those connect time strings out of the log file, add them up, and you've got your cumulative connect time for the month. This script is smart enough to calculate month-by-month totals even if you don't rotate your logs (though you should; see Script #55, Rotating Log Files, for details on how to accomplish this quite easily).

This script is essentially just a big awk program that checks month values in the system.log entries to know how to aggregate connect time. When $1, the month field in the log file output, is different from lastmonth, and lastmonth isn't the empty string (which it is when the script begins analyzing the log file), the script outputs the accumulated time for the previous month and resets the accumulator, sum, to zero:

  if ( $1 != lastmonth && lastmonth != "" ) {
if (sum > 60) { total = sum/60 " hours" }
else { total = sum " minutes" }
print lastmonth ": " total
sum=0
}

The rest of the program should be straightforward reading. Indeed, awk programs can be quite clear and readable, which is one reason I like using awk for this type of task.


Handy savings tip

The dial-up account I use with Earthlink has five hours per month prepaid, so this utility helps ensure that I know when I exceed that and am going to be charged by the hour for additional connect time. It's quite helpful for minimizing those monthly dial-up bills!

Running the Script

This script has no arguments, though you might need to tweak it to ensure that it's pointing to the log file on your particular system that records ppd output messages.

The Results

You can tell I don't rotate my log files on my laptop too often:

$ connecttime
Apr: 4.065 hours
Jun: 26.71 hours
Jul: 1.96333 hours
Aug: 15.085 hours