Last updated 2008/03/18
Return to the Suffield Academy Network Documentation Homepage
A printable version of this document is also available.
Suffield Academy has its own PBX phone switch, and allows users to make direct local and long-distance calls from the phones on campus. We used to have a 3rd-party vendor who tracked and billed our long distance, but we stopped using them after we cancelled student long-distance accounts (the students were primarily using their cell phones).
In order to keep track of the basic call activity on our lines, we wrote a small script to parse the SMDR (Station Messaging Detail Record) data that is output directly by our phone switch. It reads the SMDR data, parses it, and logs it to a SQL database for later analysis. Using simple SQL queries, we can run basic reports for total and per-number usage.
Our phone switch is a NEC NEAX 2400. The SMDR format is specific to this model of switch, but the general discussion of how it works should be roughly the same across other equipment.
Note: in 2008 Hauke Luckow e-mailed to contribute a patched version of this script that works with the Panasonic KX-TA616. If you'd like to download his patched version, please visit the luckow directory.
Also, Hauke informed us of another GPL program that logs SMDR data and allows searching via a web interface:
If you're looking for a better GUI, or support of a model other than those listed above, that program may be a good fit for you.
To log SMDR data from a phone switch, the following broad steps must be taken:
Once set up, the basic flow of information works like this:
Once in the database, administrators can run reports on the data using regular SQL queries.
Our phone switch logs SMDR data over a slow (9600 baud) serial link. We do not experience a heavy call volume, so the amount of data is very small. Additionally, the phone switch automatically buffers the data on the serial ports, so in the unlikely event of the processing system being unable to keep up with the data flow, it will be buffered until the system can catch up.
Because the amount and rate of data is so small, almost any machine will do for processing the data. We run 3 Intel Atom servers as our processing machines, though almost any machine will do (our previous machines included 200MHz MIPS servers and Intel 486-class Windows PCs).
The script is designed to work with multiple processors in simultaneous operation. You can configure the phone switch to emit SMDR data on multiple serial ports, and then connect the ports to different machines for redundancy. The script will properly detect records that have already been inserted by another processor, and not duplicate the records. To help determine if the processors are running, a separate table tracks the records inserted by each processor so that you can ensure that all the machines are working properly.
The processing script is written in Perl, so you must have Perl installed on the processing machine. Additionally several common modules are required by the script:
All of the modules, if not already built in to your system, are freely available on CPAN. On the "Lenny" flavor of Debian Linux, all modules are already installed, or available directly via APT (libdbd-pg-perl and libdevice-serialport-perl are the only two packages you need to install on top of a "standard system" Debian build).
This section gives a (very) brief overview on setting up the processing systems, along with an even briefer overview of the code structure. Note that the script itself is well-commented, and should be easily changed by someone with a basic understanding of Perl.
We have included a SQL file which defines the basic tables. It's written for the PostgreSQL database engine, though it could be made to work with any SQL-compliant database with very simple modifications. You can download the SQL here:
One table tracks all of the call data, and the other tracks the processing machines that inserted each record. To prevent duplicate records in a multi-processor environment, a UNIQUE constraint is placed on the call table. In the event that a processor attempts to insert a duplicate record, it will detect the duplicate on insertion and instead merely log that it too would have inserted a particular record. This information is stored in the "loggers" table, where the ID of each call record is listed with all the processors that processed the record.
First, download the actual script:
We suggest placing the script in /usr/local/sbin
, though it can go
anywhere. If you do change its location, be sure to update the init
script below.
Download and install the package dependencies for the script.
Modify the script to include the correct serial port and database connection information.
Next, create the file /etc/nec_smdr_postgres_password
, and put the
database password inside it.
Next, download the init script, which starts and stops the daemonized Perl script:
This is a Debian-based init script, and should work without modification on that platform. If you don't have Debian, modify it as necessary.
Link the init script into your rc.d
directories as appropriate.
Under Debian, the update-rc.d
utility can help you with this.
To test the script, you can run it directly with the -D
flag to
run in debugging mode, e.g.:
/usr/local/sbin/nec_smdr -D
Instead of daemonizing, the script will run in the foreground and provide extra information as call records are processed.
If your serial port is hooked up, you should see debugging information about the calls as they are processed. Confirm that the calls are being logged to the database.
If everything is working correctly in debug mode, quit and issue:
/etc/init.d/nec_smdr start
To launch the daemonized version. The program is now running in normal mode and processing calls. You're all done!
==== Some Hints About the Script ===
The processing script has three major phases in it:
If you need to modify the script to understand a different record format, you'll need to modify the record parsing section, and possibly the SQL section (if the number or names of the fields change).
The script has a very well-commented section on the call record format that it understands. Additionally, the script will log any lines it receives that it does not understand, so you can quickly debug the format of the lines.
If you're having trouble with the script, be sure to run it in debug
mode (with the -D
flag). This mode prevents the script from
disassociating from the terminal, and provides much more verbose
logging of its activity. It's very helpful for seeing what's going on
during processing.