nfagent 0.9.30 → 0.9.31

Sign up to get free protection for your applications and to get access to all the features.
File without changes
@@ -1,4 +1,4 @@
1
- === 0.0.1 2011-02-03
1
+ == 0.0.1 2009-09-22
2
2
 
3
3
  * 1 major enhancement:
4
4
  * Initial release
@@ -1,47 +1,29 @@
1
- History.txt
2
- Manifest.txt
3
- PostInstall.txt
4
- README.rdoc
5
1
  Rakefile
6
- script/console
7
- script/destroy
8
- script/generate
9
- test/test_chunk.rb
10
- test/test_chunk_handler.rb
11
- test/test_client.rb
12
- test/test_config.rb
13
- test/test_helper.rb
14
- test/test_mapper_proxy.rb
15
- test/test_nfagent.rb
16
- test/test_payload.rb
17
- test/test_plugin.rb
18
- test/config
19
- sandbox/dumps/debug
20
- test/plugins/my_mapper.rb
21
2
  lib/nfagent.rb
22
3
  lib/nfagent
23
- lib/nfagent/base64.rb
24
- lib/nfagent/chunk.rb
25
- lib/nfagent/chunk_handler.rb
26
4
  lib/nfagent/cli.rb
27
- lib/nfagent/client.rb
28
- lib/nfagent/client_response.rb
29
- lib/nfagent/config.rb
5
+ lib/nfagent/base64.rb
30
6
  lib/nfagent/encoder.rb
31
- lib/nfagent/event.rb
32
- lib/nfagent/info.rb
7
+ lib/nfagent/server.rb
8
+ lib/nfagent/chunk_handler.rb
33
9
  lib/nfagent/log.rb
34
- lib/nfagent/mapper_proxy.rb
35
- lib/nfagent/object_extra.rb
10
+ lib/nfagent/info.rb
11
+ lib/nfagent/event.rb
36
12
  lib/nfagent/payload.rb
37
- lib/nfagent/plugin.rb
38
13
  lib/nfagent/poller.rb
39
- lib/nfagent/server.rb
40
- lib/nfagent/submitter.rb
14
+ lib/nfagent/chunk.rb
15
+ lib/nfagent/client.rb
16
+ lib/nfagent/client_response.rb
17
+ lib/nfagent/config.rb
41
18
  lib/nfagent/tail.rb
42
19
  lib/nfagent/tests.rb
20
+ lib/nfagent/submitter.rb
43
21
  bin/nfagent
44
22
  bin/squid_log_writer
23
+ PostInstall.txt
24
+ History.txt
25
+ Manifest.txt
26
+ README.txt
45
27
  nfagent.conf
46
28
  nfagent.init.ubuntu.txt
47
29
  nfagent.init.redhat.txt
@@ -1,7 +1 @@
1
-
2
1
  For more information on nfagent, see http://nfagent.rubyforge.org
3
-
4
- NOTE: Change this information in PostInstall.txt
5
- You can also delete it if you don't want it.
6
-
7
-
@@ -1,6 +1,6 @@
1
- = nfagent
1
+ = NetFox Agent
2
2
 
3
- * http://github.com/#{github_username}/#{project_name}
3
+ * http://netfox.com
4
4
 
5
5
  == DESCRIPTION:
6
6
 
@@ -8,25 +8,33 @@ Logging Agent for NetFox Online
8
8
 
9
9
  == FEATURES/PROBLEMS:
10
10
 
11
- * FIX (list of features or problems)
12
11
 
13
12
  == SYNOPSIS:
14
13
 
15
- FIX (code sample of usage)
16
14
 
17
15
  == REQUIREMENTS:
18
16
 
19
- * FIX (list of requirements)
17
+ * Event Machine
18
+ * SV Util
20
19
 
21
20
  == INSTALL:
22
21
 
23
- * FIX (sudo gem install, anything else)
22
+ sudo gem install nfagent
23
+
24
+ == DEVELOPERS:
25
+
26
+ After checking out the source, run:
27
+
28
+ $ rake newb
29
+
30
+ This task will install any missing dependencies, run the tests/specs,
31
+ and generate the RDoc.
24
32
 
25
33
  == LICENSE:
26
34
 
27
35
  (The MIT License)
28
36
 
29
- Copyright (c) 2011 FIXME full name
37
+ Copyright (c) 2010 FIX
30
38
 
31
39
  Permission is hereby granted, free of charge, to any person obtaining
