indy 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/.autotest +18 -0
  2. data/.gitignore +2 -0
  3. data/.rspec +1 -0
  4. data/History.txt +11 -0
  5. data/README.md +132 -0
  6. data/Rakefile +68 -0
  7. data/autotest/discover.rb +2 -0
  8. data/cucumber.yml +6 -0
  9. data/features/after_time.feature +41 -0
  10. data/features/application.feature +33 -0
  11. data/features/around_time.feature +34 -0
  12. data/features/before_time.feature +34 -0
  13. data/features/custom_pattern.feature +52 -0
  14. data/features/exact_log_level.feature +35 -0
  15. data/features/exact_message.feature +33 -0
  16. data/features/exact_mulitple_fields.feature +38 -0
  17. data/features/exact_time.feature +28 -0
  18. data/features/file.feature +30 -0
  19. data/features/log_levels.feature +40 -0
  20. data/features/message.feature +39 -0
  21. data/features/multiple_fields.feature +38 -0
  22. data/features/step_definitions/find_by.steps.rb +55 -0
  23. data/features/step_definitions/log_file.steps.rb +8 -0
  24. data/features/step_definitions/support/env.rb +1 -0
  25. data/features/step_definitions/support/transforms.rb +28 -0
  26. data/features/step_definitions/test_setup.steps.rb +4 -0
  27. data/features/step_definitions/test_teardown.steps.rb +0 -0
  28. data/features/step_definitions/time.steps.rb +29 -0
  29. data/features/within_time.feature +41 -0
  30. data/indy.gemspec +61 -0
  31. data/lib/indy.rb +5 -0
  32. data/lib/indy/indy.rb +463 -0
  33. data/lib/indy/result_set.rb +8 -0
  34. data/performance/helper.rb +5 -0
  35. data/performance/profile_spec.rb +35 -0
  36. data/spec/data.log +2 -0
  37. data/spec/helper.rb +4 -0
  38. data/spec/indy_spec.rb +212 -0
  39. data/spec/result_set_spec.rb +9 -0
  40. data/spec/search_spec.rb +97 -0
  41. data/spec/time_spec.rb +80 -0
  42. metadata +126 -0
