bind_log_analyzer 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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