log_master 0.1.1

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.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Zachary Belzer
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,18 @@
1
+ = log_master
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but
13
+ bump version in a commit by itself I can ignore when I pull)
14
+ * Send me a pull request. Bonus points for topic branches.
15
+
16
+ == Copyright
17
+
18
+ Copyright (c) 2009 Zachary Belzer. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,67 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + "/lib")
5
+ require 'log_master/rake/log_task'
6
+
7
+ Dir['tasks/*.rake'].each { |rake| load rake }
8
+
9
+ begin
10
+ require 'jeweler'
11
+ Jeweler::Tasks.new do |gem|
12
+ gem.name = "log_master"
13
+ gem.summary = %Q{Creates and emails a simple report for a set of log (or text) files. Useful for aggretating small log files.}
14
+ gem.description = %Q{Creates and emails a simple report for a set of log (or text) files. Useful for aggretating small log files.}
15
+ gem.email = "zbelzer@gmail.com"
16
+ gem.homepage = "http://github.com/moneypools/log_master"
17
+ gem.authors = ["Zachary Belzer"]
18
+ gem.add_dependency "actionmailer"
19
+ gem.add_development_dependency "rspec"
20
+ gem.add_development_dependency "email_spec", " >= 0.3.5"
21
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
22
+ end
23
+ Jeweler::GemcutterTasks.new
24
+ rescue LoadError
25
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
26
+ end
27
+
28
+ require 'spec/rake/spectask'
29
+ Spec::Rake::SpecTask.new(:spec) do |spec|
30
+ spec.libs << 'lib' << 'spec'
31
+ spec.spec_files = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
35
+ spec.libs << 'lib' << 'spec'
36
+ spec.pattern = 'spec/**/*_spec.rb'
37
+ spec.rcov = true
38
+ end
39
+
40
+ task :spec => :check_dependencies
41
+
42
+ begin
43
+ require 'cucumber/rake/task'
44
+ Cucumber::Rake::Task.new(:features)
45
+
46
+ task :features => :check_dependencies
47
+ rescue LoadError
48
+ task :features do
49
+ abort "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
50
+ end
51
+ end
52
+
53
+ task :default => :spec
54
+
55
+ require 'rake/rdoctask'
56
+ Rake::RDocTask.new do |rdoc|
57
+ if File.exist?('VERSION')
58
+ version = File.read('VERSION')
59
+ else
60
+ version = ""
61
+ end
62
+
63
+ rdoc.rdoc_dir = 'rdoc'
64
+ rdoc.title = "log_master #{version}"
65
+ rdoc.rdoc_files.include('README*')
66
+ rdoc.rdoc_files.include('lib/**/*.rb')
67
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
@@ -0,0 +1,5 @@
1
+ Feature: Sending emails
2
+ Scenario: LogMaster sends an email to
3
+ Given I have configured LogMaster like:
4
+ When I run LogMaster on a file with errors
5
+ Then I should
@@ -0,0 +1,121 @@
1
+ # Commonly used email steps
2
+ #
3
+ # To add your own steps make a custom_email_steps.rb
4
+ # The provided methods are:
5
+ #
6
+ # last_email_address
7
+ # reset_mailer
8
+ # open_last_email
9
+ # visit_in_email
10
+ # unread_emails_for
11
+ # mailbox_for
12
+ # current_email
13
+ # open_email
14
+ # read_emails_for
15
+ # find_email
16
+ #
17
+ # General form for email scenarios are:
18
+ # - clear the email queue (done automatically by email_spec)
19
+ # - execute steps that sends an email
20
+ # - check the user received an/no/[0-9] emails
21
+ # - open the email
22
+ # - inspect the email contents
23
+ # - interact with the email (e.g. click links)
24
+ #
25
+ # The Cucumber steps below are setup in this order.
26
+
27
+ module EmailHelpers
28
+ def current_email_address
29
+ # Replace with your a way to find your current email. e.g @current_user.email
30
+ # last_email_address will return the last email address used by email spec to find an email.
31
+ # Note that last_email_address will be reset after each Scenario.
32
+ last_email_address || "example@example.com"
33
+ end
34
+ end
35
+
36
+ World(EmailHelpers)
37
+
38
+ #
39
+ # Reset the e-mail queue within a scenario.
40
+ # This is done automatically before each scenario.
41
+ #
42
+
43
+ Given /^(?:a clear email queue|no emails have been sent)$/ do
44
+ reset_mailer
45
+ end
46
+
47
+ #
48
+ # Check how many emails have been sent/received
49
+ #
50
+
51
+ Then /^(?:I|they|"([^"]*?)") should receive (an|no|\d+) emails?$/ do |address, amount|
52
+ unread_emails_for(address).size.should == parse_email_count(amount)
53
+ end
54
+
55
+ Then /^(?:I|they|"([^"]*?)") should have (an|no|\d+) emails?$/ do |address, amount|
56
+ mailbox_for(address).size.should == parse_email_count(amount)
57
+ end
58
+
59
+ # DEPRECATED
60
+ # The following methods are left in for backwards compatibility and
61
+ # should be removed by version 0.4.0
62
+ Then /^(?:I|they|"([^"]*?)") should not receive an email$/ do |address|
63
+ email_spec_deprecate "The step 'I/they/[email] should not receive an email' is no longer supported.
64
+ Please use 'I/they/[email] should receive no emails' instead."
65
+ unread_emails_for(address).size.should == 0
66
+ end
67
+
68
+ #
69
+ # Accessing emails
70
+ #
71
+
72
+ # Opens the most recently received email
73
+ When /^(?:I|they|"([^"]*?)") opens? the email$/ do |address|
74
+ open_email(address)
75
+ end
76
+
77
+ When /^(?:I|they|"([^"]*?)") opens? the email with subject "([^"]*?)"$/ do |address, subject|
78
+ open_email(address, :with_subject => subject)
79
+ end
80
+
81
+ When /^(?:I|they|"([^"]*?)") opens? the email with text "([^"]*?)"$/ do |address, text|
82
+ open_email(address, :with_text => text)
83
+ end
84
+
85
+ #
86
+ # Inspect the Email Contents
87
+ #
88
+
89
+ Then /^(?:I|they) should see "([^"]*?)" in the email subject$/ do |text|
90
+ current_email.should have_subject(Regexp.new(text))
91
+ end
92
+
93
+ Then /^(?:I|they) should see "([^"]*?)" in the email body$/ do |text|
94
+ current_email.body.should =~ Regexp.new(text)
95
+ end
96
+
97
+ # DEPRECATED
98
+ # The following methods are left in for backwards compatibility and
99
+ # should be removed by version 0.4.0.
100
+ Then /^(?:I|they) should see "([^"]*?)" in the subject$/ do |text|
101
+ email_spec_deprecate "The step 'I/they should see [text] in the subject' is no longer supported.
102
+ Please use 'I/they should see [text] in the email subject' instead."
103
+ current_email.should have_subject(Regexp.new(text))
104
+ end
105
+ Then /^(?:I|they) should see "([^"]*?)" in the email$/ do |text|
106
+ email_spec_deprecate "The step 'I/they should see [text] in the email' is no longer supported.
107
+ Please use 'I/they should see [text] in the email body' instead."
108
+ current_email.body.should =~ Regexp.new(text)
109
+ end
110
+
111
+ #
112
+ # Interact with Email Contents
113
+ #
114
+
115
+ When /^(?:I|they) follow "([^"]*?)" in the email$/ do |link|
116
+ visit_in_email(link)
117
+ end
118
+
119
+ When /^(?:I|they) click the first link in the email$/ do
120
+ click_first_link_in_email
121
+ end
File without changes
@@ -0,0 +1,6 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
2
+ require 'log_master'
3
+ require 'email-spec'
4
+
5
+ require 'spec/expectations'
6
+ require 'email_spec/cucumber'
data/init.rb ADDED
File without changes
@@ -0,0 +1,39 @@
1
+ require 'singleton'
2
+
3
+ module LogMaster
4
+ class Configuration
5
+ include Singleton
6
+
7
+ attr_accessor :title, :reporting
8
+
9
+ # These are options that directly affect the email
10
+ attr_accessor :recipients, :from, :reply_to
11
+
12
+ @@configured = false
13
+
14
+ def initialize
15
+ reset
16
+ end
17
+
18
+ def reset
19
+ @title = "No Title"
20
+ @reporting = {}
21
+
22
+ @@configured = false
23
+ end
24
+
25
+ def self.configure
26
+ yield instance
27
+ @@configured = true
28
+ end
29
+
30
+ def self.configured?
31
+ @@configured === true
32
+ end
33
+
34
+ # For testing purposes
35
+ def reset_configured_status!
36
+ @@configured = false
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,43 @@
1
+ require File.dirname(__FILE__) + "/../log_master"
2
+
3
+ module LogMaster
4
+ class Director
5
+
6
+ attr_accessor :reports, :logs
7
+
8
+ def initialize(files)
9
+ raise "LogMaster has not yet been configured" unless Configuration.configured?
10
+
11
+ create_log_files(files)
12
+ @reports = {}
13
+ end
14
+
15
+ def run
16
+ aggregate!
17
+ send_email
18
+ end
19
+
20
+ def aggregate!
21
+ logs.each do |l|
22
+ l.analyze.each do |name, value|
23
+ @reports[name] ||= 0
24
+ @reports[name] += value
25
+ end
26
+ end
27
+ end
28
+
29
+ def status
30
+ @reports[:fatal] == 0 && @reports[:error] == 0
31
+ end
32
+
33
+ def send_email
34
+ Notifier.deliver_update_notification(status, @reports, @logs)
35
+ end
36
+
37
+ private
38
+ def create_log_files(files)
39
+ files = files.respond_to?(:each) ? files : [files]
40
+ @logs = files.map { |f| LogFile.new(f, Configuration.instance.reporting) }
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,39 @@
1
+ module LogMaster
2
+ class LogFile
3
+ attr_accessor :file_path
4
+
5
+ def initialize(file_path, reporting_configuration={})
6
+ @file_path = file_path
7
+ @reporting_configuration = reporting_configuration
8
+ end
9
+
10
+ def analyze
11
+ reports = @reporting_configuration.keys.inject({}) {|h,l| h.merge(l => 0)}
12
+
13
+ if log_file_exists?
14
+ @reporting_configuration.each do |report_name, report_regexp|
15
+ reports[report_name] = body.scan(report_regexp).size
16
+ end
17
+ end
18
+
19
+ reports
20
+ end
21
+
22
+ def file_name
23
+ File.basename(file_path)
24
+ end
25
+
26
+ def valid?
27
+ log_file_exists?
28
+ end
29
+
30
+ def body
31
+ log_file_exists? ? File.read(file_path) : "File Missing"
32
+ end
33
+
34
+ private
35
+ def log_file_exists?
36
+ File.exists?(file_path)
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,37 @@
1
+ module LogMaster
2
+ class Notifier < ActionMailer::Base
3
+ helper_method :stylize_output
4
+
5
+ def update_notification(status, reports, logs)
6
+ @status = status
7
+ @configuration = Configuration.instance
8
+
9
+ subject create_subject
10
+ recipients determine_recipients
11
+ reply_to @configuration.reply_to || @configuration.from
12
+ from @configuration.from
13
+ content_type "text/html"
14
+ sent_on Time.now
15
+ body :title => @configuration.title, :logs => logs, :reports => reports
16
+ end
17
+
18
+
19
+ def create_subject
20
+ @configuration.title + (@status ? " SUCCESSFUL" : " FAILED")
21
+ end
22
+
23
+ def determine_recipients
24
+ @status ? @configuration.recipients[:success] : @configuration.recipients[:failure]
25
+ end
26
+
27
+ protected
28
+
29
+ def stylize_output(line)
30
+ @configuration.reporting.each do |name, regexp|
31
+ return name if line =~ regexp
32
+ end
33
+
34
+ "info"
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,20 @@
1
+ require 'log_master'
2
+
3
+ module LogMaster
4
+ module Rake
5
+ class LogTask < ::Rake::Task
6
+ attr_accessor :log_pattern
7
+
8
+ protected
9
+ def execute(*args)
10
+ super
11
+ run_log_master
12
+ end
13
+
14
+ def run_log_master
15
+ files = Dir[log_pattern]
16
+ LogMaster::Director.new(files).run
17
+ end
18
+ end
19
+ end
20
+ end
data/lib/log_master.rb ADDED
@@ -0,0 +1,14 @@
1
+ begin
2
+ require 'actionmailer'
3
+ rescue LoadError
4
+ warn 'To use LogMaster you need the actionmailer gem:'
5
+ warn '$ sudo gem install actionmailer'
6
+ raise
7
+ end
8
+
9
+ ActionMailer::Base.template_root = File.dirname(__FILE__) + "/templates"
10
+
11
+ require 'log_master/configuration'
12
+ require 'log_master/director'
13
+ require 'log_master/log_file'
14
+ require 'log_master/notifier'
@@ -0,0 +1,59 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%= @subject %></title>
5
+ <style type="text/css">
6
+ .pre {
7
+ white-space: pre;
8
+ font-family: monospace;
9
+ font-size: small;
10
+ }
11
+
12
+ .info {
13
+ color: black;
14
+ }
15
+
16
+ .fatal {
17
+ color: red;
18
+ }
19
+
20
+ .error {
21
+ color: red;
22
+ }
23
+
24
+ .warn {
25
+ color: blue;
26
+ }
27
+
28
+ .log {
29
+ font-family: monospace;
30
+ font-weight: bold;
31
+ margin-bottom: 3px;
32
+ }
33
+ </style>
34
+ </head>
35
+ <body>
36
+ <h2>
37
+ <%= @title %>
38
+ </h2>
39
+ <p>
40
+ <% @reports.each do |name, count| %>
41
+ <strong class="<%= name %>"><%= name.to_s.titleize %>: </strong><%= count %><br />
42
+ <% end %>
43
+ </p>
44
+
45
+ <hr />
46
+
47
+ <% @logs.each do |log| -%>
48
+ <div class="log"><%= log.file_name %></div>
49
+
50
+ <div class="pre">
51
+ <% log.body.each do |line| -%>
52
+ <span class="<%= stylize_output(line) %>"><%= line.chomp -%></span>
53
+ <% end -%>
54
+ </div>
55
+
56
+ <hr />
57
+ <% end -%>
58
+ </body>
59
+ </html>
@@ -0,0 +1,81 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{log_master}
8
+ s.version = "0.1.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Zachary Belzer"]
12
+ s.date = %q{2009-12-02}
13
+ s.description = %q{Creates and emails a simple report for a set of log (or text) files. Useful for aggretating small log files.}
14
+ s.email = %q{zbelzer@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "features/log_master.feature",
27
+ "features/step_definitions/email_steps.rb",
28
+ "features/step_definitions/log_master_steps.rb",
29
+ "features/support/env.rb",
30
+ "init.rb",
31
+ "lib/log_master.rb",
32
+ "lib/log_master/configuration.rb",
33
+ "lib/log_master/director.rb",
34
+ "lib/log_master/log_file.rb",
35
+ "lib/log_master/notifier.rb",
36
+ "lib/log_master/rake/log_task.rb",
37
+ "lib/templates/log_master/notifier/update_notification.html.erb",
38
+ "log_master.gemspec",
39
+ "spec/configuration_spec.rb",
40
+ "spec/director_spec.rb",
41
+ "spec/fixtures/empty_log.log",
42
+ "spec/fixtures/log_with_errors.log",
43
+ "spec/fixtures/log_without_errors.log",
44
+ "spec/log_file_spec.rb",
45
+ "spec/notification_spec.rb",
46
+ "spec/spec_helper.rb",
47
+ "tasks/log_master.rake"
48
+ ]
49
+ s.homepage = %q{http://github.com/moneypools/log_master}
50
+ s.rdoc_options = ["--charset=UTF-8"]
51
+ s.require_paths = ["lib"]
52
+ s.rubygems_version = %q{1.3.5}
53
+ s.summary = %q{Creates and emails a simple report for a set of log (or text) files. Useful for aggretating small log files.}
54
+ s.test_files = [
55
+ "spec/configuration_spec.rb",
56
+ "spec/director_spec.rb",
57
+ "spec/log_file_spec.rb",
58
+ "spec/notification_spec.rb",
59
+ "spec/spec_helper.rb"
60
+ ]
61
+
62
+ if s.respond_to? :specification_version then
63
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
64
+ s.specification_version = 3
65
+
66
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
67
+ s.add_runtime_dependency(%q<actionmailer>, [">= 0"])
68
+ s.add_development_dependency(%q<rspec>, [">= 0"])
69
+ s.add_development_dependency(%q<email_spec>, [">= 0.3.5"])
70
+ else
71
+ s.add_dependency(%q<actionmailer>, [">= 0"])
72
+ s.add_dependency(%q<rspec>, [">= 0"])
73
+ s.add_dependency(%q<email_spec>, [">= 0.3.5"])
74
+ end
75
+ else
76
+ s.add_dependency(%q<actionmailer>, [">= 0"])
77
+ s.add_dependency(%q<rspec>, [">= 0"])
78
+ s.add_dependency(%q<email_spec>, [">= 0.3.5"])
79
+ end
80
+ end
81
+
@@ -0,0 +1,18 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ module LogMaster
4
+ describe "Configuration" do
5
+
6
+ describe "configured?" do
7
+ it "should be false if .confgure has not been called" do
8
+ Configuration.instance.reset_configured_status!
9
+ Configuration.should_not be_configured
10
+ end
11
+
12
+ it "should be false if .confgure has not been called" do
13
+ Configuration.configure {|c|}
14
+ Configuration.should be_configured
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,27 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ module LogMaster
4
+ describe "Director" do
5
+ before do
6
+ @files = %w(log_without_errors.log log_with_errors.log).map {|f| log_file_path(f) }
7
+ end
8
+
9
+ it "should create a LogFile for each file given" do
10
+ Director.new(@files).logs.size.should == @files.size
11
+ end
12
+
13
+ it "should raise error if not configured" do
14
+ Configuration.instance.reset_configured_status!
15
+ lambda {Director.new(@files)}.should raise_error
16
+ Configuration.configure {|c|} # Reset configured state
17
+ end
18
+
19
+ describe "aggregate" do
20
+ it "should add the specs for all reports" do
21
+ log_master = Director.new(@files)
22
+ log_master.aggregate!
23
+ log_master.reports[:error].should == 2
24
+ end
25
+ end
26
+ end
27
+ end
File without changes
@@ -0,0 +1,6 @@
1
+ Not an error
2
+ Another completely fine line
3
+ ERROR
4
+ Back to goodness
5
+ There's an ERROR again
6
+ FATAL Oh Noes!
@@ -0,0 +1,4 @@
1
+ Line one
2
+ Line two
3
+ Line Three
4
+ Nothing to see here...
@@ -0,0 +1,44 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ module LogMaster
4
+ describe "LogFile" do
5
+ before(:all) do
6
+ @log_with_errors_path = log_file_path("log_with_errors.log")
7
+ @log_without_errors_path = log_file_path("log_without_errors.log")
8
+ end
9
+
10
+ describe "analyze!" do
11
+ it "should count the number of errors in the file according to provided regexp" do
12
+ log_file = LogFile.new(@log_with_errors_path, {:error => /ERROR/ })
13
+ log_file.analyze[:error].should == 2
14
+ end
15
+
16
+ it "should find no errors in provided file" do
17
+ log_file = LogFile.new(@log_without_errors_path, {:error => /ERROR/ })
18
+ log_file.analyze[:error].should be_zero
19
+ end
20
+ end
21
+
22
+ describe "valid?" do
23
+ it "should be true if file present and no other conditions on validity" do
24
+ log_file = LogFile.new(@log_without_errors_path)
25
+ log_file.should be_valid
26
+ end
27
+
28
+ it "should be false when file is absent" do
29
+ log_file = LogFile.new('log_that_does_not_exist.log')
30
+ log_file.should_not be_valid
31
+ end
32
+ end
33
+
34
+ describe "body" do
35
+ it "should be 'File Missing' if file does not exist" do
36
+ LogFile.new('log_that_does_not_exist.log').body.should == "File Missing"
37
+ end
38
+
39
+ it "should be the log's data" do
40
+ LogFile.new(@log_without_errors_path).body.should == File.read(FIXTURES_DIR + "/log_without_errors.log")
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,69 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ module LogMaster
4
+ describe "Notification email" do
5
+ it "should be set to be delivered to success@example.com when successful" do
6
+ email = Notifier.deliver_update_notification(true, {}, [])
7
+ email.should deliver_to("success@example.com")
8
+ end
9
+
10
+ it "should be set to be delivered to success@example.com when failure" do
11
+ email = Notifier.deliver_update_notification(false, {}, [])
12
+ email.should deliver_to("failure@example.com")
13
+ end
14
+
15
+ describe "body" do
16
+ it "should contain the title" do
17
+ email = Notifier.deliver_update_notification(true, {}, [])
18
+ email.should have_body_text(Configuration.instance.title)
19
+ end
20
+
21
+ it "should contain the aggregate report" do
22
+ email = Notifier.deliver_update_notification(true, {:error => 1, :warn => 2, :fatal => 0}, [])
23
+ email.should have_body_text(/Error:.*1/)
24
+ email.should have_body_text(/Warn:.*2/)
25
+ email.should have_body_text(/Fatal:.*0/)
26
+ end
27
+
28
+ it "should contain each of the provided logfiles" do
29
+ log_1 = LogFile.new('log_without_errors.log')
30
+ log_2 = LogFile.new('log_with_errors.log')
31
+ email = Notifier.deliver_update_notification(true, {}, [log_1, log_2])
32
+
33
+ log_1.body.each do |line|
34
+ email.should have_body_text(line.chomp)
35
+ end
36
+
37
+ log_2.body.each do |line|
38
+ email.should have_body_text(line.chomp)
39
+ end
40
+ end
41
+
42
+ it "should warn that the file does not exist" do
43
+ log_file = LogFile.new('fake_log.log')
44
+ email = Notifier.deliver_update_notification(true, {}, [log_file])
45
+ email.should have_body_text("File Missing")
46
+ end
47
+
48
+ it "should wrap lines in their respective classes" do
49
+ log_file = LogFile.new(log_file_path('log_with_errors.log'), {:warn => /WARN/, :error => /ERROR/, :fatal => /FATAL/})
50
+ email = Notifier.deliver_update_notification(true, {}, [log_file])
51
+ email.should have_body_text(/class="error".*ERROR/)
52
+ email.should have_body_text(/class="info".*Not an error/)
53
+ email.should have_body_text(/class="fatal".*FATAL Oh Noes!/)
54
+ end
55
+ end
56
+
57
+ describe "subject" do
58
+ it "should contain successful message when successful" do
59
+ email = Notifier.deliver_update_notification(true, {}, [])
60
+ email.should have_subject(/SUCCESSFUL/)
61
+ end
62
+
63
+ it "should contain failure message when failure" do
64
+ email = Notifier.deliver_update_notification(false, {}, [])
65
+ email.should have_subject(/FAILED/)
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,32 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'rubygems'
4
+ require 'log_master'
5
+ require 'spec'
6
+ require 'spec/autorun'
7
+
8
+ require "email_spec"
9
+ require "email_spec/helpers"
10
+ require "email_spec/matchers"
11
+
12
+ require File.dirname(__FILE__) + '/../lib/log_master'
13
+
14
+ FIXTURES_DIR = File.dirname(__FILE__) + "/fixtures"
15
+
16
+ ActionMailer::Base.delivery_method = :test
17
+ # ActionMailer::Base.logger = Logger.new('test.log')
18
+
19
+ LogMaster::Configuration.configure do |config|
20
+ config.title = "Testing LogMaster"
21
+ config.reporting = {:warn => /WARN/, :error => /ERROR/, :fatal => /FATAL/}
22
+ config.recipients = {:success => "success@example.com", :failure => "failure@example.com"}
23
+ end
24
+
25
+ Spec::Runner.configure do |config|
26
+ config.include(EmailSpec::Helpers)
27
+ config.include(EmailSpec::Matchers)
28
+ end
29
+
30
+ def log_file_path(path)
31
+ File.join(FIXTURES_DIR, path)
32
+ end
@@ -0,0 +1,18 @@
1
+ namespace :log_master do
2
+ task :configure do
3
+ require 'action_mailer'
4
+ ActionMailer::Base.delivery_method = :sendmail
5
+
6
+ LogMaster::Configuration.configure do |config|
7
+ config.title = "This is a sample email"
8
+ config.recipients = {:success => 'localhost', :failure => 'localhost' }
9
+ config.reporting = {:warn => /WARN/, :error => /ERROR/, :fatal => /FATAL/}
10
+ config.reply_to = "sender@example.com"
11
+ end
12
+ end
13
+
14
+ desc "Runs log master on specified log file"
15
+ LogMaster::Rake::LogTask.define_task "test" => :configure do |t|
16
+ t.log_pattern = ENV['log_pattern'] || "spec/fixtures/log_with_errors.log"
17
+ end
18
+ end
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: log_master
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Zachary Belzer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-12-02 00:00:00 -06:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: actionmailer
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: email_spec
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 0.3.5
44
+ version:
45
+ description: Creates and emails a simple report for a set of log (or text) files. Useful for aggretating small log files.
46
+ email: zbelzer@gmail.com
47
+ executables: []
48
+
49
+ extensions: []
50
+
51
+ extra_rdoc_files:
52
+ - LICENSE
53
+ - README.rdoc
54
+ files:
55
+ - .document
56
+ - .gitignore
57
+ - LICENSE
58
+ - README.rdoc
59
+ - Rakefile
60
+ - VERSION
61
+ - features/log_master.feature
62
+ - features/step_definitions/email_steps.rb
63
+ - features/step_definitions/log_master_steps.rb
64
+ - features/support/env.rb
65
+ - init.rb
66
+ - lib/log_master.rb
67
+ - lib/log_master/configuration.rb
68
+ - lib/log_master/director.rb
69
+ - lib/log_master/log_file.rb
70
+ - lib/log_master/notifier.rb
71
+ - lib/log_master/rake/log_task.rb
72
+ - lib/templates/log_master/notifier/update_notification.html.erb
73
+ - log_master.gemspec
74
+ - spec/configuration_spec.rb
75
+ - spec/director_spec.rb
76
+ - spec/fixtures/empty_log.log
77
+ - spec/fixtures/log_with_errors.log
78
+ - spec/fixtures/log_without_errors.log
79
+ - spec/log_file_spec.rb
80
+ - spec/notification_spec.rb
81
+ - spec/spec_helper.rb
82
+ - tasks/log_master.rake
83
+ has_rdoc: true
84
+ homepage: http://github.com/moneypools/log_master
85
+ licenses: []
86
+
87
+ post_install_message:
88
+ rdoc_options:
89
+ - --charset=UTF-8
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: "0"
97
+ version:
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: "0"
103
+ version:
104
+ requirements: []
105
+
106
+ rubyforge_project:
107
+ rubygems_version: 1.3.5
108
+ signing_key:
109
+ specification_version: 3
110
+ summary: Creates and emails a simple report for a set of log (or text) files. Useful for aggretating small log files.
111
+ test_files:
112
+ - spec/configuration_spec.rb
113
+ - spec/director_spec.rb
114
+ - spec/log_file_spec.rb
115
+ - spec/notification_spec.rb
116
+ - spec/spec_helper.rb