snoopit 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 773c96a6cce42a924a16de8a09d32981180fb570
4
- data.tar.gz: e150e7960bad252b7707abd10775fdc748226f39
3
+ metadata.gz: 988a42e05de998211eac2a93a6c6692c320369be
4
+ data.tar.gz: 9fad23966cbbe1a33ab254a5f55b2d4960ecdbba
5
5
  SHA512:
6
- metadata.gz: c73e43dd072abdbdef14e56ab28ae096c3beeca3d8bfc7dd9de1dbd0929b57af194882f49e2dc279d674fdf0d6d2ea70805b0756ddb3da6876656ae4217b5404
7
- data.tar.gz: e80aa3bf4c634cfb6cd35adcec8d6009af9ecb141a04f8aa1aaac5c583dcece65b62f20dd90b14e062995132fa97362ebc6a82abe2880ab72bf86b4f9ae4b074
6
+ metadata.gz: 9c7b97959b9e5f0ec282990567eef77141da2cc06f4be52fa21065afc848039737069fa8c4febdbb72a32a1be936a291f48bb5d24928e717965942edea4ca430
7
+ data.tar.gz: b230a55bf4487df00f0fb36d3a377b8b7ad7c7ff57d483f54ff99f23080ae2befd0453efd32e43172782338e94ff5a104dcb50336026f525038d4010ba4d88a8
@@ -1,6 +1,9 @@
1
1
  language: ruby
2
2
 
3
+ bundler_args: --without debug
4
+
3
5
  rvm:
6
+ - 1.9.3
4
7
  - 2.0.0
5
8
  - 2.1.0
6
9
 
data/Gemfile CHANGED
@@ -3,9 +3,12 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in snoopit.gemspec
4
4
  gemspec
5
5
 
6
+ group :debug do
7
+ gem 'pry', '~> 0.9.12.6', require: false
8
+ gem 'pry-byebug', '~> 1.3.0', require: false
9
+ end
10
+
6
11
  group :test, :development do
7
- gem 'pry', '~> 0.9.12.6'
8
- gem 'pry-byebug', '~> 1.3.0'
9
12
  gem 'coveralls', :require => false
10
13
  end
11
14
 
@@ -13,6 +13,7 @@ require 'snoopit/notifiers/email'
13
13
  require 'snoopit/notifiers/http'
14
14
  require 'snoopit/notifiers/https'
15
15
 
16
+ # Snoops files for a matching regular expressions and generates subscribed events
16
17
  module Snoopit
17
18
 
18
19
  def self.logger
@@ -1,8 +1,11 @@
1
1
  module Snoopit
2
+
3
+ # When the sniffer detects a match it saves the contextual information in a +Detected+ instances
2
4
  class Detected
3
5
 
4
6
  attr :comment, :before, :after, :after_count, :regexp, :match, :finished, :file, :line_no
5
7
 
8
+ # These are parameters from the match
6
9
  def initialize(comment, pre_before, after, match, file, line_no)
7
10
  setup_before pre_before
8
11
  @comment = comment
@@ -14,10 +17,12 @@ module Snoopit
14
17
  @finished = false
15
18
  end
16
19
 
20
+ # Get the lines before the found match
17
21
  def setup_before(pre_before)
18
22
  @before = Register.new pre_before.size, pre_before.register
19
23
  end
20
24
 
25
+ # This collects the lines after a match is found
21
26
  def track(line)
22
27
  return if line == @match
23
28
  if @after_count < @after.size
@@ -1,6 +1,8 @@
1
1
  require 'time'
2
2
 
3
3
  module Snoopit
4
+
5
+ # Holds and manages the file read information
4
6
  class FileInfo
5
7
 
6
8
  attr_accessor :file, :line_no, :offset, :size, :mtime, :last_line, :init_stat
@@ -18,6 +20,7 @@ module Snoopit
18
20
  # Update file Info if the file has changed use the file handle to move the file pointer
19
21
  # to the character where reading will start
20
22
  #
23
+ # @param file_handle [File]
21
24
  # @return [boolean] true if updated false not updated
22
25
  def updated?(file_handle)
23
26
  c_stat = File.stat @file
@@ -38,6 +41,7 @@ module Snoopit
38
41
  updated
39
42
  end
40
43
 
44
+ # This is a new file reset or start reading from the beginning
41
45
  def new_file?(file_handle, stat)
42
46
  # seek to 0
43
47
  Snoopit.logger.debug 'FileTracker.updated? file new read from start of file: ' + @file