@@ -0,0 +1,18 @@
1
+ begin
2
+ require 'autotest/growl'
3
+ rescue Exception
4
+ puts %{
5
+ Autotest/Autospec can use Growl (growl.info|growlforwindows.com) to assist with reporting errors.
6
+ This would require Growl for the appropriate platform (MAC|Windows) and the Ruby gem 'karl-autotest-growl'
7
+ }
8
+ sleep 4
9
+ end
10
+
11
+ Autotest.add_hook(:initialize) {|at|
12
+ at.add_exception %r{^\.git} # ignore Version Control System
13
+ at.add_exception %r{^./tmp} # ignore temp files, lest autotest will run again, and again...
14
+ at.add_mapping(%r{^lib/.*\.rb$}) {|f, _|
15
+ Dir['spec/**/*.rb']
16
+ }
17
+ nil
18
+ }
@@ -0,0 +1,2 @@
1
+ nbproject
2
+
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,11 @@
1
+ === 0.1.1 / 2011-01-13
2
+
3
+ * Scope search by time (after, before, around, or within)
4
+ * Explicit format string can be provided to parse non-standard log times
5
+ * Reopen (or rewind) source for each #search
6
+ * Source parameter creates an IO object (StringIO, File, or Process)
7
+
8
+ === 0.1.0 / 2010-12-13
9
+
10
+ * Search by exact match or regular expression
11
+ * Search with custom pattern
@@ -0,0 +1,132 @@
1
+ Indy: A Log Archaeology Tool
2
+ ====================================
3
+
4
+ Synopsis
5
+ --------
6
+
7
+ Log files are often searched for particular strings but it does not often treat the logs themselves as data structures. Indy attempts to deliver logs with more powerful features by allowing the ability: to collect segments of a log from particular time; find a particular event; or monitor/reflect on a log to see if a particular event occurred (or not occurred).
8
+
9
+ Installation
10
+ ------------
11
+
12
+ To install Indy use the following command:
13
+
14
+ $ gem install indy
15
+
16
+ (Add `sudo` if you're installing under a POSIX system as root)
17
+
18
+ Usage
19
+ -----
20
+
21
+ ## Require Indy
22
+
23
+ require 'indy'
24
+
25
+ ## Specify your Source
26
+
27
+ ### As a process or command
28
+
29
+ Indy.search( {:cmd => 'ssh user@system "bash --login -c \"cat /var/log/standard.log\" "'} ).for(:severity => 'INFO')
30
+
31
+ ### As a file
32
+
33
+ Indy.search('logpath/output.log').for(:application => 'MyApp')
34
+
35
+ ### As a string
36
+
37
+ log_string = %{
38
+ 2000-09-07 14:07:41 INFO MyApp - Entering application.
39
+ 2000-09-07 14:07:41 INFO MyApp - Exiting application. }
40
+
41
+ Indy.search(log_string).for(:message => 'Entering application')
42
+
43
+ ## Specify your Pattern
44
+
45
+ The default search pattern resembles something you might find:
46
+
47
+ YYYY-MM-DD HH:MM:SS SEVERITY APPLICATION_NAME - MESSAGE
48
+
49
+ ### Default Log Pattern
50
+
51
+ Indy.search(source).for(:severity => 'INFO')
52
+ Indy.search(source).for(:application => 'MyApp', :severity => 'DEBUG')
53
+
54
+ ### Custom Log Pattern
55
+
56
+ If the default pattern is obviously not strong enough for you, brew your own.
57
+ To do so, specify a pattern and each of the match with their symbolic name.
58
+
59
+ # HH:MM:SS SEVERITY APPLICATION#METHOD - MESSAGE
60
+ custom_pattern = "^(\d{2}:\d{2}:\d{2})\s*(INFO|DEBUG|WARN|ERROR)\s*([^#]+)#([^\s]+)\s*-\s*(.+)$"
61
+
62
+ Indy.search(source).with(custom_pattern,:time,:severity,:application,:method,:message).for(:severity => 'INFO', :method => 'allocate')
63
+
64
+ ### Explicit Time Format
65
+
66
+ By default, Indy tries to guess your time format (courtesy of DateTime#parse). If you supply an explicit time format, it will use DateTime#strptime, as well as try to guess.
67
+
68
+ This is required when log data uses a non-standard date format, e.g.: U.S. format 12-31-2000
69
+
70
+ # 12-31-2011 23:59:59
71
+ Indy.new(:time_format => '%m-%d-%Y %H:%M:%S', :source => LOG_FILE).for(:all)
72
+
73
+ ## Match Criteria
74
+
75
+ ### Exact Match
76
+
77
+ Indy.search(source).for(:message => 'Entering Application')
78
+ Indy.search(source).for(:severity => 'INFO')
79
+
80
+ ### Exact Match with multiple parameters
81
+
82
+ Indy.search(source).for(:message => 'Entering Application', :application => 'MyApp')
83
+ Indy.search(source).for(:severity => 'INFO', :application => 'MyApp')
84
+
85
+ ### Time Scope
86
+
87
+ Indy.search(source).after(:time => '2011-01-13 13:40:00').for(:all)
88
+ Indy.search(source).before(:time => '2010-12-31 23:59:59').for(:all)
89
+ Indy.search(source).around(:time => '2011-01-01 00:00:00', :span => 2).for(:all) # 2 minutes around New Year's Eve
90
+ Indy.search(source).within(:time => ['2011-01-01 00:00:00','2011-02-01 00:00:00']).for(:severity => 'ERROR', :application => 'MyApp')
91
+
92
+ ### Partial Match
93
+
94
+ Indy.search(source).like(:message => 'Memory')
95
+
96
+ ### Partial Match with multiple parameters
97
+
98
+ Indy.search(source).like(:severity => '(?:INFO|DEBUG)', :message => 'Memory')
99
+
100
+ ## Process the Results
101
+
102
+ entries = Indy.search(source).for(:message => 'Entering Application')
103
+
104
+ Indy.search(source).for(:message => 'Entering Application').each do |entry|
105
+ puts entry
106
+ end
107
+
108
+ LICENSE
109
+ -------
110
+
111
+ (The MIT License)
112
+
113
+ Copyright (c) 2010 Franklin Webber
114
+
115
+ Permission is hereby granted, free of charge, to any person obtaining
116
+ a copy of this software and associated documentation files (the
117
+ 'Software'), to deal in the Software without restriction, including
118
+ without limitation the rights to use, copy, modify, merge, publish,
119
+ distribute, sublicense, and/or sell copies of the Software, and to
120
+ permit persons to whom the Software is furnished to do so, subject to
121
+ the following conditions:
122
+
123
+ The above copyright notice and this permission notice shall be
124
+ included in all copies or substantial portions of the Software.
125
+
126
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
127
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
128
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
129
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
130
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
131
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
132
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,68 @@
1
+ require 'rake'
2
+ require 'rspec/core'
3
+ require 'rspec/core/rake_task'
4
+ require "cucumber/rake/task"
5
+ require "yard"
6
+ require "city"
7
+
8
+ desc 'Default: run tests'
9
+ task :default => :test
10
+
11
+ desc "Run specs"
12
+ RSpec::Core::RakeTask.new do |t|
13
+ t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
14
+ # Put spec opts in a file named .rspec in root
15
+ end
16
+
17
+ desc "Run performance specs"
18
+ RSpec::Core::RakeTask.new(:perf) do |t|
19
+ t.pattern = "./performance/**/*_spec.rb"
20
+ end
21
+
22
+ desc "Run features"
23
+ Cucumber::Rake::Task.new(:features) do |task|
24
+ task.cucumber_opts = ["features", "-f progress"]
25
+ end
26
+
27
+ desc "Run all reports, specs and features"
28
+ task :all do
29
+ puts "\nProfiling report"
30
+ Rake::Task['perf'].invoke
31
+ puts "\nCode Coverage report"
32
+ Rake::Task['coverage'].invoke
33
+ puts "\nFlog results"
34
+ Rake::Task['flog'].invoke
35
+ puts "\nSpec Tests"
36
+ Rake::Task['spec'].invoke
37
+ puts "\nCucumber features"
38
+ Rake::Task['features'].invoke
39
+ end
40
+
41
+ desc "Run tests"
42
+ task :test do
43
+ Rake::Task['spec'].invoke
44
+ Rake::Task['features'].invoke
45
+ end
46
+
47
+ desc "Flog the code! (*nix only)"
48
+ task :flog do
49
+ system('find lib -name \*.rb | xargs flog')
50
+ end
51
+
52
+ desc "Detailed Flog report! (*nix only)"
53
+ task :flog_detail do
54
+ system('find lib -name \*.rb | xargs flog -d')
55
+ end
56
+
57
+ desc "Generate code coverage"
58
+ RSpec::Core::RakeTask.new(:coverage) do |t|
59
+ t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
60
+ t.rcov = true
61
+ t.rcov_opts = ['--exclude', 'spec', '--exclude', 'gems', '-T']
62
+ end
63
+
64
+
65
+ YARD::Rake::CitydocTask.new do |t|
66
+ t.files = ['features/**/*', 'lib/**/*.rb']
67
+ t.options = ['--private']
68
+ end
@@ -0,0 +1,2 @@
1
+ Autotest.add_discovery { "rspec2" }
2
+
@@ -0,0 +1,6 @@
1
+ ## YAML Template.
2
+ ---
3
+ default: -p base
4
+ base: --format rerun --out rerun.txt --format pretty
5
+ autotest: --format pretty --color
6
+ autotest-all: --format pretty --color
@@ -0,0 +1,41 @@
1
+ @time @after
2
+ Feature: Finding log messages after a particular time
3
+ As an Indy user I am able to find all log messages that have happened after a specified time
4
+
5
+ Background:
6
+ Given the following log:
7
+ """
8
+ 2000-09-07 14:07:41 INFO MyApp - Entering application.
9
+ 2000-09-07 14:07:42 DEBUG MyApp - Focusing application.
10
+ 2000-09-07 14:07:43 DEBUG MyApp - Blurring application.
11
+ 2000-09-07 14:07:44 WARN MyApp - Low on Memory.
12
+ 2000-09-07 14:07:45 ERROR MyApp - Out of Memory.
13
+ 2000-09-07 14:07:46 INFO MyApp - Exiting application.
14
+ """
15
+
16
+
17
+ Scenario: Count of entries after a specified time
18
+ When searching the log for all entries after the time 2000-09-07 14:07:44
19
+ Then I expect to have found 2 log entries
20
+
21
+ Scenario: Count of entries after and including a specified time
22
+ When searching the log for all entries after and including the time 2000-09-07 14:07:44
23
+ Then I expect to have found 3 log entries
24
+
25
+
26
+ Scenario: Count of entries after a specified time
27
+ When searching the log for all entries after the time 2000-09-07 14:07:40
28
+ Then I expect to have found 6 log entries
29
+
30
+
31
+ Scenario: Particular entry after the specified time
32
+ When searching the log for all entries after the time 2000-09-07 14:07:41
33
+ Then I expect the first entry to be:
34
+ """
35
+ 2000-09-07 14:07:42 DEBUG MyApp - Focusing application.
36
+ """
37
+
38
+
39
+ Scenario: No entries after the specified time
40
+ When searching the log for all entries after the time 2000-09-07 14:07:50
41
+ Then I expect to have found no log entries
@@ -0,0 +1,33 @@
1
+ @application
2
+ Feature: Finding log entries by application
3
+ As an Indy user I am able to create an instance and find all logs related to a particular application.
4
+
5
+ Background:
6
+ Given the following log:
7
+ """
8
+ 2000-09-07 14:07:41 INFO MyApp - Entering application.
9
+
10
+ 2000-09-07 14:07:41 INFO MyApp - Exiting application.
11
+ """
12
+
13
+
14
+ Scenario: Count of entries for a specific application
15
+ When searching the log for the application 'MyApp'
16
+ Then I expect to have found 2 log entries
17
+
18
+
19
+ Scenario: Particular entry for a specific application
20
+ When searching the log for the application 'MyApp'
21
+ Then I expect the first entry to be:
22
+ """
23
+ 2000-09-07 14:07:41 INFO MyApp - Entering application.
24
+ """
25
+ Then I expect the last entry to be:
26
+ """
27
+ 2000-09-07 14:07:41 INFO MyApp - Exiting application.
28
+ """
29
+
30
+
31
+ Scenario: No entries for a specific application
32
+ When searching the log for the application 'YourApp'
33
+ Then I expect to have found no log entries
@@ -0,0 +1,34 @@
1
+ @time @around
2
+ Feature: Finding log messages around a particular time
3
+ As an Indy user I am able to find all log messages that have happened around a specified time
4
+
5
+ Background:
6
+ Given the following log:
7
+ """
8
+ 2000-09-07 14:07:41 INFO MyApp - Entering application.
9
+ 2000-09-07 14:17:43 DEBUG MyApp - Focusing application.
10
+ 2000-09-07 14:27:43 DEBUG MyApp - Blurring application.
11
+ 2000-09-07 14:37:43 WARN MyApp - Low on Memory.
12
+ 2000-09-07 14:47:43 ERROR MyApp - Out of Memory.
13
+ 2000-09-07 14:57:46 INFO MyApp - Exiting application.
14
+ """
15
+
16
+ Scenario: Count of entries for a time span around a specified time
17
+ When searching the log for all entries 31 minutes around the time 2000-09-07 14:27:43
18
+ Then I expect to have found 3 log entries
19
+
20
+ Scenario: Count of entries for a time span before a specified time
21
+ When searching the log for all entries 11 minutes before the time 2000-09-07 14:27:43
22
+ Then I expect to have found 1 log entries
23
+
24
+ Scenario: Count of entries for a time span after a specified time
25
+ When searching the log for all entries 31 minutes after the time 2000-09-07 14:27:43
26
+ Then I expect to have found 3 log entries
27
+
28
+ Scenario: Count of entries for a time span before and including a specified time
29
+ When searching the log for all entries 11 minutes before and including the time 2000-09-07 14:47:43
30
+ Then I expect to have found 2 log entries
31
+
32
+ Scenario: Count of entries for a time span after and including a specified time
33
+ When searching the log for all entries 31 minutes after and including the time 2000-09-07 14:17:43
34
+ Then I expect to have found 3 log entries
@@ -0,0 +1,34 @@
1
+ @time @before
2
+ Feature: Finding log messages before a particular time
3
+ As an Indy user I am able to find all log messages that have happened before a specified time
4
+
5
+ Background:
6
+ Given the following log:
7
+ """
8
+ 2000-09-07 14:07:41 INFO MyApp - Entering application.
9
+ 2000-09-07 14:07:42 DEBUG MyApp - Focusing application.
10
+ 2000-09-07 14:07:43 DEBUG MyApp - Blurring application.
11
+ 2000-09-07 14:07:44 WARN MyApp - Low on Memory.
12
+ 2000-09-07 14:07:45 ERROR MyApp - Out of Memory.
13
+ 2000-09-07 14:07:46 INFO MyApp - Exiting application.
14
+ """
15
+
16
+
17
+ Scenario: Count of entries before a specifed time
18
+ When searching the log for all entries before the time 2000-09-07 14:07:44
19
+ Then I expect to have found 3 log entries
20
+
21
+ Scenario: Count of entries before and including a specifed time
22
+ When searching the log for all entries before and including the time 2000-09-07 14:07:44
23
+ Then I expect to have found 4 log entries
24
+
25
+ Scenario: Particular entry before the specified time
26
+ When searching the log for all entries before the time 2000-09-07 14:07:43
27
+ Then I expect the last entry to be:
28
+ """
29
+ 2000-09-07 14:07:42 DEBUG MyApp - Focusing application.
30
+ """
31
+
32
+ Scenario: No entries before the specified time
33
+ When searching the log for all entries before the time 2000-09-07 14:07:40
34
+ Then I expect to have found no log entries
@@ -0,0 +1,52 @@
1
+ @log_level
2
+ Feature: Finding log entries with a custom pattern
3
+ As an Indy user I am able to find all log entries that match my custom log pattern
4
+
5
+ Background:
6
+ Given the following log:
7
+ """
8
+ 14:07:41 INFO MyApp#initialize - Entering application.
9
+ 14:07:42 DEBUG MyApp#panel - Focusing application.
10
+ 14:07:43 DEBUG MyApp#panel - Blurring application.
11
+ 14:07:44 WARN MyApp#allocate - Low on Memory.
12
+ 14:07:45 ERROR MyApp#allocate - Out of Memory.
13
+ 14:07:46 INFO MyApp#exit - Exiting application.
14
+ """
15
+ And the custom pattern (time,severity,application,method,message):
16
+ """
17
+ ^(\d{2}:\d{2}:\d{2})\s*(INFO|DEBUG|WARN|ERROR)\s*([^#]+)#([^\s]+)\s*-\s*(.+)$
18
+ """
19
+
20
+ Scenario: Count of entries at specified log level
21
+ When searching the log for the log severity INFO
22
+ Then I expect to have found 2 log entries
23
+
24
+
25
+ Scenario: Particular entry at the specified log level
26
+ When searching the log for the log severity INFO
27
+ Then I expect the first entry to be:
28
+ """
29
+ 14:07:41 INFO MyApp#initialize - Entering application.
30
+ """
31
+ And I expect the last entry to be:
32
+ """
33
+ 14:07:46 INFO MyApp#exit - Exiting application.
34
+ """
35
+
36
+
37
+ Scenario: No entries at the specified log level
38
+ When searching the log for the log severity SEVERE
39
+ Then I expect to have found no log entries
40
+
41
+
42
+ Scenario: Find entries at the custom field
43
+ When searching the log for the exact match of custom field method "allocate"
44
+ Then I expect to have found 2 log entries
45
+ Then I expect the first entry to be:
46
+ """
47
+ 14:07:44 WARN MyApp#allocate - Low on Memory.
48
+ """
49
+ And I expect the last entry to be:
50
+ """
51
+ 14:07:45 ERROR MyApp#allocate - Out of Memory.
52
+ """