sawmill 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.rdoc +3 -0
- data/README.rdoc +81 -0
- data/Rakefile +147 -0
- data/lib/sawmill/entry.rb +307 -0
- data/lib/sawmill/entry_classifier.rb +75 -0
- data/lib/sawmill/entry_processor/build_records.rb +157 -0
- data/lib/sawmill/entry_processor/conditionals.rb +444 -0
- data/lib/sawmill/entry_processor/filter_basic_fields.rb +145 -0
- data/lib/sawmill/entry_processor/format.rb +228 -0
- data/lib/sawmill/entry_processor/simple_queue.rb +116 -0
- data/lib/sawmill/entry_processor.rb +158 -0
- data/lib/sawmill/errors.rb +66 -0
- data/lib/sawmill/level.rb +264 -0
- data/lib/sawmill/log_record_middleware.rb +93 -0
- data/lib/sawmill/logger.rb +373 -0
- data/lib/sawmill/parser.rb +181 -0
- data/lib/sawmill/record.rb +255 -0
- data/lib/sawmill/record_processor/conditionals.rb +330 -0
- data/lib/sawmill/record_processor/decompose.rb +75 -0
- data/lib/sawmill/record_processor/filter_by_attributes.rb +87 -0
- data/lib/sawmill/record_processor/filter_by_record_id.rb +77 -0
- data/lib/sawmill/record_processor/format.rb +88 -0
- data/lib/sawmill/record_processor/simple_queue.rb +117 -0
- data/lib/sawmill/record_processor.rb +137 -0
- data/lib/sawmill/rotater/base.rb +90 -0
- data/lib/sawmill/rotater/date_based_log_file.rb +145 -0
- data/lib/sawmill/rotater/shifting_log_file.rb +166 -0
- data/lib/sawmill/rotater.rb +236 -0
- data/lib/sawmill/util/queue.rb +138 -0
- data/lib/sawmill/version.rb +47 -0
- data/lib/sawmill.rb +78 -0
- data/tests/tc_entry_processors.rb +138 -0
- data/tests/tc_formatter_parser.rb +144 -0
- data/tests/tc_levels.rb +118 -0
- data/tests/tc_logger.rb +315 -0
- data/tests/tc_record_processors.rb +117 -0
- data/tests/tc_records.rb +206 -0
- 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
|
data/tests/tc_levels.rb
ADDED
@@ -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
|