32
40
  a copy of this software and associated documentation files (the
data/Rakefile CHANGED
@@ -1,28 +1,31 @@
1
- require 'rubygems'
2
- gem 'hoe', '>= 2.1.0'
3
- require 'hoe'
4
- require 'fileutils'
5
- require './lib/nfagent'
6
-
7
- Hoe.plugin :newgem
8
- # Hoe.plugin :website
9
- # Hoe.plugin :cucumberfeatures
1
+ %w[rubygems rake rake/clean hoe fileutils newgem rubigen].each { |f| require f }
2
+ require File.dirname(__FILE__) + '/lib/nfagent'
10
3
 
11
4
  # Generate all the Rake tasks
12
5
  # Run 'rake -T' to see list of generated tasks (from gem root directory)
13
- $hoe = Hoe.spec 'nfagent' do
14
- self.developer('Daniel Draper', 'daniel@netfox.com')
15
- self.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
16
- self.rubyforge_name = self.name # TODO this is default value
17
- self.extra_deps = [
18
- ['svutil','>= 0.1.3'], ['eventmachine', '>= 0.12.8'], ['squiggle', '>= 0.0.8']
6
+ $hoe = Hoe.spec('nfagent') do |p|
7
+ p.version = NFAgent::VERSION
8
+ p.summary = "Logging Agent for NetFox Online"
9
+ p.developer('Daniel Draper', 'daniel@netfox.com')
10
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
11
+ p.post_install_message = 'PostInstall.txt'
12
+ p.rubyforge_name = p.name
13
+ p.extra_deps = [
14
+ ['svutil','>= 0.0.12'], ['eventmachine', '>= 0.12.8']
19
15
  ]
20
-
16
+ p.extra_dev_deps = [
17
+ ['newgem', ">= #{::Newgem::VERSION}"]
18
+ ]
19
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
20
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
21
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
22
+ p.rsync_args = '-av --delete --ignore-errors'
23
+ p.readme_file = "README.txt"
24
+ p.spec_extras[:default_executable] = 'nfagent'
21
25
  end
22
26
 
23
- require 'newgem/tasks'
27
+ require 'newgem/tasks' # load /tasks/*.rake
24
28
  Dir['tasks/**/*.rake'].each { |t| load t }
25
29
 
26
30
  # TODO - want other tests/tasks run by default? Add them to the list
27
- # remove_task :default
28
31
  # task :default => [:spec, :features]
@@ -6,14 +6,12 @@ class Client
6
6
  def initialize(host, port)
7
7
  @host = host
8
8
  @port = port
9
- @count = 0
10
9
  end
11
10
 
12
11
  def write_safely(data)
13
12
  connect_socket unless @connected
14
13
  begin
15
14
  @client.puts(data)
16
- sleep 0.01
17
15
  rescue
18
16
  @connected = false
19
17
  end
@@ -2,9 +2,7 @@ $:.unshift(File.dirname(__FILE__)) unless
2
2
  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
3
 
4
4
  require 'rubygems'
5
- require 'active_support'
6
5
  require 'svutil'
7
- require 'squiggle'
8
6
 
9
7
  require 'fileutils'
10
8
  require 'logger'
@@ -15,13 +13,10 @@ require 'eventmachine'
15
13
  require 'em/timers'
16
14
  require 'rbconfig'
17
15
 
18
- require 'nfagent/object_extra'
19
16
  require 'nfagent/chunk'
20
17
  require 'nfagent/client'
21
18
  require 'nfagent/client_response'
22
19
  require 'nfagent/chunk_handler'
23
- require 'nfagent/mapper_proxy'
24
- require 'nfagent/plugin'
25
20
  require 'nfagent/submitter'
26
21
  require 'nfagent/encoder'
27
22
  require 'nfagent/config'
@@ -36,5 +31,5 @@ require 'nfagent/cli'
36
31
  require 'nfagent/tests'
37
32
 
38
33
  module NFAgent
39
- VERSION = '0.9.30'
34
+ VERSION = '0.9.31'
40
35
  end
@@ -2,58 +2,44 @@ require 'zlib'
2
2
  require 'digest'
3
3
 
4
4
  module NFAgent
5
- class ChunkExpired < StandardError; end
6
- class ChunkFull < StandardError; end
7
- class DayBoundary < StandardError; end
8
-
9
- class Chunk < Array
5
+ class Chunk
10
6
  attr_reader :created_at
11
- attr_reader :max_size
12
7
 
13
- DEFAULT_MAX_SIZE = 500
8
+ ::DEFAULT_TIME_OUT = 60
14
9
 
15
- def initialize(max_size = DEFAULT_MAX_SIZE)
10
+ def initialize(max_size = 500)
16
11
  @max_size = max_size
17
12
  @created_at = Time.now
13
+ @array = []
14
+ @submitter = Submitter.new(Config.client_key)
18
15
  end
19
16
 
20
17
  def <<(line)
21
- raise ChunkExpired if expired?
22
- raise ChunkFull if full?
23
- raise DayBoundary if Time.now.day != self.created_at.day
24
- super(line)
18
+ @array << line
25
19
  end
26
20
 
27
21
  def full?
28
- self.size >= @max_size
22
+ @array.size >= @max_size
29
23
  end
30
24
 
31
25
  def expired?
32
- (Time.now - @created_at > Config.chunk_timeout) && !self.empty?
26
+ (Time.now - @created_at > ::DEFAULT_TIME_OUT) && !@array.empty?
33
27
  end
34
28
 
35
- def dump(key = nil)
29
+ # TODO: Is this the right place for compression, encoding and check summing? Perhaps it should go into the submitter to that it can be deferred
30
+ def dump
36
31
  Payload.new do |payload|
37
- Log.info("Dumping payload from chunk (#{self.size || 0} lines #{'due to expiry' if expired?}")
38
- payload.line_count = self.size
32
+ Log.info("Dumping payload from chunk (#{@array.size} lines)")
33
+ payload.line_count = @array.size
39
34
  payload.chunk_expired = expired?
40
- payload.key = key
41
- payload.data = Encoder.encode64url(Zlib::Deflate.deflate(self.join("\n"), Zlib::BEST_COMPRESSION))
35
+ payload.data = Encoder.encode64url(Zlib::Deflate.deflate(@array.join("\n"), Zlib::BEST_COMPRESSION))
42
36
  payload.checksum = Digest::SHA1.hexdigest(payload.data)
43
37
  end
44
38
  end
45
39
 
46
- def submit(key = nil)
47
- Log.info("Submitting...")
48
- # TODO God knows why EM Deferrable isn't working - defer here is OK
49
- EM.defer {
50
- submitter = Submitter.new(self.dump(key))
51
- submitter.errback { |payload|
52
- payload.write_to_disk(Config.dump_dir)
53
- }
54
- submitter.perform
55
- }
56
- # Callback and remove from chunk group
40
+ def clear
41
+ @array.clear
42
+ @created_at = Time.now
57
43
  end
58
44
  end
59
45
  end
@@ -1,72 +1,40 @@
1
1
  module NFAgent
2
- class LookUpError < StandardError; end
3
- class IgnoreLine < StandardError; end
4
-
5
2
  class ChunkHandler
6
3
 
7
- attr_accessor :chunk_group
8
-
9
- def initialize(options = {})
10
- @chunk_size = options[:chunk_size] || 500
11
- @parser = options[:parser] || Squiggle::SquidStandardParser.new(Config.time_zone)
12
- @chunk_group = {}
13
- class << @chunk_group
14
- def fetch!(key, new_chunk)
15
- if self.has_key?(key)
16
- self.fetch(key)
17
- else
18
- self[key] = new_chunk
19
- new_chunk
20
- end
21
- end
22
- end
4
+ # TODO: Rename this to Controller later
5
+ def initialize(chunk_size = 500)
6
+ @chunk = Chunk.new(chunk_size)
23
7
  end
24
8
 
25
9
  def append(line)
26
- if Config.parse == 'locally'
27
- parsed = @parser.parse(line)
28
- return if parsed.invalid?
29
- if Config.mode == 'multi'
30
- begin
31
- key = MapperProxy.find_account_id(parsed.username, parsed.client_ip)
32
- # TODO: Still appending line as string until Server API has been updated
33
- return append2(line, key)
34
- rescue LookUpError, IgnoreLine
35
- return # Do nothing
36
- end
37
- end
38
- end
39
- # TODO: rename append2
40
- append2(line)
41
- end
42
-
43
- def append2(line, key = nil)
44
- key ||= 'all'
45
- begin
46
- chunk = @chunk_group.fetch!(key, Chunk.new(@chunk_size))
47
- chunk << line
48
- rescue ChunkExpired, ChunkFull
49
- Log.info("Chunk full or expired, cannot add lines")
50
- reset_chunk(key)
10
+ # if current day is > day of last entry on current_chunk
11
+ # then submit and reset the chunk before adding the line
12
+ current_day = Time.now.day
13
+ if current_day != @chunk.created_at.day
14
+ Log.info("Expiring chunk due to date rollover")
15
+ reset_chunk
51
16
  end
17
+ @chunk << line
52
18
  end
53
19
 
54
20
  def check_full_or_expired
55
- @chunk_group.each_pair do |key, chunk|
56
- if chunk.full?
57
- Log.info("Chunk Full: Resetting...")
58
- reset_chunk(key)
59
- elsif chunk.expired?
60
- Log.info("Chunk Expired: Resetting...")
61
- reset_chunk(key)
62
- end
21
+ if @chunk.full?
22
+ Log.info("Chunk Full: Resetting...")
23
+ reset_chunk
24
+ elsif @chunk.expired?
25
+ Log.info("Chunk Expired: Resetting...")
26
+ reset_chunk
63
27
  end
64
28
  end
65
29
 
66
30
  private
67
- def reset_chunk(key = nil)
68
- chunk = @chunk_group.delete(key || 'all')
69
- chunk.submit(key == 'all' ? nil : key)
31
+ def reset_chunk
32
+ submitter = Submitter.new(@chunk.dump)
33
+ submitter.errback { |payload|
34
+ payload.write_to_disk(Config.dump_dir)
35
+ }
36
+ @chunk.clear
37
+ submitter.perform
70
38
  end
71
39
  end
72
40
  end
@@ -4,12 +4,12 @@ module NFAgent
4
4
  include SVUtil
5
5
 
6
6
  def initialize
7
- Config.init
7
+ Config.load_and_parse
8
8
  if Config.test_mode?
9
9
  Tests.run
10
10
  exit 1
11
11
  end
12
- @process = ProcessManager.new(Server)
12
+ @process = ProcessManager.new(Server, Config)
13
13
  @process.start
14
14
  end
15
15
  end
@@ -1,6 +1,6 @@
1
1
  module NFAgent
2
2
  class Client
3
- SERVICE_HOST = "collector.service.netfox.com"
3
+ SERVICE_HOST = "collector.service.netfox.com"
4
4
 
5
5
  def self.post(end_point, data_hash)
6
6
  proxy_class = Net::HTTP::Proxy(Config.http_proxy_host, Config.http_proxy_port, Config.http_proxy_user, Config.http_proxy_password)
@@ -8,17 +8,14 @@ module NFAgent
8
8
  proxy_class.start(SERVICE_HOST, 80) do |http|
9
9
  http.read_timeout = 120 # 2 minutes TODO: Make this a config option with 120 as default
10
10
  req = Net::HTTP::Post.new("/#{end_point}")
11
- p({"key" => Config.client_key}.merge(data_hash).delete('data'))
12
- req.set_form_data({"key" => Config.client_key}.merge(data_hash))
11
+ req.set_form_data(data_hash.merge("key" => Config.client_key))
13
12
  ClientResponse.new do |resp|
14
13
  resp.response, resp.message = http.request(req)
15
- Log.info("Client Returned with '#{resp.message}'")
16
14
  end
17
15
  end
18
16
  rescue Exception => e
19
17
  # Trap Exception class here to ensure we catch Timeout
20
18
  ClientResponse.new do |resp|
21
- Log.info("Client Error: #{$!}")
22
19
  resp.message = $!
23
20
  end
24
21
  end
@@ -8,41 +8,11 @@ module NFAgent
8
8
  @@test_mode
9
9
  end
10
10
 
11
- # Config Options
12
- # client_key: String, the access key for the client (for the account in normal mode or for a partner in multi mode)
13
- # dump_dir: String, the directory path of a local spool location
14
- # pid_file: String, path of process ID file
15
- # mode: (optional, default: 'normal') String, either 'normal' or 'multi' - can be left blank
16
- # mapping: Class, this is a plugin class which must be stored in a file in the directory /etc/nfagent/plugins/
17
- # parse: (optional, default: 'remotely'): String, either 'remotely' or 'locally'
18
- #
19
- defaults do |c|
20
- c.mode = 'normal'
21
- c.parse = 'remotely'
22
- c.chunk_timeout = 60
23
- c.time_zone = 'UTC'
24
- c.plugin_directory = '/etc/nfagent/plugins/'
25
- end
26
-
27
11
  class << self
28
12
  def validate
29
13
  unless dump_dir and File.exists?(dump_dir) and File.directory?(dump_dir)
30
14
  raise "Dump dir (#{dump_dir}) must exist and be a directory"
31
15
  end
32
- # Mode
33
- unless %w(normal multi).include?(mode)
34
- raise "Invalid mode: must be one of 'normal' or 'multi'"
35
- end
36
- if mode == 'multi' && mapper.blank?
37
- raise "Multi mode requires a mapper to be set"
38
- end
39
- if mode == 'multi' && parse != 'locally'
40
- raise "Multi mode requires that parsing be done locally (set parse = 'locally')"
41
- end
42
- # Parse
43
- unless %w(remotely locally).include?(parse)
44
- raise "Invalid parse option: Must be one of 'remotely' or 'locally'"
45
- end
46
16
  super
47
17
  end
48
18
 
@@ -60,9 +30,6 @@ module NFAgent
60
30
  opts.on("-T", "--test", "Run connection tests") do
61
31
  @@test_mode = true
62
32
  end
63
- opts.on("-P", "--parse", "Parse locally before submitting") do
64
- Config.parse_locally = true
65
- end
66
33
  end
67
34
  end
68
35
  end