Per-vhost bandwidth measuring
What? mod_bw_counter?
This lighttpd module measures incoming and outgoing bandwidth used by each vhost and puts it into MySQL table.
Who's responsible?
This is written by GDR! as a part of his job at CloudAccess.net.
How do I compile it?
- Grab lighttpd sources
- Put mod_bw_counter.c in src/ subdirectory of lighttpd source tree
- Paste the following into src/Makefile.am:
lib_LTLIBRARIES += mod_bw_counter.la mod_bw_counter_la_SOURCES = mod_bw_counter.c mod_bw_counter_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined mod_bw_counter_la_LIBADD = $(MYSQL_LIBS) $(common_libadd)
- Type
./autogen.sh
, then./configure
andmake
How do I configure it?
First of all, add the following line to server.modules
section in your lighttpd.conf
:
"mod_bw_counter",
Then, the following server-wide options apply:
bw_counter.mysql_server
- MySQL server to connect tobw_counter.mysql_db
- MySQL database namebw_counter.mysql_table
- MySQL table namebw_counter.mysql_user
- MySQL user namebw_counter.mysql_password
- MySQL passwordbw_counter.report_interval
- the minimum number of seconds plugin will report usage to database.
The maximum value internal counters can handle is 4294967295 bytes, so in heavy traffic conditions make sure to set report_interval so that this value isn't exceeded for any vhost.
How do I set up MySQL for this?
It's the most secure to create a separate MySQL user for bandiwdth logging, with access to only one table. The table is defined as following:
CREATE TABLE IF NOT EXISTS `bandwidth` ( `vhost` varchar(255) NOT NULL, `day` date NOT NULL, `in` bigint(64) NOT NULL, `out` bigint(64) NOT NULL, PRIMARY KEY (`vhost`,`day`) )
The usage report is broken down per-day. Other schemes require light hacking of pluging source.
Notice the bigint(64) type - this may cause problems with languages with poor 64-bit support, like PHP. You may to cast it to float or divide number of bytes by (1024*1024*1024) on a SQL query level, as a poor substitute for having a real programming language..
How does it work?
This plugin handles two internal events in lighttpd: connection close and connection reset. It also maintains an two associative arrays: hostname → in_bytes and hostname → out_bytes. On each connection close or reset, it takes number of bytes read and written in this connection, and adds it to counter for the hostname this connection handles.
Additionally, every report_interval
seconds, it sends the collected data to MySQL database. The queries have a form of:
`in` = `in` + bytes_read
and after each successful insert/update, the according counters are set to 0.
Why does it not work?
Look at lighttpd error log.