Bind Log Analyzer
Simple analysis and SQL storage for Bind DNS server's logs.
The gem includes a web interface to analyze the data collected from the analyzed logs.
Requirements
This gem was tested with:
- ruby-2.1.x
- rubygem (1.8.15)
- bundler (1.0.21)
- activerecord (3.2.2)
Installation
Just install the gem:
gem install bind_log_analyzer
The gem requires active_record but you probably need to install the right adapter. As example, if you'll use MySQL, install the mysql2 gem.
Configuration
Bind
To configure Bind add these lines to /etc/bind/named.conf.options (or whatever your s.o. and bind installation require)
logging{
channel "querylog" {
file "/var/log/bind/query.log";
print-time yes;
};
category queries { querylog; };
};
Restart bind and make sure than the query.log file contains lines as this:
28-Mar-2012 16:48:19.694 client 192.168.10.38#58767: query: www.github.com IN A + (192.168.10.1)
or the regexp will fail :(
Database
To store the logs you can use every database supported by ActiveRecord. Just create a database and a user with the right privileges. You can provide the -s flag to BindLogAnalyzer to make it create the table. Otherwise create it by yourself.
This is the MySQL CREATE TABLE syntax:
CREATE TABLE `logs` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`date` datetime NOT NULL,
`client` varchar(255) NOT NULL,
`query` varchar(255) NOT NULL,
`q_type` varchar(255) NOT NULL,
`server` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;
Usage
Use the provided --help to get various options available. This is the default help:
-h, --help Display this screen
-v, --verbose LEVEL Enables verbose output. Use level 1 for WARN, 2 for INFO and 3 for DEBUG
-w, --webserver [HTTP_PORT] Launches the Sinatra web server on specified port, or 4567 if omitted
-s, --setup Creates the needed tables in the database.
-f, --file FILE Indicates the log file to parse. It's mandatory if you don't specify the --webserver option.
-c, --config CONFIG A yaml file containing the database configurations under the "database" entry
-a, --adapter ADAPTER The database name to save the logs
-d, --database DATABASE The database name to save the logs
-H, --host HOST The address (IP, hostname or path) of the database
-P, --port PORT The port of the database
-u, --user USER The username to be used to connect to the database
-p, --password PASSWORD The password of the user
The first time you launch BindLogAnalyzer you can use the -s|--setup flag to make it create the table (using ActiveRecord::Migration).
The database credentials can be provided using the needed flags or creating a YAML file containing all the informations under the database key. This is an example:
database:
adapter: mysql2
database: bindloganalyzer
host: localhost
port: 3306
username: root
password:
There are two usage of the gem:
- Use --file FILE flag to pass to BindLogAnalyzer the file to analyze.
- Use -w, --webserver [HTTP_PORT] to start the Sinatra webserver and watch the stats on the collected data.
Automatization
A good way to use this script is to let it be launched by logrotate so create the /etc/logrotate.d/bind file with this content:
/var/log/named/query.log {
weekly
missingok
rotate 8
compress
delaycompress
notifempty
create 644 bind bind
postrotate
if [ -e /var/log/named/query.log.1 ]; then
exec su - YOUR_USER -c '/usr/local/bin/update_bind_log_analyzer.sh /var/log/named/query.log.1'
fi
endscript
}
The script /usr/local/bin/update_bind_log_analyzer.sh can be wherever you prefer. Its typical content if you use RVM and a dedicated gemset for BindLogAnalyzer, can be:
#!/bin/bash
# *************************** #
# EDIT THESE VARS #
# *************************** #
BLA_RVM_GEMSET="1.9.3-p125@bind_log_analyzer"
BLA_USER="my_username"
BLA_DB_FILE="/etc/bind_log_analyzer/database.yml"
# *************************** #
# DO NOT EDIT BELOW THIS LINE #
# *************************** #
. /home/$BLA_USER/.rvm/scripts/rvm && source "/home/$BLA_USER/.rvm/scripts/rvm"
rvm use $BLA_RVM_GEMSET
bind_log_analyzer --config $BLA_DB_FILE --file $1
Performance
On a 1.6 Ghz Intel Core i5 with SSD SATA2 disk, using Ruby-1.9.3-p125 and MySQL 5.5.15, this is the performance:
~$ time bind_log_analyzer -f query.log -c database.yml
Analyzed 319758 lines and correctly stored 319758 logs
bind_log_analyzer -f query.log -c database.yml 322,44s user 22,90s system 76% cpu 7:33,17 total
which is equivalent to ±706 query/sec.
Development
First, create a database and add its credentials in the database.yml
file.
Then create the logs
table with the following query:
CREATE TABLE `logs` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`date` datetime NOT NULL,
`client` varchar(255) NOT NULL,
`query` varchar(255) NOT NULL,
`q_type` varchar(255) NOT NULL,
`server` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;
Run tests
bundle exec rspec
Changelog
###0.2.4
Support both old and new Bind log versions
Add --bind
option to the cli to bind Sinatra on specified IP
Reverse the order of the last queries in the GUI
Fix tests
0.2.3
Added the -u|--uniqueness flag to check if a record exists in the db before inserting a new one
0.2.2
Added the new BindLogAnalyzer::LogUtils module and the Logger support in various parts of the code
0.2.1
If the -c, --config CONFIG parameter is not specified, it tries to use a database.yml file in the directory from where the gem was launched
0.2.0
First version including the web interface
0.1.0
First stable version