@@ -49,6 +53,7 @@ module Snoopit
49
53
  true
50
54
  end
51
55
 
56
+ # Continue reading from last location, which maybe on new file on initialization
52
57
  def read_from_last?(file_handle, stat)
53
58
  # seek to last position + 1
54
59
  old_size = @size
@@ -60,6 +65,7 @@ module Snoopit
60
65
  true
61
66
  end
62
67
 
68
+ # Get the last line of the file
63
69
  def get_last_line(file_handle)
64
70
  line = nil
65
71
  unless @last_line.nil?
@@ -1,4 +1,8 @@
1
1
  module Snoopit
2
+
3
+ # Used to track file locations of the last requested snoops per +snooper.json+
4
+ # This is handy for repeated invocations via +cron+ so that the snooper does not send repeated notifications
5
+ # This is a very simple json file with **NO** concurrency.
2
6
  class FileTracker
3
7
 
4
8
  attr_accessor :files, :db_file
@@ -13,6 +17,7 @@ module Snoopit
13
17
  end
14
18
  end
15
19
 
20
+ # Used to start reading lines from the last read invocation
16
21
  def foreach(file, &block)
17
22
  file_info = get_file(file)
18
23
  unless file_info.nil?
@@ -21,12 +26,14 @@ module Snoopit
21
26
  end
22
27
  end
23
28
 
29
+ # Get the last read file information
24
30
  def get_file(file)
25
31
  return nil unless File.exist? file
26
32
  @files[file] = FileInfo.new(file) if @files[file].nil?
27
33
  @files[file]
28
34
  end
29
35
 
36
+ # Used to start reading lines from the last read invocation
30
37
  def read_lines(file_info, block)
31
38
  begin
32
39
  fh = File.new(file_info.file)
@@ -2,8 +2,11 @@ require 'logger'
2
2
  require 'awesome_print'
3
3
 
4
4
  module Snoopit
5
+
6
+ # Snoopis Logging Wrapper
5
7
  module Logging
6
8
 
