nfagent 0.9.31 → 0.9.50

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.
@@ -13,7 +13,7 @@ module NFAgent
13
13
  if data && data.length > 10
14
14
  @handler.append(data)
15
15
  end
16
- send_data('OK')
16
+ #send_data('OK')
17
17
  end
18
18
 
19
19
  def unbind
@@ -0,0 +1,18 @@
1
+ module NFAgent
2
+ class MapperProxy
3
+ class << self
4
+ def instance
5
+ return @instance if @instance
6
+ raise "No Mapper Set" if Config.mapper.blank?
7
+ @instance = Object.const_get(Config.mapper).new
8
+ end
9
+
10
+ # TODO: Can we delegate?
11
+ def find_account_id(username, client_ip)
12
+ instance.find_account_id(username, client_ip)
13
+ end
14
+
15
+ # TODO: before shutdown
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,5 @@
1
+ class Object
2
+ def blank?
3
+ respond_to?(:empty?) ? empty? : !self
4
+ end
5
+ end
@@ -1,6 +1,6 @@
1
1
 
2
2
  module NFAgent
3
- class Payload < Struct.new(:data, :checksum, :filename, :line_count, :chunk_expired)
3
+ class Payload < Struct.new(:data, :checksum, :filename, :line_count, :chunk_expired, :key)
4
4
  def initialize
5
5
  yield self
6
6
  end
@@ -23,16 +23,19 @@ module NFAgent
23
23
  end
24
24
 
25
25
  def to_hash
26
- {
26
+ ret = {
27
27
  "payload" => self.data,
28
28
  "checksum" => self.checksum,
29
29
  "line_count" => self.line_count,
30
30
  "chunk_expired" => self.chunk_expired
31
31
  }
32
+ ret["key"] = self.key unless self.key.blank?
33
+ ret
32
34
  end
33
35
 
34
36
  def write_to_disk(directory)
35
- File.open(File.join(directory, "#{self.checksum}-#{self.attempt}"), "w") do |file|
37
+ filename = [ self.checksum, self.attempt, self.key ].compact.join("-")
38
+ File.open(File.join(directory, filename), "w") do |file|
36
39
  file << self.data
37
40
  end
38
41
  end
@@ -48,14 +51,14 @@ module NFAgent
48
51
  filename && File.exists?(lockfile)
49
52
  end
50
53
 
51
- def self.read_from_file(filename)
54
+ def self.read_from_file(filename, dir = Config.dump_dir)
52
55
  # Ensure the file is only relative
53
56
  filename = File.basename(filename)
54
57
  self.new do |payload|
55
58
  payload.filename = filename
56
- payload.checksum, payload.attempt = filename.split("-")
59
+ payload.checksum, payload.attempt, payload.key = filename.split("-")
57
60
  payload.data = ""
58
- ref = File.join(Config.dump_dir, filename)
61
+ ref = File.join(dir, filename)
59
62
  File.open(ref, "r") do |file|
60
63
  payload.data << file.read
61
64
  end
@@ -68,7 +71,8 @@ module NFAgent
68
71
 
69
72
  def try_again_later
70
73
  # TODO: Move the file to a new name with a later timetamp
71
- FileUtils.mv(File.join(Config.dump_dir, self.filename), File.join(Config.dump_dir, "#{self.checksum}-#{self.attempt}"))
74
+ new_filename = [ self.checksum, self.attempt, self.key ].compact.join("-")
75
+ FileUtils.mv(File.join(Config.dump_dir, self.filename), File.join(Config.dump_dir, new_filename))
72
76
  end
73
77
 
74
78
  private
@@ -0,0 +1,14 @@
1
+ module NFAgent
2
+ class Plugin
3
+ class << self
4
+ def load_plugins
5
+ if Config.plugin_directory && !Config.plugin_directory.empty? && File.exists?(Config.plugin_directory)
6
+ Dir.glob(File.join(Config.plugin_directory, "*.rb")).each do |file|
7
+ Log.info("Loading plugin: #{file}")
8
+ load(file)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -2,6 +2,11 @@ module NFAgent
2
2
  class Server
3
3
  def run
4
4
  Log.info("Starting up")
5
+ NFAgent::Plugin.load_plugins
6
+
7
+ Log.info("Parsing #{Config.parse}")
8
+ Log.info("Mode set to #{Config.mode}")
9
+
5
10
  chunk_handler = ChunkHandler.new
6
11
  poller = Poller.new
7
12
 
@@ -15,6 +15,7 @@ module NFAgent
15
15
  response = Client.post(:collector, @payload.to_hash)
16
16
  if response.ok?
17
17
  succeed(@payload)
18
+ Log.info("Submitted #{@payload.line_count} lines")
18
19
  else
19
20
  Log.error "Submission Failed: #{response.message}"
20
21
  fail(@payload)
@@ -1,4 +1,4 @@
1
- client_key = 1234
2
- dump_dir = /tmp/dumps
3
- log_file = /tmp/debug
4
- pid_file = /tmp/nfagent.pid
1
+ client_key = hOFxKEgYEBf1Ni8WqJ02
2
+ dump_dir = sandbox/dumps
3
+ log_file = sandbox/debug
4
+ pid_file = sandbox/nfagent.pid
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/nfagent.rb'}"
9
+ puts "Loading nfagent gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
@@ -0,0 +1,5 @@
1
+ client_key = 1234
2
+ dump_dir = sandbox/dumps
3
+ log_file = sandbox/debug
4
+ pid_file = sandbox/nfagent.pid
5
+ plugin_directory = test/plugins/
@@ -0,0 +1,18 @@
1
+ class MyMapper
2
+ def initialize
3
+ @hash = {
4
+ 'dan' => 'acme',
5
+ 'paul' => 'jetson',
6
+ 'mike' => 'acme'
7
+ }
8
+ end
9
+
10
+ def before_shutdown
11
+ # Put any cleanup code in here
12
+ end
13
+
14
+ def find_account_id(username, client_ip)
15
+ raise NFAgent::IgnoreLine if username == 'andrew'
16
+ @hash[username]
17
+ end
18
+ end
@@ -0,0 +1,79 @@
1
+
2
+ require 'test/test_helper'
3
+
4
+ class TestChunk < ActiveSupport::TestCase
5
+ setup do
6
+ NFAgent::Config.config_file = "test/config"
7
+ NFAgent::Config.init
8
+ @logline = "1253604221 19 127.0.0.1 TCP_MISS/200 562 GET http://www.gravatar.com/blavatar/e81cfb9068d04d1cfd598533bb380e1f?s=16&d=http://s.wordpress.com/favicon.ico - NONE/- text/html"
9
+ end
10
+
11
+ test "initialize" do
12
+ chunk = NFAgent::Chunk.new
13
+ assert_equal 500, chunk.max_size
14
+ chunk = NFAgent::Chunk.new(600)
15
+ assert_equal 600, chunk.max_size
16
+ end
17
+
18
+ test "full" do
19
+ chunk = NFAgent::Chunk.new(20)
20
+ 19.times do
21
+ chunk << @logline
22
+ end
23
+ assert !chunk.full?
24
+ chunk << @logline
25
+ assert chunk.full?
26
+ assert_raises(NFAgent::ChunkFull) { chunk << @logline }
27
+ end
28
+
29
+ test "won't expire if empty" do
30
+ NFAgent::Config.chunk_time_out = 1
31
+ chunk = NFAgent::Chunk.new
32
+ assert !chunk.expired?
33
+ Timecop.freeze(Time.now + 61) do
34
+ assert !chunk.expired?
35
+ end
36
+ end
37
+
38
+ test "expired" do
39
+ chunk = NFAgent::Chunk.new
40
+ chunk << @logline
41
+ assert !chunk.expired?
42
+ Timecop.freeze(Time.now + 61) do
43
+ assert chunk.expired?
44
+ assert_raises(NFAgent::ChunkExpired) { chunk << @logline }
45
+ end
46
+ end
47
+
48
+ test "day boundary" do
49
+ d = Date.today
50
+ Timecop.travel(Time.local(2011, 1, 10, 23, 59, 58)) do
51
+ chunk = NFAgent::Chunk.new
52
+ Timecop.travel(Time.local(2011, 1, 11, 0, 0, 10)) do
53
+ assert_raises(NFAgent::DayBoundary) { chunk << @logline }
54
+ end
55
+ end
56
+ end
57
+
58
+ test "submit" do
59
+ EM.expects(:defer)
60
+ chunk = NFAgent::Chunk.new
61
+ chunk.submit
62
+ end
63
+
64
+ test "dump" do
65
+ Zlib::Deflate.expects(:deflate).returns("x\234\313\316*/\314HO-\312N\317(J\005\000&~\005u").times(2)
66
+ chunk = NFAgent::Chunk.new
67
+ chunk << @logline
68
+ payload = chunk.dump
69
+ assert_equal 1, payload.line_count
70
+ assert_instance_of String, payload.data
71
+ # Dump with key
72
+ payload = chunk.dump('acme')
73
+ assert_equal 'acme', payload.key
74
+ end
75
+
76
+ test "dump from LogLine" do
77
+ pending
78
+ end
79
+ end
@@ -0,0 +1,131 @@
1
+
2
+ require 'test/test_helper'
3
+
4
+ class TestChunkHandler < ActiveSupport::TestCase
5
+ setup do
6
+ NFAgent::Config.config_file = "test/config"
7
+ NFAgent::Config.init
8
+ NFAgent::Config.plugin_directory = File.dirname(__FILE__) + '/../test/plugins/'
9
+ NFAgent::Plugin.load_plugins
10
+ @logline = "1253604221 19 127.0.0.1 TCP_MISS/200 562 GET http://www.gravatar.com/blavatar/e81cfb9068d04d1cfd598533bb380e1f?s=16&d=http://s.wordpress.com/favicon.ico dan NONE/- text/html"
11
+ @logline2 = "1253604221 19 127.0.0.1 TCP_MISS/200 562 GET http://www.gravatar.com/blavatar/e81cfb9068d04d1cfd598533bb380e1f?s=16&d=http://s.wordpress.com/favicon.ico paul NONE/- text/html"
12
+ @ignored_logline = "1253604221 19 127.0.0.1 TCP_MISS/200 562 GET http://www.gravatar.com/blavatar/e81cfb9068d04d1cfd598533bb380e1f?s=16&d=http://s.wordpress.com/favicon.ico andrew NONE/- text/html"
13
+ end
14
+
15
+ test "append line" do
16
+ chunk_handler = NFAgent::ChunkHandler.new
17
+ chunk_handler.append(@logline)
18
+ assert_equal 1, chunk_handler.chunk_group['all'].size
19
+ assert_instance_of String, chunk_handler.chunk_group['all'][-1]
20
+ end
21
+
22
+ test "append with local parsing" do
23
+ NFAgent::Config.parse = 'locally'
24
+ chunk_handler = NFAgent::ChunkHandler.new
25
+ chunk_handler.append(@logline)
26
+ assert_equal 1, chunk_handler.chunk_group['all'].size
27
+ assert_instance_of Squiggle::LogLine, chunk_handler.chunk_group['all'][-1]
28
+ end
29
+
30
+ test "append with multi" do
31
+ NFAgent::Config.parse = 'locally'
32
+ NFAgent::Config.mode = 'multi'
33
+ NFAgent::Config.mapper = 'MyMapper'
34
+ chunk_handler = NFAgent::ChunkHandler.new
35
+ chunk_handler.append(@logline)
36
+ assert chunk_handler.chunk_group.has_key?('acme')
37
+ assert_equal 1, chunk_handler.chunk_group['acme'].size
38
+ chunk_handler.append(@logline2)
39
+ assert chunk_handler.chunk_group.has_key?('acme')
40
+ assert chunk_handler.chunk_group.has_key?('jetson')
41
+ assert_equal 1, chunk_handler.chunk_group['acme'].size
42
+ assert_equal 1, chunk_handler.chunk_group['jetson'].size
43
+ end
44
+
45
+ test "mapper raises ignore line in multi mode" do
46
+ NFAgent::Config.parse = 'locally'
47
+ NFAgent::Config.mode = 'multi'
48
+ NFAgent::Config.mapper = 'MyMapper'
49
+ chunk_handler = NFAgent::ChunkHandler.new
50
+ chunk_handler.append(@ignored_logline)
51
+ assert !chunk_handler.chunk_group.has_key?('acme')
52
+ assert !chunk_handler.chunk_group.has_key?('jetson')
53
+ assert chunk_handler.chunk_group['acme'].blank?
54
+ assert chunk_handler.chunk_group['jetson'].blank?
55
+ end
56
+
57
+ test "reset chunk after expiry in multi mode" do
58
+ NFAgent::Config.parse = 'locally'
59
+ NFAgent::Config.mode = 'multi'
60
+ NFAgent::Config.mapper = 'MyMapper'
61
+ NFAgent::Chunk.any_instance.expects(:submit).at_least_once
62
+ chunk_handler = NFAgent::ChunkHandler.new
63
+ chunk_handler.append(@logline)
64
+ Timecop.travel(30) do
65
+ chunk_handler.append(@logline2)
66
+ assert_equal 1, chunk_handler.chunk_group['acme'].size
67
+ assert_equal 1, chunk_handler.chunk_group['jetson'].size
68
+
69
+ Timecop.travel(31) do
70
+ chunk_handler.check_full_or_expired
71
+ assert !chunk_handler.chunk_group.has_key?('acme')
72
+ assert_equal 1, chunk_handler.chunk_group['jetson'].size
73
+
74
+ Timecop.travel(31) do
75
+ chunk_handler.check_full_or_expired
76
+ assert !chunk_handler.chunk_group.has_key?('acme')
77
+ assert !chunk_handler.chunk_group.has_key?('jestson')
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+ test "reset chunk after full with check_full_or_expired in multi mode" do
84
+ NFAgent::Config.parse = 'locally'
85
+ NFAgent::Config.mode = 'multi'
86
+ NFAgent::Config.mapper = 'MyMapper'
87
+ EM.expects(:defer).times(2)
88
+ chunk_handler = NFAgent::ChunkHandler.new(:chunk_size => 10)
89
+ 9.times { chunk_handler.append(@logline) }
90
+ 9.times { chunk_handler.append(@logline2) }
91
+ assert_equal 9, chunk_handler.chunk_group['acme'].size
92
+ assert_equal 9, chunk_handler.chunk_group['jetson'].size
93
+ chunk_handler.append(@logline)
94
+ chunk_handler.check_full_or_expired
95
+ assert !chunk_handler.chunk_group.has_key?('acme')
96
+ chunk_handler.append(@logline2)
97
+ chunk_handler.check_full_or_expired
98
+ assert !chunk_handler.chunk_group.has_key?('jetson')
99
+ end
100
+
101
+ test "fail an invalid logline in local parse mode" do
102
+ NFAgent::Config.parse = 'locally'
103
+ chunk_handler = NFAgent::ChunkHandler.new
104
+ chunk_handler.append("") # Invalid logline
105
+ assert chunk_handler.chunk_group['all'].nil?
106
+ end
107
+
108
+ test "reset chunk is passed appropriate key in multi mode" do
109
+ NFAgent::Config.parse = 'locally'
110
+ NFAgent::Config.mode = 'multi'
111
+ NFAgent::Config.mapper = 'MyMapper'
112
+ NFAgent::Chunk.any_instance.expects(:submit).with('acme')
113
+ chunk_handler = NFAgent::ChunkHandler.new
114
+ chunk_handler.append(@logline)
115
+ Timecop.travel(61) do
116
+ chunk_handler.check_full_or_expired
117
+ end
118
+ end
119
+
120
+ test "reset chunk is passed nil key in normal mode" do
121
+ NFAgent::Config.parse = 'remotely'
122
+ NFAgent::Config.mode = 'normal'
123
+ NFAgent::Chunk.any_instance.expects(:submit).with(nil)
124
+ chunk_handler = NFAgent::ChunkHandler.new
125
+ chunk_handler.append(@logline)
126
+ Timecop.travel(61) do
127
+ chunk_handler.check_full_or_expired
128
+ end
129
+ end
130
+
131
+ end
@@ -0,0 +1,20 @@
1
+
2
+ require 'test/test_helper'
3
+
4
+ class TestClient < ActiveSupport::TestCase
5
+ setup do
6
+ end
7
+
8
+ test "post data with configured client key" do
9
+ Net::HTTP::Post.any_instance.expects(:set_form_data).with({ 'payload' => 'data', 'checksum' => 'checksum', 'line_count' => 10, 'chunk_expired' => false, 'key' => '1234' })
10
+ hash = { 'payload' => 'data', 'checksum' => 'checksum', 'line_count' => 10, 'chunk_expired' => false }
11
+ NFAgent::Client.post(:collector, hash)
12
+ end
13
+
14
+ test "post data with key passed in data hash" do
15
+ Net::HTTP::Post.any_instance.expects(:set_form_data).with({ 'payload' => 'data', 'checksum' => 'checksum', 'line_count' => 10, 'chunk_expired' => false, 'key' => 'abcd' })
16
+ hash = { 'payload' => 'data', 'checksum' => 'checksum', 'line_count' => 10, 'chunk_expired' => false, 'key' => 'abcd' }
17
+ NFAgent::Client.post(:collector, hash)
18
+ end
19
+
20
+ end
@@ -0,0 +1,49 @@
1
+
2
+ require 'test/test_helper'
3
+
4
+ class TestConfig < ActiveSupport::TestCase
5
+ setup do
6
+ NFAgent::Config.attrs.clear
7
+ end
8
+
9
+ test "defaults" do
10
+ puts "HHHHHH"
11
+ p NFAgent::Config.attrs
12
+ assert_equal "normal", NFAgent::Config.mode
13
+ assert_equal "remotely", NFAgent::Config.parse
14
+ assert_equal 60, NFAgent::Config.chunk_timeout
15
+ assert_equal 'UTC', NFAgent::Config.time_zone
16
+ assert_equal '/etc/nfagent/plugins/', NFAgent::Config.plugin_directory
17
+ end
18
+
19
+ test "validates valid mode" do
20
+ NFAgent::Config.mode = 'some stupid thing'
21
+ assert_raises(RuntimeError) { NFAgent::Config.validate }
22
+ end
23
+
24
+ test "validates mapping with multi" do
25
+ NFAgent::Config.attrs.clear
26
+ NFAgent::Config.config_file = "test/config"
27
+ NFAgent::Config.init
28
+
29
+ NFAgent::Config.mode = 'multi'
30
+ assert_raises(RuntimeError) { NFAgent::Config.validate }
31
+ NFAgent::Config.mapper = 'AccountMapper'
32
+ assert_raises(RuntimeError) { NFAgent::Config.validate }
33
+ NFAgent::Config.parse = 'locally'
34
+ assert NFAgent::Config.validate
35
+ end
36
+
37
+ test "validates valid parse option" do
38
+ NFAgent::Config.attrs.clear
39
+ NFAgent::Config.config_file = "test/config"
40
+ NFAgent::Config.init
41
+
42
+ NFAgent::Config.parse = 'some stupid thing'
43
+ assert_raises(RuntimeError) { NFAgent::Config.validate }
44
+ NFAgent::Config.parse = 'locally'
45
+ assert NFAgent::Config.validate
46
+ NFAgent::Config.parse = 'remotely'
47
+ assert NFAgent::Config.validate
48
+ end
49
+ end