1

I'm keeping track of data transfers on my network interfaces but want them to be reset to 0 on the 1st of each month.

When I try echo 0 to the rx_bytes or tx_bytes files I get this:

bash: /sys/class/net/wlan0/statistics/rx_bytes: Permission denied

I run the command as root.

I also tried copying (overwriting) in a file:

cp: cannot create regular file:‘/sys/class/net/wlan0/statistics/rx_bytes’: Permission denied

I also tried changing permissions to 777 (default is 444)

Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232
Jim
  • 240

3 Answers3

2

The usual way would be to save the value at the change of month, and calculate differences against that value. That way you could easily, say count values over more than a single interval, and also make it possible to use a single data source with multiple independent consumers, without them stepping on each other's numbers. Besides, zeroing the counter would require a way to atomically read and clear it, otherwise you would lose the count for the traffic between reading the counter and zeroing it. Stuff like SNMP will also usually give you a read-only counter.

So I don't think you really want to clear the counter.

Programs designed for graphing network statistics can usually deal with the wraparound issue (e.g. rrdtool has COUNTER mode). Though you would still want to use 64-bit counters, since I remember getting problems with 32-bit overflow with a gigabit interface and a 5 minute polling rate.

ilkkachu
  • 138,973
  • Thanks for the feedback. I've written a cool little script to handle the 32-bit overflow issue here: http://unix.stackexchange.com/questions/3446/shomehow-the-rx-tx-counters-on-the-interface-resets/294384 I'm using both COUNTER and GAUGE in RRDTool for different graphs on the traffic. I'm not overly concerned about the data lost between the last 23:59 of month n and the 1st 00:00 of month n+1... but I may factor in some code to handle the missing bytes when zeroing out the values. However, if there's a way to do this within rrdtool itself, I'm all ears (eyes) :-) – Jim Jul 07 '16 at 14:27
  • @Jim, IIRC, rrdtool would save the amount of traffic transferred during a time slot (sample period), so you might be able to ask it to sum the values over a certain time if you want the e.g. total transfered during a certain month. (But that really has nothing to do with how Linux exports the traffic statistics.) – ilkkachu Jul 08 '16 at 11:43
  • Thanks @ikkachu, I love RRDTool, but configuring it to work is a lot of work (for me). I'd rather feed it numbers that I know are correct (pre-configured) and display them like that. Rather than feeding it raw data and spend a few days (or weeks) figuring out how to display it the way I want. – Jim Jul 09 '16 at 12:53
1

The file manipulation operations you are performing might not be working, because files in /proc are not really true files in the common sense, but virtual files that provide a 'window'/interface to variables in the linux kernel.

The only way to reset the interface counters is by unloading and loading again the corresponding interface kernel module.

To find out the kernel module of eth0:

$sudo ethtool -i eth0 | grep driver
driver: vmxnet3

Then unload and load the kernel module with:

sudo -- sh -c  'ifdown eth0 ; modprobe -r vmxnet3; modprobe vmxnet3 ; ifup eth0'

if you do not use the above sudo syntax, I do recommend creating a script with the above commands, or otherwise you can, in certain conditions, lose control of the remote linux machine.

Be aware that if you have processes monitoring eth0, for instance watchdogs, you will have to stop them too before unloading the module.

Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232
  • 1
    Wow, that's really interesting, thanks! Could you give a bit more info on that 2nd command? I use root access by default, so sudo would not be needed, but I've never seen/used a command that starts with --. Also, is there a way to find out if there are any processes monitoring the network interfaces? I'm not running watchdogs (that I'm aware of), but I am running webmin. – Jim Jul 07 '16 at 12:31
  • 1
    You only have to worry about possibly monit or watchdogs that try to restart services/the server if the interface fails (automatic recovery of services). Since you do not have them, no worries. as for the -- it is a special argument to getopts, marking the end of options. I do not recommend working all the time as root, and moreover, if you do not use the above sudo syntax, I do recommend creating a script with the above commands, or otherwise you can in certain conditions, lose control of the terminal. https://www.mkssoftware.com/docs/man1/getopts.1.asp – Rui F Ribeiro Jul 07 '16 at 12:36
  • Great! The PC is a headless server (Raspberry Pi), so I don't really need to access it as a non-root user for the most part. I'm drawing graphs with regards to data usage on a monthly basis and would like to zero out the graph (see: http://unix.stackexchange.com/questions/3446/shomehow-the-rx-tx-counters-on-the-interface-resets/294384#294384) at the beginning of each month. Your code above will be run in a script with fcron with root permission. Would I need to install any other packages (what is modprobe?) – Jim Jul 07 '16 at 12:43
  • 1
    Tested in my raspberry, for some odd reason raspbian has only ethtool in the path for root, changed the answer. If you use a SNMP-based package for instance to graph your usage, you might not to do that. Mind you that after 4GB of usage, the value wraps around to 0 (i.e. it does not grow ad eternum) – Rui F Ribeiro Jul 07 '16 at 12:46
  • Got the wrap-around sorted (see link above) :-D – Jim Jul 07 '16 at 12:47
  • Do you know rpimonitor? – Rui F Ribeiro Jul 07 '16 at 12:49
  • So I'm trying to run those commands separately now and getting this: modprobe: FATAL: Module rt18192cu not found. Here's the result from ethtool -i wlan0: driver: rtl8192cu version: firmware-version: bus-info: 1-1.2:1.0 supports-statistics: no supports-test: no supports-eeprom-access: no supports-register-dump: no supports-priv-flags: no – Jim Jul 20 '16 at 14:59
  • 1
    Would rebooting the device (and flushing the saved data values also work?) – Jim Jul 20 '16 at 15:00
  • Obviously, however the practice of reseting the counters is already questionable, and rebooting even more so. I usually only reboot after major security problems surface in the current operating kernel. – Rui F Ribeiro Jul 20 '16 at 16:03
  • Agreed on both counts, however, 1 reboot a month (while still detestable) should be manageable. I am working on updating the script I put up to see if i can get around resetting or rebooting. If I manage to accomplish it I'll put up the code as an answer. – Jim Jul 21 '16 at 07:19
  • You certainly can get around it...if n2 < n then t += n2 else t += ( n2 - n ) – Rui F Ribeiro Jul 21 '16 at 09:51
  • At the base level, that's kinda what I used to get around the 4Gb limitation. However, the problem here is getting the graphs to start again from '0' at 00:00:00 on the 1st of every month. And to do that, the actual rx_bytes and tx_bytes need to be ignored or more specifically a "Baseline" value to be added while also factoring in the wrap-around to make sure that no bugs slip though. i.e. if max_value=40, and new month comes around at "39", then base line is 39, wraparound happens at 40 and now it's at 1 again, but the baseline of 39 needs to be remembered even after multiple wraparounds. – Jim Jul 21 '16 at 11:12
0

Ok, So in my case, The only way to force the counters to reset would be to reboot the server. Not ideal, but this is the case.

As mentioned by ilkkachu, probably the best way to do this would be to save the value at the beginning of the new month and then calculate from that point forward. However, I couldn't wrap my head around an elegant way to accomplish this with the script I currently have set up.

So in lieu of that, I've gone for the reboot-my-server-once-a-month scenario. I've included a snippet of the code that I used below:

# CHECK FOR THE OLD_MONTH FILE
if [ ! -e /usr/local/bin/system/old_month ]; then
        # CREATE IT IF IT DOESN'T EXIST WITH THIS MONTHS DATE
        echo `date` | awk '{print $2,$6}' > /usr/local/bin/system/old_month
fi

# CREATE A NEW FILE EVERY TIME THIS IS RUN WITH THIS MONTHS DATE
echo `date` | awk '{print $2,$6}' > /usr/local/bin/system/this_month

# CHECK IF OLD_MONTH AND THIS_MONTH ARE NOT THE SAME
if ! cmp /usr/local/bin/system/this_month /usr/local/bin/system/old_month > /dev/null 2>&1 ;
then
        # RUN YOUR RELEVANT CODE HERE #
        echo `date` | awk '{print $2,$6}' > /usr/local/bin/system/old_month     # UPDATE THE VALUE IN OLD_MONTH SO THAT THEY WILL MATCH NEXT TIME
        reboot now                                                              # REBOOT
        exit 0                                                                  # AND EXIT THIS SCRIPT
fi
Jim
  • 240