9
+ # Maps standard logger constants to symbols
7
10
  LEVEL_MAP = {
8
11
  info: ::Logger::INFO,
9
12
  warn: ::Logger::WARN,
@@ -1,5 +1,6 @@
1
1
  module Snoopit
2
2
 
3
+ # Instantiates all specified +Notifiers+
3
4
  class NotificationManager
4
5
 
5
6
  attr :active, :config
@@ -10,6 +11,7 @@ module Snoopit
10
11
  load_default_notifiers unless @config.nil?
11
12
  end
12
13
 
14
+ # Load default notifiers and configured notifiers
13
15
  def load_notifier_config(config)
14
16
  @config = config
15
17
  load_default_notifiers
@@ -17,12 +19,16 @@ module Snoopit
17
19
  load_files(load) unless load.nil?
18
20
  end
19
21
 
22
+ # Register the specified +Notifier+
23
+ # @param notifier [Notifier]
20
24
  def register(notifier)
21
25
  raise NameError.new "Notifier missing valid name: #{notifier.inspect}" if notifier.name.nil?
22
26
  Snoopit.logger.debug "Registering notifier #{notifier.name}"
23
27
  @active[notifier.name] = notifier
24
28
  end
25
29
 
30
+ # Unregister the specified +Notifier+
31
+ # @param notifier [Notifier]
26
32
  def unregister(notifier)
27
33
  self.unregister_by_name notifier.name
28
34
  end
@@ -35,6 +41,8 @@ module Snoopit
35
41
  @active[name]
36
42
  end
37
43
 
44
+ # Invoke all notifications that this list of snoopies is subscribed to via the +snooper.json+
45
+ # @param snoopies [Snoopy]
38
46
  def notify(snoopies)
39
47
  snoopies.each do |snoopy|
40
48
  snoopy.sniffers.each do |sniffer|
@@ -43,6 +51,8 @@ module Snoopit
43
51
  end
44
52
  end
45
53
 
54
+ # Snoopies use sniffers that may or may not be associated with a notifier
55
+ # @param sniffer [Sniffer]
46
56
  def sniffer_notify(sniffer)
47
57
  messages = get_sniffed_messages sniffer
48
58
  sniffer.notifiers.each do |key, value|
@@ -2,6 +2,7 @@ require 'stomp'
2
2
  require 'awesome_print'
3
3
 
4
4
  module Snoopit
5
+ # Notifiers belong to this module
5
6
  module Notifiers
6
7
 
7
8
  class Stomp < Snoopit::Notifier
@@ -1,8 +1,12 @@
1
1
  module Snoopit
2
+
3
+ # Does the actual searching for the given regular expression
2
4
  class Sniffer
3
5
 
4
6
  attr :pre_before, :before, :after, :comment, :regexp, :sniffed, :notifiers
5
7
 
8
+ # This creates a +Sniffer+ which was specified in the +snoopers.json+ file in the +sniffers+ section
9
+ # @param sniffer_params [Hash] this is a hash from the +snoopers.json+ file in the +sniffers+ section for the assciated +Snoopy+
6
10
  def initialize(sniffer_params)
7
11
  @before = sniffer_params['lines']['before'].nil? ? 2 : sniffer_params['lines']['before']
8
12
  @pre_before = Register.new @before
@@ -14,10 +18,16 @@ module Snoopit
14
18
  @sniffed = []
15
19
  end
16
20
 
21
+ # Set up the specified notifier parameters
22
+ # @param params [Hash] this is a hash from the +snoopers.json+ file in the +notify+ section for the associated +Sniffer+
17
23
  def setup_notifiers(params)
18
24
  @notifiers = params['notify'] unless params['notify'].nil?
19
25
  end
20
26
 
27
+ # This sniffer tracks through a file until it detects a match
28
+ # @param file [String] file the +sniffer+ is tracking
29
+ # @param line_no [Integer] line number the +sniffer+ is tracking
30
+ # @param line [String] line the +sniffer+ is tracking
21
31
  def track(file, line_no, line)
22
32
  matched = @regexp.match(line) do |m|
23
33
  @sniffed << Detected.new(@comment, @pre_before, @after, line, file, line_no)
@@ -26,6 +36,8 @@ module Snoopit
26
36
  tracking line
27
37
  end
28
38
 
39
+ # This is tracking the lines after the match
40
+ # The +Detected+ instance will let us know when we are finished collecting lines
29
41
  def tracking(line)
30
42
  @sniffed.each do |detected|
31
43
  detected.track line unless detected.finished?
@@ -1,11 +1,19 @@
1
1
  require 'json'
2
2
  module Snoopit
3
+
4
+ # Coordinates activities between the +NotificationManager+ the +Snoopies+ their
5
+ # +Sniffers+ and the +FileTracker+
3
6
  class Snooper
4
7
 
8
+ # +snoopies+ table of +Snoopy+ instances that snoop files
9
+ # +notifier+ +NotificationManager+ manages distributing notifications
10
+ # +file_tracker+
5
11
  attr_accessor :snoopies, :notifier, :file_tracker
6
12
 
7
13
  # Snoopies are the list of available named snoopers
8
- # Snoopers are the current active invocations of selected snoopies
14
+ # @param [boolean #notifications] generate notifications
15
+ # @param [String #db_file] used for file tracking
16
+ # @param [Logger #logger] use the passed in logger
9
17
  def initialize(notifications=true, db_file=nil, logger=nil, log_level=::Logger::INFO)
10
18
  @snoopies = { }
11
19
  @file_tracker = FileTracker.new db_file unless db_file.nil?
@@ -42,19 +50,29 @@ module Snoopit
42
50
  raise ArgumentError.new 'There are no Snoopies in the JSON Snooper ' if @snoopies.size == 0
43
51
  end
44
52
 
53
+ # Load notifiers from the +notifiers+ section
54
+ # @param json_hash [Hash]
45
55
  def load_notifiers(json_hash)
46
56
  @notifier.load_notifier_config json_hash['notifiers'] unless @notifier.nil?
47
57
  end
48
58
 
59
+ # Register the given +notifier+ that inherits from the +Notifier+ class and implements the
60
+ # +notify+ method
61
+ # @params notifier [Notifier]
49
62
  def register_notifier(notifier)
50
63
  @notifier.register notifier
51
64
  end
52
65
 
66
+ # Unegister the given +notifier+ that inherits from the +Notifier+ class and implements the
67
+ # +notify+ method
68
+ # @params notifier [Notifier]
53
69
  def unregister_notifier(notifier)
54
70
  @notifier.unregister notifier
55
71
  end
56
72
 
57
- # Use the snoopies and start snooping
73
+ # Start the snooping files. If a list of names are given then the only the snoopies in the
74
+ # list will be used
75
+ # @param names [Array] - an array of string names
58
76
  def snoop(names=[])
59
77
  snoopers = get_snoopers names
60
78
  snoopers.each do |snoopy|
@@ -68,6 +86,8 @@ module Snoopit
68
86
  snoopers
69
87
  end
70
88
 
89
+ # Get all the snoopers or only the named snoopers
90
+ # @param names [Array] - an array of string names
71
91
  def get_snoopers(names=[])
72
92
  snoopers = []
73
93
  use_names = (names.size == 0 ? false : true)
@@ -81,6 +101,8 @@ module Snoopit
81
101
  snoopers
82
102
  end
83
103
 
104
+ # Have the given +snoopy+ sniff the files in its specified directory
105
+ # @param snoopy [Snoopy] - current active snoopy
84
106
  def snoop_dir(snoopy)
85
107
  Snoopit.logger.debug "Snooping directory: #{snoopy.dir}"
86
108
  get_files(snoopy).each do |file|
@@ -89,6 +111,8 @@ module Snoopit
89
111
  end
90
112
  end
91
113
 
114
+ # Get the files the +snoopy+ must sniff out for information
115
+ # @param snoopy [Snoopy] - current active snoopy
92
116
  def get_files(snoopy)
93
117
  if snoopy.glob?
94
118
  files = get_glob_list snoopy
@@ -98,6 +122,8 @@ module Snoopit
98
122
  files
99
123
  end
100
124
 
125
+ # Get the files that match the glob expression so the +snoopy+ can snoop the files
126
+ # @param snoopy [Snoopy] - current active snoopy
101
127
  def get_glob_list(snoopy)
102
128
  Snoopit.logger.debug "Snooping glob: #{snoopy.glob}"
103
129
  cwd = Dir.getwd
@@ -110,17 +136,24 @@ module Snoopit
110
136
  files
111
137
  end
112
138
 
139
+ # Get the files that match the glob expression so the +snoopy+ can snoop the files
140
+ # @param snoopy [Snoopy] - current active snoopy
113
141
  def get_file_list(snoopy)
114
142
  Snoopit.logger.debug "Snooper directory: #{snoopy.dir}"
115
143
  Dir.entries snoopy.dir
116
144
  end
117
145
 
146
+ # Have the +snoopy+ snoop a file
147
+ # @param snoopy [Snoopy] - current active snoopy
118
148
  def snoop_file(snoopy)
119
149
  raise ArgumentError.new "Could find file #{snoopy.input}" unless File.exist? snoopy.input
120
150
  Snoopit.logger.debug "Snooping file: #{snoopy.input} with snoopy: #{snoopy.name}"
121
151
  sniff_it snoopy, snoopy.input
122
152
  end
123
153
 
154
+ # Have the +snoopy+ sniff a file for
155
+ # @param snoopy [Snoopy] - current active snoopy
156
+ # @param file_name [String] - file to be snooped
124
157
  def sniff_it(snoopy, file_name)
125
158
  Snoopit.logger.debug "Sniffing file: #{file_name} with snoopy: #{snoopy.name}"
126
159
  unless @file_tracker.nil?
@@ -130,12 +163,18 @@ module Snoopit
130
163
  end
131
164
  end
132
165
 
166
+ # Have the +snoopy+ sniff a file that is being tracked
167
+ # @param snoopy [Snoopy] - current active snoopy
168
+ # @param file_name [String] - file to be snooped
133
169
  def file_track_read(snoopy, file_name)
134
170
  @file_tracker.foreach file_name do |line, line_no|
135
171
  snoopy.sniff snoopy.input, line_no, line
136
172
  end
137
173
  end
138
174
 
175
+ # Have the +snoopy+ sniff a file
176
+ # @param snoopy [Snoopy] - current active snoopy
177
+ # @param file_name [String] - file to be snooped
139
178
  def file_read(snoopy, file_name)
140
179
  line_no = 0
141
180
  File.foreach file_name do |line|
@@ -1,8 +1,13 @@
1
1
  module Snoopit
2
+
3
+ # Snoops around the specified file or directory of files
2
4
  class Snoopy
3
5
 
4
6
  attr :name, :input, :output, :dir, :glob, :sniffers
5
7
 
8
+ # This creates a +Snoopy+ which was specified in the +snoopers.json+ file in the +snoopers+ section
9
+ # @param name [String] the name of the snoopy
10
+ # @param params [Hash] this is a hash from the +snoopers.json+ file in the +snoopers+ section for this +Snoopy+
6
11
  def initialize(name, params)
7
12
  @name = name
8
13
  @output = params['output']
@@ -12,21 +17,28 @@ module Snoopit
12
17
  setup_sniffers params
13
18
  end
14
19
 
20
+ # Get the name of the file to snoop if specified
21
+ # @param params [Hash] this is a hash from the +snoopers.json+ file in the +snoopers+ section for this +Snoopy+
15
22
  def setup_input(params)
16
23
  @input = params['snoop']
17
24
  end
18
25
 
26
+ # Get the name of the directory to snoop if specified
27
+ # @param params [Hash] this is a hash from the +snoopers.json+ file in the +snoopers+ section for this +Snoopy+
19
28
  def setup_dir(params)
20
29
  @dir = params['dir']['path']
21
30
  @glob = params['dir']['glob']
22
31
  end
23
32
 
33
+ # Ensure we have something to snoop
24
34
  def input_check?
25
35
  return true unless @input.nil?
26
36
  return true unless @dir.nil?
27
37
  raise ArgumentError.new('Snooper JSON must contain either an input or dir parameter')
28
38
  end
29
39
 
40
+ # Create the specified sniffers
41
+ # @param params [Hash] this is a hash from the +snoopers.json+ file in the +sniffers+ section for this +Snoopy+
30
42
  def setup_sniffers(params)
31
43
  raise ArgumentError.new('Snooper JSON missing sniffers array') if params['sniffers'].nil?
32
44
  @sniffers = []
@@ -43,6 +55,10 @@ module Snoopit
43
55
  ! @glob.nil?
44
56
  end
45
57
 
58
+ # Sniff specified line which is from the named file
59
+ # param file [String] file +Snoopy+ is sniffing
60
+ # param line_no [Integer] line_n0 +Snoopy+ is sniffing
61
+ # param line [String] line +Snoopy+ is sniffing
46
62
  def sniff(file, line_no, line)
47
63
  @sniffers.each do |sniffer|
48
64
  sniffer.track file, line_no, line
@@ -1,3 +1,3 @@
1
1
  module Snoopit
2
- VERSION = '0.0.1'
2
+ VERSION = '0.0.2'
3
3
  end
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ['Robert Birch']
10
10
  spec.email = ['robdbirch@gmail.com']
11
11
  spec.description = %q{Snoops files for specified information via a simple configuration file}
12
- spec.summary = %q{Using regular expressions snoops files or directories for specific information. Sends events and tracks repeated invocations as not to send repeat events}
12
+ spec.summary = %q{Simple tool for monitoring process log files for specified events and then generating basic notifications. This is an extensible and data driven solution. It provides a single location to manage log scraping duties.}
13
13
  spec.homepage = 'https://github.com/robdbirch/snoopit/blob/master/README.md'
14
14
  spec.license = 'MIT'
15
15
 
@@ -18,6 +18,8 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ['lib']
20
20
 
21
+ spec.required_ruby_version = '>=1.9.3', '<3.0'
22
+
21
23
  spec.add_runtime_dependency 'awesome_print', '~> 1.2'
22
24
  spec.add_runtime_dependency 'stomp', '~> 1.3'
23
25
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: snoopit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Birch
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-28 00:00:00.000000000 Z
11
+ date: 2014-06-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: awesome_print
@@ -155,7 +155,10 @@ required_ruby_version: !ruby/object:Gem::Requirement
155
155
  requirements:
156
156
  - - ">="
157
157
  - !ruby/object:Gem::Version
158
- version: '0'
158
+ version: 1.9.3
159
+ - - "<"
160
+ - !ruby/object:Gem::Version
161
+ version: '3.0'
159
162
  required_rubygems_version: !ruby/object:Gem::Requirement
160
163
  requirements:
161
164
  - - ">="
@@ -166,8 +169,9 @@ rubyforge_project:
166
169
  rubygems_version: 2.2.2
167
170
  signing_key:
168
171
  specification_version: 4
169
- summary: Using regular expressions snoops files or directories for specific information.
170
- Sends events and tracks repeated invocations as not to send repeat events
172
+ summary: Simple tool for monitoring process log files for specified events and then
173
+ generating basic notifications. This is an extensible and data driven solution.
174
+ It provides a single location to manage log scraping duties.
171
175
  test_files:
172
176
  - spec/bin/snoopit_spec.rb
173
177
  - spec/file_info_spec.rb
@@ -188,3 +192,4 @@ test_files:
188
192
  - spec/support/snoopies_notifiers.json
189
193
  - spec/support/test_notifier.rb
190
194
  - spec/support/test_notifier_load.rb
195
+ has_rdoc: