sawmill 0.0.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.
Files changed (38) hide show
  1. data/History.rdoc +3 -0
  2. data/README.rdoc +81 -0
  3. data/Rakefile +147 -0
  4. data/lib/sawmill/entry.rb +307 -0
  5. data/lib/sawmill/entry_classifier.rb +75 -0
  6. data/lib/sawmill/entry_processor/build_records.rb +157 -0
  7. data/lib/sawmill/entry_processor/conditionals.rb +444 -0
  8. data/lib/sawmill/entry_processor/filter_basic_fields.rb +145 -0
  9. data/lib/sawmill/entry_processor/format.rb +228 -0
  10. data/lib/sawmill/entry_processor/simple_queue.rb +116 -0
  11. data/lib/sawmill/entry_processor.rb +158 -0
  12. data/lib/sawmill/errors.rb +66 -0
  13. data/lib/sawmill/level.rb +264 -0
  14. data/lib/sawmill/log_record_middleware.rb +93 -0
  15. data/lib/sawmill/logger.rb +373 -0
  16. data/lib/sawmill/parser.rb +181 -0
  17. data/lib/sawmill/record.rb +255 -0
  18. data/lib/sawmill/record_processor/conditionals.rb +330 -0
  19. data/lib/sawmill/record_processor/decompose.rb +75 -0
  20. data/lib/sawmill/record_processor/filter_by_attributes.rb +87 -0
  21. data/lib/sawmill/record_processor/filter_by_record_id.rb +77 -0
  22. data/lib/sawmill/record_processor/format.rb +88 -0
  23. data/lib/sawmill/record_processor/simple_queue.rb +117 -0
  24. data/lib/sawmill/record_processor.rb +137 -0
  25. data/lib/sawmill/rotater/base.rb +90 -0
  26. data/lib/sawmill/rotater/date_based_log_file.rb +145 -0
  27. data/lib/sawmill/rotater/shifting_log_file.rb +166 -0
  28. data/lib/sawmill/rotater.rb +236 -0
  29. data/lib/sawmill/util/queue.rb +138 -0
  30. data/lib/sawmill/version.rb +47 -0
  31. data/lib/sawmill.rb +78 -0
  32. data/tests/tc_entry_processors.rb +138 -0
  33. data/tests/tc_formatter_parser.rb +144 -0
  34. data/tests/tc_levels.rb +118 -0
  35. data/tests/tc_logger.rb +315 -0
  36. data/tests/tc_record_processors.rb +117 -0
  37. data/tests/tc_records.rb +206 -0
  38. metadata +116 -0
