nfagent 0.9.30 → 0.9.31

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.
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