bind_log_analyzer 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .rvmrc
6
+ query.log
7
+ coverage/
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in bind_log_analyzer.gemspec
4
+ gemspec
5
+
6
+ gem 'mysql2'
data/README.md ADDED
@@ -0,0 +1,126 @@
1
+ # Bind Log Analyzer
2
+
3
+ Simple analysis and SQL storage for Bind DNS server's logs
4
+
5
+ ## Requirements
6
+
7
+ This gem was tested with:
8
+
9
+ - ruby-1.9.3-p125
10
+ - rubygem (1.8.15)
11
+ - bundler (1.0.21)
12
+ - activerecord (3.2.2)
13
+
14
+ ## Installation
15
+
16
+ Just install the gem:
17
+
18
+ gem install bind_log_analyzer
19
+
20
+ 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.
21
+
22
+ ## Configuration
23
+
24
+ ### Bind
25
+
26
+ To configure **Bind** add these lines to _/etc/bind/named.conf.options_ (or whatever your s.o. and bind installation require)
27
+
28
+ logging{
29
+ channel "querylog" {
30
+ file "/var/log/bind/query.log";
31
+ print-time yes;
32
+ };
33
+
34
+ category queries { querylog; };
35
+ };
36
+
37
+ Restart bind and make sure than the _query.log_ file contains lines as this:
38
+
39
+ 28-Mar-2012 16:48:19.694 client 192.168.10.38#58767: query: www.github.com IN A + (192.168.10.1)
40
+
41
+ or the regexp will fail :(
42
+
43
+ ### Database
44
+
45
+ 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.
46
+ This is the MySQL CREATE TABLE syntax:
47
+
48
+ CREATE TABLE `logs` (
49
+ `id` int(11) NOT NULL AUTO_INCREMENT,
50
+ `date` datetime NOT NULL,
51
+ `client` varchar(255) NOT NULL,
52
+ `query` varchar(255) NOT NULL,
53
+ `q_type` varchar(255) NOT NULL,
54
+ `server` varchar(255) NOT NULL,
55
+ PRIMARY KEY (`id`)
56
+ ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;
57
+
58
+ ## Usage
59
+
60
+ Use the provided --help to get various options available. This is the default help:
61
+
62
+ -h, --help Display this screen
63
+ -v, --verbose LEVEL Enables verbose output. Use level 1 for WARN, 2 for INFO and 3 for DEBUG
64
+ -s, --setup Creates the needed tables in the database.
65
+ -f, --file FILE Indicates the log file to parse. It's mandatory.
66
+ -c, --config CONFIG A yaml file containing the database configurations under the "database" entry
67
+ -a, --adapter ADAPTER The database name to save the logs
68
+ -d, --database DATABASE The database name to save the logs
69
+ -H, --host HOST The address (IP, hostname or path) of the database
70
+ -P, --port PORT The port of the database
71
+ -u, --user USER The username to be used to connect to the database
72
+ -p, --password PASSWORD The password of the user
73
+
74
+ There's only one mandatory argument which is **--file FILE**. With this flag you pass the Bind log file to analyze to *BindLogAnalyzer*.
75
+
76
+ The first time you launch *BindLogAnalyzer* you can use the **-s|--setup** flag to make it create the table (using ActiveRecord::Migration).
77
+ 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:
78
+
79
+ database:
80
+ adapter: mysql2
81
+ database: bindloganalyzer
82
+ host: localhost
83
+ port: 3306
84
+ username: root
85
+ password:
86
+
87
+ ## Automatization
88
+
89
+ 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:
90
+
91
+ /var/log/named/query.log {
92
+ weekly
93
+ missingok
94
+ rotate 8
95
+ compress
96
+ delaycompress
97
+ notifempty
98
+ create 644 bind bind
99
+ postrotate
100
+ if [ -e /var/log/named/query.log.1 ]; then
101
+ exec su - YOUR_USER -c '/usr/local/bin/update_bind_log_analyzer.sh /var/log/named/query.log.1'
102
+ fi
103
+ endscript
104
+ }
105
+
106
+ 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:
107
+
108
+ #!/bin/bash
109
+
110
+ # *************************** #
111
+ # EDIT THESE VARS #
112
+ # *************************** #
113
+ BLA_RVM_GEMSET="1.9.3-p125@bind_log_analyzer"
114
+ BLA_USER="my_username"
115
+ BLA_DB_FILE="/etc/bind_log_analyzer/database.yml"
116
+
117
+ # *************************** #
118
+ # DO NOT EDIT BELOW THIS LINE #
119
+ # *************************** #
120
+ . /home/$BLA_USER/.rvm/scripts/rvm && source "/home/$BLA_USER/.rvm/scripts/rvm"
121
+ rvm use $BLA_RVM_GEMSET
122
+ bind_log_analyzer --config $BLA_DB_FILE --file $1
123
+
124
+ ## To do
125
+
126
+ - Add a web interface to show the queries (with awesome graphs, obviously :)
data/Rakefile ADDED
@@ -0,0 +1,110 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+
3
+ require "bind_log_analyzer/version"
4
+
5
+ require 'rubygems'
6
+ require 'rspec/core/rake_task'
7
+ require "bundler/gem_tasks"
8
+
9
+ require 'yaml'
10
+ require 'logger'
11
+ require 'active_record'
12
+
13
+ namespace :spec do
14
+ desc "Run all specs"
15
+ RSpec::Core::RakeTask.new(:spec) do |t|
16
+ #t.pattern = 'spec/**/*_spec.rb'
17
+ t.rspec_opts = ['--options', 'spec/spec.opts']
18
+ end
19
+
20
+ desc "Generate code coverage"
21
+ RSpec::Core::RakeTask.new(:coverage) do |t|
22
+ #t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
23
+ require 'simplecov'
24
+ SimpleCov.start
25
+ #t.rcov = true
26
+ #t.rcov_opts = ['--exclude', 'spec']
27
+ end
28
+ end
29
+
30
+ task :build do
31
+ system "gem build bind_log_analyzer.gemspec"
32
+ end
33
+
34
+ task :release => :build do
35
+ system "gem push pkg/bind_log_analyzer-#{BindLogAnalyzer::VERSION}.gem"
36
+ end
37
+
38
+ namespace :db do
39
+ def create_database config
40
+ options = {:charset => 'utf8', :collation => 'utf8_unicode_ci'}
41
+
42
+ create_db = lambda do |config|
43
+ ActiveRecord::Base.establish_connection config.merge('database' => nil)
44
+ ActiveRecord::Base.connection.create_database config['database'], options
45
+ ActiveRecord::Base.establish_connection config
46
+ end
47
+
48
+ begin
49
+ create_db.call config
50
+ rescue Mysql::Error => sqlerr
51
+ if sqlerr.errno == 1405
52
+ print "#{sqlerr.error}. \nPlease provide the root password for your mysql installation\n>"
53
+ root_password = $stdin.gets.strip
54
+
55
+ grant_statement = <<-SQL
56
+ GRANT ALL PRIVILEGES ON #{config['database']}.*
57
+ TO '#{config['username']}'@'localhost'
58
+ IDENTIFIED BY '#{config['password']}' WITH GRANT OPTION;
59
+ SQL
60
+
61
+ create_db.call config.merge('database' => nil, 'username' => 'root', 'password' => root_password)
62
+ else
63
+ $stderr.puts sqlerr.error
64
+ $stderr.puts "Couldn't create database for #{config.inspect}, charset: utf8, collation: utf8_unicode_ci"
65
+ $stderr.puts "(if you set the charset manually, make sure you have a matching collation)" if config['charset']
66
+ end
67
+ end
68
+ end
69
+
70
+ task :environment do
71
+ DATABASE_ENV = ENV['DATABASE_ENV'] || 'development'
72
+ MIGRATIONS_DIR = ENV['MIGRATIONS_DIR'] || 'db/migrate'
73
+ end
74
+
75
+ task :configuration => :environment do
76
+ @config = YAML.load_file('config/databases.yml')[DATABASE_ENV]
77
+ end
78
+
79
+ task :configure_connection => :configuration do
80
+ ActiveRecord::Base.establish_connection @config
81
+ ActiveRecord::Base.logger = Logger.new STDOUT if @config['logger']
82
+ end
83
+
84
+ desc 'Create the database from config/database.yml for the current DATABASE_ENV'
85
+ task :create => :configure_connection do
86
+ create_database @config
87
+ end
88
+
89
+ desc 'Drops the database for the current DATABASE_ENV'
90
+ task :drop => :configure_connection do
91
+ ActiveRecord::Base.connection.drop_database @config['database']
92
+ end
93
+
94
+ desc 'Migrate the database (options: VERSION=x, VERBOSE=false).'
95
+ task :migrate => :configure_connection do
96
+ ActiveRecord::Migration.verbose = true
97
+ ActiveRecord::Migrator.migrate MIGRATIONS_DIR, ENV['VERSION'] ? ENV['VERSION'].to_i : nil
98
+ end
99
+
100
+ desc 'Rolls the schema back to the previous version (specify steps w/ STEP=n).'
101
+ task :rollback => :configure_connection do
102
+ step = ENV['STEP'] ? ENV['STEP'].to_i : 1
103
+ ActiveRecord::Migrator.rollback MIGRATIONS_DIR, step
104
+ end
105
+
106
+ desc "Retrieves the current schema version number"
107
+ task :version => :configure_connection do
108
+ puts "Current version: #{ActiveRecord::Migrator.current_version}"
109
+ end
110
+ end
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bind_log_analyzer"
4
+ require 'optparse'
5
+
6
+ @filename = nil
7
+ @log_level = 0
8
+ @database_confs = nil
9
+ @setup_database = false
10
+ @db_yaml = nil
11
+ @db_adapter = 'mysql2'
12
+ @db_host = nil
13
+ @db_database = nil
14
+ @db_port = nil
15
+ @db_username = nil
16
+ @db_password = nil
17
+
18
+ optparse = OptionParser.new do |opts|
19
+ # Set a banner, displayed at the top
20
+ # of the help screen.
21
+ opts.banner = "Usage: ./#{File.basename(__FILE__)} (--file|-f FILENAME [--setup|-s] [--verbose|-v (1|2|3)] [--database|-d database_name] [--config|-c database_yaml_configurations] [--host|-H database_hostname] [--port|-p database_port] [--user|-u database_username] [--password|-p database_password] | --help|-h)"
22
+
23
+ # This displays the help screen
24
+ opts.on( '-h', '--help', 'Display this screen' ) do
25
+ puts opts
26
+ exit
27
+ end
28
+
29
+ opts.on( '-v', '--verbose LEVEL', "Enables verbose output. Use level 1 for WARN, 2 for INFO and 3 for DEBUG" ) do |opt|
30
+ case
31
+ when 1 === opt.to_i
32
+ @log_level = 1
33
+ when 2 === opt.to_i
34
+ @log_level = 2
35
+ when opt.to_i >= 3
36
+ @log_level = 3
37
+ end
38
+ end
39
+
40
+ opts.on( '-s', '--setup', "Creates the needed tables in the database." ) do |opt|
41
+ @setup_database = true
42
+ end
43
+
44
+ opts.on( '-f', '--file FILE', "Indicates the log file to parse. It's mandatory." ) do |opt|
45
+ @filename = opt
46
+ end
47
+
48
+ opts.on( '-c', '--config CONFIG', 'A yaml file containing the database configurations under the "database" entry' ) do |opt|
49
+ @db_yaml = opt
50
+ end
51
+
52
+ opts.on( '-a', '--adapter ADAPTER', 'The database name to save the logs' ) do |opt|
53
+ @db_adapter = opt
54
+ end
55
+
56
+ opts.on( '-d', '--database DATABASE', 'The database name to save the logs' ) do |opt|
57
+ @db_database = opt
58
+ end
59
+
60
+ opts.on( '-H', '--host HOST', 'The address (IP, hostname or path) of the database' ) do |opt|
61
+ @db_host = opt
62
+ end
63
+
64
+ opts.on( '-P', '--port PORT', 'The port of the database' ) do |opt|
65
+ @db_port = opt
66
+ end
67
+
68
+ opts.on( '-u', '--user USER', 'The username to be used to connect to the database' ) do |opt|
69
+ @db_username = opt
70
+ end
71
+
72
+ opts.on( '-p', '--password PASSWORD', 'The password of the user' ) do |opt|
73
+ @db_password = opt
74
+ end
75
+ end
76
+
77
+ optparse.parse!
78
+
79
+ if @db_yaml
80
+ @database_confs = @db_yaml
81
+ elsif @db_username || @db_password || @db_host || @db_port || @db_database
82
+ @database_confs = {
83
+ adapter: @db_adapter,
84
+ username: @db_username,
85
+ password: @db_password,
86
+ host: @db_host,
87
+ port: @db_port,
88
+ database: @db_database
89
+ }
90
+ end
91
+
92
+ if @filename
93
+ @base = BindLogAnalyzer::Base.new(@database_confs, @filename, @setup_database, @log_level)
94
+ @base.analyze
95
+ else
96
+ puts optparse.banner
97
+ exit -1
98
+ end
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "bind_log_analyzer/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "bind_log_analyzer"
7
+ s.version = BindLogAnalyzer::VERSION
8
+ s.authors = ["Tommaso Visconti"]
9
+ s.email = ["tommaso.visconti@gmail.com"]
10
+ s.homepage = "https://github.com/tommyblue/Bind-Log-Analyzer"
11
+ s.summary = %q{Log analysis and SQL storage for Bind DNS server}
12
+ s.description = %q{BindLogAnalyzer analyzes a Bind query log file and stores it's data into a SQL database (ActiveRecord is used for this feature)}
13
+
14
+ s.rubyforge_project = "bind_log_analyzer"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_dependency "activerecord"
22
+ s.add_development_dependency "rspec"
23
+ s.add_development_dependency "simplecov"
24
+ end
@@ -0,0 +1,11 @@
1
+ class CreateLogs < ActiveRecord::Migration
2
+ def change
3
+ create_table :logs do |t|
4
+ t.datetime :date, :null => false
5
+ t.string :client, :null => false
6
+ t.string :query, :null => false
7
+ t.string :q_type, :null => false
8
+ t.string :server, :null => false
9
+ end
10
+ end
11
+ end
data/doc/database.yml ADDED
@@ -0,0 +1,7 @@
1
+ database:
2
+ adapter: mysql2
3
+ database: bindloganalyzer
4
+ host: localhost
5
+ port: 3306
6
+ username: root
7
+ password:
@@ -0,0 +1,16 @@
1
+ #!/bin/bash
2
+
3
+ # *************************** #
4
+ # EDIT THESE VARS #
5
+ # *************************** #
6
+ BLA_PATH="~/Devel/bind-log-analyzer"
7
+ BLA_RVM_GEMSET="1.9.3-p125@bind_log_analyzer"
8
+ BLA_USER="my_username"
9
+
10
+ # *************************** #
11
+ # DO NOT EDIT BELOW THIS LINE #
12
+ # *************************** #
13
+ cd $BLA_PATH
14
+ . /home/$BLA_USER/.rvm/scripts/rvm && source "/home/$BLA_USER/.rvm/scripts/rvm"
15
+ rvm use $BLA_RVM_GEMSET
16
+ $BLA_PATH/bin/bind_log_analyzer -f $1
@@ -0,0 +1,87 @@
1
+ require 'bind_log_analyzer/exceptions'
2
+ require 'bind_log_analyzer/connector'
3
+ require 'models/log'
4
+
5
+ module BindLogAnalyzer
6
+ class Base
7
+ include BindLogAnalyzer::Connector
8
+
9
+ attr_reader :log_filename, :database_confs
10
+
11
+ def initialize(database_confs = nil, logfile = nil, setup_database = false, log_level = 0)
12
+ if database_confs
13
+ if database_confs.instance_of?(Hash)
14
+ @database_confs = database_confs
15
+ else
16
+ # Load the yaml file
17
+ if FileTest.exists?(database_confs)
18
+ @database_confs = YAML::load(File.open(database_confs))['database']
19
+ else
20
+ raise BindLogAnalyzer::DatabaseConfsNotValid, "The indicated YAML file doesn't exist or is invalid"
21
+ end
22
+ end
23
+ else
24
+ # Tries to find the yaml file or prints an error
25
+ filename = File.join(File.dirname(__FILE__), 'database.yml')
26
+ if FileTest.exists?(filename)
27
+ @database_confs = YAML::load(File.open(filename))['database']
28
+ else
29
+ raise BindLogAnalyzer::DatabaseConfsNotValid, "Can't find valid database configurations"
30
+ end
31
+ end
32
+
33
+ @stored_queries = 0
34
+ self.logfile = logfile if logfile
35
+ setup_db(@database_confs, setup_database, log_level)
36
+ end
37
+
38
+ def logfile=(logfile)
39
+ @log_filename = logfile if FileTest.exists?(logfile)
40
+ end
41
+
42
+ def logfile
43
+ @log_filename
44
+ end
45
+
46
+ def parse_line(line)
47
+ query = {}
48
+ regexp = %r{^(\d{2}-\w{3}-\d{4}\s+\d{2}:\d{2}:\d{2}\.\d{3})\s+client\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})#\d+:\s+query:\s+(.*)\s+IN\s+(\w+)\s+\+\s+\((\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\)$}
49
+
50
+ parsed_line = line.scan(regexp)
51
+ if parsed_line.size > 0
52
+ # Parse timestamp
53
+ parsed_timestamp = Date._strptime(parsed_line[0][0], "%d-%b-%Y %H:%M:%S.%L")
54
+ query_time = Time.local(parsed_timestamp[:year], parsed_timestamp[:mon], parsed_timestamp[:mday], parsed_timestamp[:hour], parsed_timestamp[:min], parsed_timestamp[:sec], parsed_timestamp[:sec_fraction], parsed_timestamp[:zone])
55
+
56
+ query[:date] = query_time
57
+ query[:client] = parsed_line[0][1]
58
+ query[:query] = parsed_line[0][2]
59
+ query[:q_type] = parsed_line[0][3]
60
+ query[:server] = parsed_line[0][4]
61
+
62
+ query
63
+ else
64
+ false
65
+ end
66
+ end
67
+
68
+ def store_query(query)
69
+ log = Log.new(query)
70
+ @stored_queries += 1 if log.save
71
+ end
72
+
73
+ def analyze
74
+ return false unless @log_filename
75
+
76
+ lines = 0
77
+ File.new(@log_filename).each do |line|
78
+ query = self.parse_line(line)
79
+ if query
80
+ self.store_query(query)
81
+ lines += 1
82
+ end
83
+ end
84
+ puts "Analyzed #{lines} lines and correctly stored #{@stored_queries} logs"
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,47 @@
1
+ require 'active_record'
2
+ require 'logger'
3
+
4
+ module BindLogAnalyzer
5
+ module Connector
6
+
7
+ def setup_db(database_params, setup_database = false, log_level = 0)
8
+ @database_params = database_params
9
+
10
+ self.connect
11
+
12
+ migrate_tables if setup_database
13
+
14
+ self.load_environment
15
+ if log_level > 0
16
+
17
+ log_level_class = {
18
+ 1 => Logger::WARN,
19
+ 2 => Logger::INFO,
20
+ 3 => Logger::DEBUG
21
+ }
22
+
23
+ log = Logger.new STDOUT
24
+ log.level = log_level_class[log_level]
25
+ ActiveRecord::Base.logger = log
26
+ end
27
+ end
28
+
29
+ def migrate_tables
30
+ ActiveRecord::Migration.verbose = true
31
+ migrations_dir = File.join(File.dirname(__FILE__), '..', '..', 'db/migrate')
32
+ ActiveRecord::Migrator.migrate migrations_dir
33
+ end
34
+
35
+ def connect
36
+ ActiveRecord::Base.establish_connection(@database_params)
37
+ end
38
+
39
+ def connected?
40
+ ActiveRecord::Base.connected?
41
+ end
42
+
43
+ def load_environment
44
+ Dir.glob('./lib/models/*').each { |r| require r }
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,4 @@
1
+ module BindLogAnalyzer
2
+ class DatabaseConfsNotValid < Exception
3
+ end
4
+ end
@@ -0,0 +1,3 @@
1
+ module BindLogAnalyzer
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,6 @@
1
+ require "bind_log_analyzer/version"
2
+ require "bind_log_analyzer/base"
3
+
4
+ module BindLogAnalyzer
5
+
6
+ end
data/lib/models/log.rb ADDED
@@ -0,0 +1,2 @@
1
+ class Log < ActiveRecord::Base
2
+ end
@@ -0,0 +1,86 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe BindLogAnalyzer do
4
+ before :all do
5
+ @db_params = YAML::load(File.open(File.join(File.dirname(__FILE__), '..', 'config', 'databases.yml')))['database']
6
+
7
+ # Create a test logfile
8
+ @filename = 'test_file.log'
9
+ @doc = <<EOF
10
+ 28-Mar-2012 16:48:32.411 client 192.168.10.37#60303: query: github.com IN A + (192.168.10.1)
11
+ 28-Mar-2012 16:48:32.412 client 192.168.10.201#60303: query: google.com IN AAAA + (192.168.10.1)
12
+ 28-Mar-2012 16:48:32.898 client 192.168.10.114#53309: query: www.nasa.gov IN A + (192.168.10.1)
13
+ EOF
14
+
15
+ File.open(@filename, 'w') { |f| f.write(@doc) } unless FileTest.exists?(@filename)
16
+ end
17
+
18
+ after :all do
19
+ #delete the test logfile
20
+ File.delete(@filename) if FileTest.exists?(@filename)
21
+ end
22
+
23
+ before :each do
24
+ end
25
+
26
+ #it "can't be instantiated without database params" do
27
+ # base = BindLogAnalyzer::Base.new
28
+ # ??
29
+ #end
30
+
31
+ it "can be instantiated without a logfile" do
32
+ base = BindLogAnalyzer::Base.new(@db_params)
33
+ base.logfile.should == nil
34
+ end
35
+
36
+ it "permit setting a logfile from initializer" do
37
+ @base = BindLogAnalyzer::Base.new(@db_params, @filename)
38
+ @base.logfile.should == @filename
39
+ end
40
+
41
+ it "should update the logfile name" do
42
+ @base = BindLogAnalyzer::Base.new(@db_params, @filename)
43
+
44
+ # Create a new dummy file
45
+ @new_filename = 'new_test_file.log'
46
+ doc = ''
47
+ File.open(@new_filename, 'w') { |f| f.write(doc) } unless FileTest.exists?(@new_filename)
48
+
49
+ @base.logfile = @new_filename
50
+ @base.logfile.should == @new_filename
51
+
52
+ # Delete the file
53
+ File.delete(@new_filename)
54
+ end
55
+
56
+ it "shouldn't update the logfile name if it doesn't exist" do
57
+ @base = BindLogAnalyzer::Base.new(@db_params, @filename)
58
+ @base.logfile = 'unexisting_test_file'
59
+ @base.logfile.should_not == 'unexisting_test_file'
60
+ end
61
+
62
+ it "should correctly parse a line" do
63
+ @base = BindLogAnalyzer::Base.new(@db_params, @filename)
64
+ line = "28-Mar-2012 16:48:32.412 client 192.168.10.201#60303: query: google.com IN AAAA + (192.168.10.1)"
65
+ test_line = {
66
+ date: Time.local('2012','mar',28, 16, 48, 31),
67
+ client: "192.168.10.201",
68
+ query: "google.com",
69
+ type: "AAAA",
70
+ server: "192.168.10.1"
71
+ }
72
+ parsed_line = @base.parse_line(line)
73
+ parsed_line.should == test_line
74
+ end
75
+
76
+ it "should be connected after setup_db is called" do
77
+ @base = BindLogAnalyzer::Base.new(@db_params, @filename)
78
+ @base.connected?.should == true
79
+ end
80
+
81
+ it "should be possible to instantiate a Log class after BindLogAnalyzer::Base initialization" do
82
+ @base = BindLogAnalyzer::Base.new(@db_params, @filename)
83
+ log = Log.new
84
+ log.class.should_not == NilClass
85
+ end
86
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --colour
@@ -0,0 +1,9 @@
1
+ SPEC_DIR = File.dirname(__FILE__)
2
+ lib_path = File.expand_path("#{SPEC_DIR}/../lib")
3
+ $LOAD_PATH.unshift lib_path unless $LOAD_PATH.include?(lib_path)
4
+
5
+ require 'rubygems'
6
+ require 'bundler/setup'
7
+
8
+ require 'bind_log_analyzer'
9
+ require 'models/log'
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bind_log_analyzer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Tommaso Visconti
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-03 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activerecord
16
+ requirement: &8286660 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *8286660
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ requirement: &8286020 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *8286020
36
+ - !ruby/object:Gem::Dependency
37
+ name: simplecov
38
+ requirement: &8285380 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *8285380
47
+ description: BindLogAnalyzer analyzes a Bind query log file and stores it's data into
48
+ a SQL database (ActiveRecord is used for this feature)
49
+ email:
50
+ - tommaso.visconti@gmail.com
51
+ executables:
52
+ - bind_log_analyzer
53
+ extensions: []
54
+ extra_rdoc_files: []
55
+ files:
56
+ - .gitignore
57
+ - Gemfile
58
+ - README.md
59
+ - Rakefile
60
+ - bin/bind_log_analyzer
61
+ - bind_log_analyzer.gemspec
62
+ - db/migrate/20120329151738_create_logs.rb
63
+ - doc/database.yml
64
+ - doc/update_bind_log_analyzer.sh
65
+ - lib/bind_log_analyzer.rb
66
+ - lib/bind_log_analyzer/base.rb
67
+ - lib/bind_log_analyzer/connector.rb
68
+ - lib/bind_log_analyzer/exceptions.rb
69
+ - lib/bind_log_analyzer/version.rb
70
+ - lib/models/log.rb
71
+ - spec/bind_log_analyzer_spec.rb
72
+ - spec/spec.opts
73
+ - spec/spec_helper.rb
74
+ homepage: https://github.com/tommyblue/Bind-Log-Analyzer
75
+ licenses: []
76
+ post_install_message:
77
+ rdoc_options: []
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ! '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ requirements: []
93
+ rubyforge_project: bind_log_analyzer
94
+ rubygems_version: 1.8.15
95
+ signing_key:
96
+ specification_version: 3
97
+ summary: Log analysis and SQL storage for Bind DNS server
98
+ test_files:
99
+ - spec/bind_log_analyzer_spec.rb
100
+ - spec/spec.opts
101
+ - spec/spec_helper.rb