@@ -0,0 +1,47 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # Sawmill version
4
+ #
5
+ # -----------------------------------------------------------------------------
6
+ # Copyright 2009 Daniel Azuma
7
+ #
8
+ # All rights reserved.
9
+ #
10
+ # Redistribution and use in source and binary forms, with or without
11
+ # modification, are permitted provided that the following conditions are met:
12
+ #
13
+ # * Redistributions of source code must retain the above copyright notice,
14
+ # this list of conditions and the following disclaimer.
15
+ # * Redistributions in binary form must reproduce the above copyright notice,
16
+ # this list of conditions and the following disclaimer in the documentation
17
+ # and/or other materials provided with the distribution.
18
+ # * Neither the name of the copyright holder, nor the names of any other
19
+ # contributors to this software, may be used to endorse or promote products
20
+ # derived from this software without specific prior written permission.
21
+ #
22
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
+ # POSSIBILITY OF SUCH DAMAGE.
33
+ # -----------------------------------------------------------------------------
34
+ ;
35
+
36
+
37
+ # This module is a namespace for Sawmill.
38
+
39
+ module Sawmill
40
+
41
+ # Current gem version, as a frozen string.
42
+ VERSION_STRING = '0.0.1'.freeze
43
+
44
+ # Current gem version, as a Versionomy::Value.
45
+ VERSION = ::Versionomy.parse(VERSION_STRING, :standard)
46
+
47
+ end
data/lib/sawmill.rb ADDED
@@ -0,0 +1,78 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # Sawmill entry point
4
+ #
5
+ # -----------------------------------------------------------------------------
6
+ # Copyright 2009 Daniel Azuma
7
+ #
8
+ # All rights reserved.
9
+ #
10
+ # Redistribution and use in source and binary forms, with or without
11
+ # modification, are permitted provided that the following conditions are met:
12
+ #
13
+ # * Redistributions of source code must retain the above copyright notice,
14
+ # this list of conditions and the following disclaimer.
15
+ # * Redistributions in binary form must reproduce the above copyright notice,
16
+ # this list of conditions and the following disclaimer in the documentation
17
+ # and/or other materials provided with the distribution.
18
+ # * Neither the name of the copyright holder, nor the names of any other
19
+ # contributors to this software, may be used to endorse or promote products
20
+ # derived from this software without specific prior written permission.
21
+ #
22
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
+ # POSSIBILITY OF SUCH DAMAGE.
33
+ # -----------------------------------------------------------------------------
34
+ ;
35
+
36
+
37
+ begin
38
+ require 'blockenspiel'
39
+ require 'versionomy'
40
+ rescue ::LoadError
41
+ require 'rubygems'
42
+ require 'blockenspiel'
43
+ require 'versionomy'
44
+ end
45
+
46
+
47
+ dir_ = ::File.expand_path('sawmill', ::File.dirname(__FILE__))
48
+
49
+ includes_ = [
50
+ 'version',
51
+ 'util/queue',
52
+ 'errors',
53
+ 'level',
54
+ 'entry',
55
+ 'entry_classifier',
56
+ 'entry_processor',
57
+ 'entry_processor/conditionals',
58
+ 'entry_processor/simple_queue',
59
+ 'entry_processor/filter_basic_fields',
60
+ 'entry_processor/build_records',
61
+ 'entry_processor/format',
62
+ 'record',
63
+ 'record_processor',
64
+ 'record_processor/conditionals',
65
+ 'record_processor/filter_by_record_id',
66
+ 'record_processor/filter_by_attributes',
67
+ 'record_processor/simple_queue',
68
+ 'record_processor/decompose',
69
+ 'record_processor/format',
70
+ 'parser',
71
+ 'logger',
72
+ 'rotater',
73
+ 'rotater/base',
74
+ 'rotater/date_based_log_file',
75
+ 'rotater/shifting_log_file',
76
+ 'log_record_middleware',
77
+ ]
78
+ includes_.each{ |file_| require "#{dir_}/#{file_}" }
@@ -0,0 +1,138 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # Sawmill: tests on entry processors
4
+ #
5
+ # -----------------------------------------------------------------------------
6
+ # Copyright 2009 Daniel Azuma
7
+ #
8
+ # All rights reserved.
9
+ #
10
+ # Redistribution and use in source and binary forms, with or without
11
+ # modification, are permitted provided that the following conditions are met:
12
+ #
13
+ # * Redistributions of source code must retain the above copyright notice,
14
+ # this list of conditions and the following disclaimer.
15
+ # * Redistributions in binary form must reproduce the above copyright notice,
16
+ # this list of conditions and the following disclaimer in the documentation
17
+ # and/or other materials provided with the distribution.
18
+ # * Neither the name of the copyright holder, nor the names of any other
19
+ # contributors to this software, may be used to endorse or promote products
20
+ # derived from this software without specific prior written permission.
21
+ #
22
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
+ # POSSIBILITY OF SUCH DAMAGE.
33
+ # -----------------------------------------------------------------------------
34
+
35
+
36
+ require 'test/unit'
37
+ require ::File.expand_path("#{::File.dirname(__FILE__)}/../lib/sawmill.rb")
38
+
39
+
40
+ module Sawmill
41
+ module Tests # :nodoc:
42
+
43
+ class TestEntryProcessors < ::Test::Unit::TestCase # :nodoc:
44
+
45
+
46
+ def setup
47
+ @entries = ::Sawmill::EntryProcessor::SimpleQueue.new
48
+ @levels = ::Sawmill::STANDARD_LEVELS
49
+ end
50
+
51
+
52
+ # Test a basic filter that checks the level
53
+
54
+ def test_basic_level_filter
55
+ processor_ = ::Sawmill::EntryProcessor::build do
56
+ If(FilterBasicFields(:level => :WARN), @entries)
57
+ end
58
+ @logger = ::Sawmill::Logger.new(:processor => processor_)
59
+ @logger.warn('Hello 1')
60
+ @logger.info('Hello 2')
61
+ @logger.error('Hello 3')
62
+ assert_equal('Hello 1', @entries.dequeue.message)
63
+ assert_equal('Hello 3', @entries.dequeue.message)
64
+ assert_equal(0, @entries.size)
65
+ end
66
+
67
+
68
+ # Test a basic filter that checks the progname
69
+
70
+ def test_basic_progname_filter
71
+ processor_ = ::Sawmill::EntryProcessor::build do
72
+ If(FilterBasicFields(:progname => 'rails'), @entries)
73
+ end
74
+ @logger = ::Sawmill::Logger.new(:processor => processor_)
75
+ @logger.info('Hello 1')
76
+ @logger.info('rails') {'Hello 2'}
77
+ @logger.info('Hello 3')
78
+ assert_equal('Hello 2', @entries.dequeue.message)
79
+ assert_equal(0, @entries.size)
80
+ end
81
+
82
+
83
+ # Test an "AND" filter
84
+
85
+ def test_conjunction_and
86
+ processor_ = ::Sawmill::EntryProcessor::build do
87
+ If(And(FilterBasicFields(:progname => 'rails'),
88
+ FilterBasicFields(:level => :WARN)), @entries)
89
+ end
90
+ @logger = ::Sawmill::Logger.new(:processor => processor_)
91
+ @logger.warn('Hello 1')
92
+ @logger.warn('rails') {'Hello 2'}
93
+ @logger.info('rails') {'Hello 3'}
94
+ @logger.info('Hello 4')
95
+ assert_equal('Hello 2', @entries.dequeue.message)
96
+ assert_equal(0, @entries.size)
97
+ end
98
+
99
+
100
+ # Test an "OR" filter
101
+
102
+ def test_conjunction_or
103
+ processor_ = ::Sawmill::EntryProcessor::build do
104
+ If(Or(FilterBasicFields(:progname => 'rails'),
105
+ FilterBasicFields(:level => :WARN)), @entries)
106
+ end
107
+ @logger = ::Sawmill::Logger.new(:processor => processor_)
108
+ @logger.warn('Hello 1')
109
+ @logger.warn('rails') {'Hello 2'}
110
+ @logger.info('rails') {'Hello 3'}
111
+ @logger.info('Hello 4')
112
+ assert_equal('Hello 1', @entries.dequeue.message)
113
+ assert_equal('Hello 2', @entries.dequeue.message)
114
+ assert_equal('Hello 3', @entries.dequeue.message)
115
+ assert_equal(0, @entries.size)
116
+ end
117
+
118
+
119
+ # Test a "NOT" filter
120
+
121
+ def test_boolean_not
122
+ processor_ = ::Sawmill::EntryProcessor::build do
123
+ If(Not(FilterBasicFields(:progname => 'rails')), @entries)
124
+ end
125
+ @logger = ::Sawmill::Logger.new(:processor => processor_)
126
+ @logger.info('Hello 1')
127
+ @logger.info('rails') {'Hello 2'}
128
+ @logger.info('sawmill') {'Hello 3'}
129
+ assert_equal('Hello 1', @entries.dequeue.message)
130
+ assert_equal('Hello 3', @entries.dequeue.message)
131
+ assert_equal(0, @entries.size)
132
+ end
133
+
134
+
135
+ end
136
+
137
+ end
138
+ end
@@ -0,0 +1,144 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # Sawmill: tests log file formatting and parsing
4
+ #
5
+ # -----------------------------------------------------------------------------
6
+ # Copyright 2009 Daniel Azuma
7
+ #
8
+ # All rights reserved.
9
+ #
10
+ # Redistribution and use in source and binary forms, with or without
11
+ # modification, are permitted provided that the following conditions are met:
12
+ #
13
+ # * Redistributions of source code must retain the above copyright notice,
14
+ # this list of conditions and the following disclaimer.
15
+ # * Redistributions in binary form must reproduce the above copyright notice,
16
+ # this list of conditions and the following disclaimer in the documentation
17
+ # and/or other materials provided with the distribution.
18
+ # * Neither the name of the copyright holder, nor the names of any other
19
+ # contributors to this software, may be used to endorse or promote products
20
+ # derived from this software without specific prior written permission.
21
+ #
22
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
+ # POSSIBILITY OF SUCH DAMAGE.
33
+ # -----------------------------------------------------------------------------
34
+
35
+
36
+ require 'test/unit'
37
+ require 'stringio'
38
+ require ::File.expand_path("#{::File.dirname(__FILE__)}/../lib/sawmill.rb")
39
+
40
+
41
+ module Sawmill
42
+ module Tests # :nodoc:
43
+
44
+ class TestFormatterParser < ::Test::Unit::TestCase # :nodoc:
45
+
46
+
47
+ def setup
48
+ @entries = []
49
+ @levels = ::Sawmill::STANDARD_LEVELS
50
+ end
51
+
52
+
53
+ def _run_test(expected_, opts_={})
54
+ stringio_ = ::StringIO.new
55
+ formatter_ = ::Sawmill::EntryClassifier.new(::Sawmill::Formatter.new(stringio_, opts_))
56
+ @entries.each do |entry_|
57
+ formatter_.entry(entry_)
58
+ end
59
+ formatted_string_ = stringio_.string
60
+ assert_equal(expected_, formatted_string_)
61
+ stringio_ = ::StringIO.new(formatted_string_)
62
+ parser_ = ::Sawmill::Parser.new(stringio_, nil)
63
+ @entries.each do |expected_|
64
+ assert_equal(expected_, parser_.parse_one_entry)
65
+ end
66
+ end
67
+
68
+
69
+ # Test message entry
70
+
71
+ def test_basic_message
72
+ @entries << ::Sawmill::Entry::Message.new(@levels.get(:INFO), Time.utc(2009, 10, 20, 8, 30, 45, 120000), 'rails', nil, 'Hello')
73
+ _run_test("[INFO 2009-10-20 08:30:45.12 rails .] Hello\n")
74
+ end
75
+
76
+
77
+ # Test message with no fractional seconds
78
+
79
+ def test_message_with_whole_seconds
80
+ @entries << ::Sawmill::Entry::Message.new(@levels.get(:INFO), Time.utc(2009, 10, 20, 8, 30, 45, 0), 'rails', nil, 'Hello')
81
+ _run_test("[INFO 2009-10-20 08:30:45.00 rails .] Hello\n")
82
+ end
83
+
84
+
85
+ # Test multiple message entry
86
+
87
+ def test_multiple_messages
88
+ @entries << ::Sawmill::Entry::Message.new(@levels.get(:INFO), Time.utc(2009, 10, 20, 8, 30, 45, 120000), 'rails', nil, 'Hello')
89
+ @entries << ::Sawmill::Entry::Message.new(@levels.get(:ERROR), Time.utc(2009, 10, 20, 8, 30, 46, 980000), 'rails', nil, 'Something bad happened!')
90
+ _run_test("[INFO 2009-10-20 08:30:45.12 rails .] Hello\n[ERROR 2009-10-20 08:30:46.98 rails .] Something bad happened!\n")
91
+ end
92
+
93
+
94
+ # Test multi-line message entries
95
+
96
+ def test_multi_line_messages
97
+ @entries << ::Sawmill::Entry::Message.new(@levels.get(:INFO), Time.utc(2009, 10, 20, 8, 30, 45, 120000), 'rails', nil, "Multiple\nLines\n")
98
+ @entries << ::Sawmill::Entry::Message.new(@levels.get(:ERROR), Time.utc(2009, 10, 20, 8, 30, 46, 980000), 'rails', nil, "Multiple Lines\\\nwith trailing backslashes\\\\\n")
99
+ @entries << ::Sawmill::Entry::Message.new(@levels.get(:ERROR), Time.utc(2009, 10, 20, 8, 30, 47, 0), 'rails', nil, "More trailing\\\nbackslashes\\\\")
100
+ _run_test("[INFO 2009-10-20 08:30:45.12 rails .] Multiple\\\nLines\\\n\n[ERROR 2009-10-20 08:30:46.98 rails .] Multiple Lines\\\\\\\nwith trailing backslashes\\\\\\\\\\\n\n[ERROR 2009-10-20 08:30:47.00 rails .] More trailing\\\\\\\nbackslashes\\\\\\\\\n")
101
+ end
102
+
103
+
104
+ # Test record delimiter entries
105
+
106
+ def test_record_delimiters
107
+ @entries << ::Sawmill::Entry::BeginRecord.new(@levels.get(:ANY), Time.utc(2009, 10, 20, 8, 30, 45, 120000), 'rails', 'abcdefg')
108
+ @entries << ::Sawmill::Entry::EndRecord.new(@levels.get(:ANY), Time.utc(2009, 10, 20, 8, 30, 46, 980000), 'rails', 'abcdefg')
109
+ _run_test("[ANY 2009-10-20 08:30:45.12 rails ^] BEGIN abcdefg\n[ANY 2009-10-20 08:30:46.98 rails $] END abcdefg\n")
110
+ end
111
+
112
+
113
+ # Test attribute entries
114
+
115
+ def test_attributes
116
+ @entries << ::Sawmill::Entry::BeginRecord.new(@levels.get(:ANY), Time.utc(2009, 10, 20, 8, 30, 45, 110000), 'rails', 'abcdefg')
117
+ @entries << ::Sawmill::Entry::Attribute.new(@levels.get(:INFO), Time.utc(2009, 10, 20, 8, 30, 45, 120000), 'rails', 'abcdefg', 'SIZE', 'small')
118
+ @entries << ::Sawmill::Entry::Attribute.new(@levels.get(:INFO), Time.utc(2009, 10, 20, 8, 30, 46, 980000), 'rails', 'abcdefg', 'COLOR', "red\nand\nblue", :append)
119
+ @entries << ::Sawmill::Entry::EndRecord.new(@levels.get(:ANY), Time.utc(2009, 10, 20, 8, 30, 46, 990000), 'rails', 'abcdefg')
120
+ _run_test("[ANY 2009-10-20 08:30:45.11 rails ^] BEGIN abcdefg\n[INFO 2009-10-20 08:30:45.12 rails =] SIZE = small\n[INFO 2009-10-20 08:30:46.98 rails =] COLOR + red\\\nand\\\nblue\n[ANY 2009-10-20 08:30:46.99 rails $] END abcdefg\n")
121
+ end
122
+
123
+
124
+ # Test message with include_id
125
+
126
+ def test_message_with_include_id
127
+ @entries << ::Sawmill::Entry::Message.new(@levels.get(:INFO), Time.utc(2009, 10, 20, 8, 30, 45, 0), 'rails', 'abcdefg', 'Hello 1')
128
+ @entries << ::Sawmill::Entry::Message.new(@levels.get(:INFO), Time.utc(2009, 10, 20, 8, 30, 45, 100000), 'rails', nil, 'Hello 2')
129
+ _run_test("[INFO 2009-10-20 08:30:45.00 rails abcdefg .] Hello 1\n[INFO 2009-10-20 08:30:45.10 rails .] Hello 2\n", :include_id => true)
130
+ end
131
+
132
+
133
+ # Test message where fractional seconds are turned off
134
+
135
+ def test_message_without_fractional_seconds
136
+ @entries << ::Sawmill::Entry::Message.new(@levels.get(:INFO), Time.utc(2009, 10, 20, 8, 30, 45, 0), 'rails', nil, 'Hello 1')
137
+ _run_test("[INFO 2009-10-20 08:30:45 rails .] Hello 1\n", :fractional_second_digits => 0)
138
+ end
139
+
140
+
141
+ end
142
+
143
+ end
144
+ end
@@ -0,0 +1,118 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # Sawmill: tests on the levels mechanism
4
+ #
5
+ # -----------------------------------------------------------------------------
6
+ # Copyright 2009 Daniel Azuma
7
+ #
8
+ # All rights reserved.
9
+ #
10
+ # Redistribution and use in source and binary forms, with or without
11
+ # modification, are permitted provided that the following conditions are met:
12
+ #
13
+ # * Redistributions of source code must retain the above copyright notice,
14
+ # this list of conditions and the following disclaimer.
15
+ # * Redistributions in binary form must reproduce the above copyright notice,
16
+ # this list of conditions and the following disclaimer in the documentation
17
+ # and/or other materials provided with the distribution.
18
+ # * Neither the name of the copyright holder, nor the names of any other
19
+ # contributors to this software, may be used to endorse or promote products
20
+ # derived from this software without specific prior written permission.
21
+ #
22
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
+ # POSSIBILITY OF SUCH DAMAGE.
33
+ # -----------------------------------------------------------------------------
34
+
35
+
36
+ require 'test/unit'
37
+ require 'logger'
38
+ require ::File.expand_path("#{::File.dirname(__FILE__)}/../lib/sawmill.rb")
39
+
40
+
41
+ module Sawmill
42
+ module Tests # :nodoc:
43
+
44
+ class TestLevels < ::Test::Unit::TestCase # :nodoc:
45
+
46
+
47
+ def setup
48
+ @levels = ::Sawmill::STANDARD_LEVELS
49
+ end
50
+
51
+
52
+ # Test equivalence of standard level names and legacy logger level constants
53
+
54
+ def test_standard_names_vs_legacy_constants
55
+ assert_equal(@levels.get(:DEBUG), @levels.get(::Logger::DEBUG))
56
+ assert_not_equal(@levels.get(:DEBUG), @levels.get(::Logger::INFO))
57
+ assert_equal(@levels.get(:INFO), @levels.get(::Logger::INFO))
58
+ assert_equal(@levels.get(:WARN), @levels.get(::Logger::WARN))
59
+ assert_equal(@levels.get(:ERROR), @levels.get(::Logger::ERROR))
60
+ assert_equal(@levels.get(:FATAL), @levels.get(::Logger::FATAL))
61
+ assert_equal(@levels.get(:ANY), @levels.get(::Logger::UNKNOWN))
62
+ end
63
+
64
+
65
+ # Test special levels in the standard set
66
+
67
+ def test_special_standard_levels
68
+ assert_equal(@levels.get(:DEBUG), @levels.lowest)
69
+ assert_equal(@levels.get(:INFO), @levels.default)
70
+ assert_equal(@levels.get(:ANY), @levels.highest)
71
+ assert_equal(@levels.get(nil), @levels.default)
72
+ end
73
+
74
+
75
+ # Test method lookup of standard levels
76
+
77
+ def test_standard_method_lookup
78
+ assert_equal(@levels.get(:DEBUG), @levels.lookup_method(:debug))
79
+ assert_equal(@levels.get(:INFO), @levels.lookup_method(:info))
80
+ assert_equal(@levels.get(:WARN), @levels.lookup_method(:warn))
81
+ assert_equal(@levels.get(:ERROR), @levels.lookup_method(:error))
82
+ assert_equal(@levels.get(:FATAL), @levels.lookup_method(:fatal))
83
+ assert_equal(@levels.get(:ANY), @levels.lookup_method(:any))
84
+ assert_equal(@levels.get(:ANY), @levels.lookup_method(:unknown))
85
+ end
86
+
87
+
88
+ # Test comparison of standard levels
89
+
90
+ def test_standard_comparisons
91
+ assert(@levels.get(:DEBUG) < @levels.get(:INFO))
92
+ assert(@levels.get(:ANY) > @levels.get(:FATAL))
93
+ assert(@levels.get(:ERROR) >= @levels.get(:DEBUG))
94
+ assert(@levels.get(:WARN) >= @levels.get(:WARN))
95
+ end
96
+
97
+
98
+ # Test custom level group
99
+
100
+ def test_custom_group
101
+ group_ = ::Sawmill::LevelGroup.new do |g_|
102
+ g_.add(:LOW, :methods => 'low')
103
+ g_.add(:MED, :methods => 'med', :default => true)
104
+ g_.add(:HIGH, :methods => 'high')
105
+ g_.add(:CRIT, :methods => 'crit')
106
+ end
107
+ assert_equal(group_.get(:LOW), group_.get(0))
108
+ assert_equal(group_.get(:HIGH), group_.get(2))
109
+ assert_equal(group_.default, group_.get(1))
110
+ assert_equal(group_.highest, group_.get(3))
111
+ assert_not_equal(@levels.lowest, group_.lowest)
112
+ end
113
+
114
+
115
+ end
116
+
117
+ end
118
+ end