filterfish-logging 0.9.8

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 (55) hide show
  1. data/History.txt +176 -0
  2. data/Manifest.txt +54 -0
  3. data/README.txt +93 -0
  4. data/Rakefile +28 -0
  5. data/data/logging.yaml +63 -0
  6. data/lib/logging.rb +288 -0
  7. data/lib/logging/appender.rb +257 -0
  8. data/lib/logging/appenders/console.rb +43 -0
  9. data/lib/logging/appenders/email.rb +131 -0
  10. data/lib/logging/appenders/file.rb +55 -0
  11. data/lib/logging/appenders/growl.rb +182 -0
  12. data/lib/logging/appenders/io.rb +81 -0
  13. data/lib/logging/appenders/rolling_file.rb +293 -0
  14. data/lib/logging/appenders/syslog.rb +202 -0
  15. data/lib/logging/config/yaml_configurator.rb +197 -0
  16. data/lib/logging/layout.rb +103 -0
  17. data/lib/logging/layouts/basic.rb +35 -0
  18. data/lib/logging/layouts/pattern.rb +292 -0
  19. data/lib/logging/log_event.rb +50 -0
  20. data/lib/logging/logger.rb +388 -0
  21. data/lib/logging/repository.rb +151 -0
  22. data/lib/logging/root_logger.rb +60 -0
  23. data/lib/logging/utils.rb +44 -0
  24. data/tasks/ann.rake +78 -0
  25. data/tasks/bones.rake +21 -0
  26. data/tasks/gem.rake +106 -0
  27. data/tasks/manifest.rake +49 -0
  28. data/tasks/notes.rake +22 -0
  29. data/tasks/post_load.rake +37 -0
  30. data/tasks/rdoc.rake +49 -0
  31. data/tasks/rubyforge.rake +57 -0
  32. data/tasks/setup.rb +253 -0
  33. data/tasks/svn.rake +45 -0
  34. data/tasks/test.rake +38 -0
  35. data/test/appenders/test_console.rb +40 -0
  36. data/test/appenders/test_email.rb +167 -0
  37. data/test/appenders/test_file.rb +94 -0
  38. data/test/appenders/test_growl.rb +115 -0
  39. data/test/appenders/test_io.rb +113 -0
  40. data/test/appenders/test_rolling_file.rb +187 -0
  41. data/test/appenders/test_syslog.rb +192 -0
  42. data/test/benchmark.rb +88 -0
  43. data/test/config/test_yaml_configurator.rb +41 -0
  44. data/test/layouts/test_basic.rb +44 -0
  45. data/test/layouts/test_pattern.rb +173 -0
  46. data/test/setup.rb +66 -0
  47. data/test/test_appender.rb +162 -0
  48. data/test/test_layout.rb +85 -0
  49. data/test/test_log_event.rb +81 -0
  50. data/test/test_logger.rb +589 -0
  51. data/test/test_logging.rb +250 -0
  52. data/test/test_repository.rb +123 -0
  53. data/test/test_root_logger.rb +82 -0
  54. data/test/test_utils.rb +48 -0
  55. metadata +126 -0
data/tasks/svn.rake ADDED
@@ -0,0 +1,45 @@
1
+ # $Id$
2
+
3
+ if PROJ.svn.path and system("svn --version 2>&1 > #{DEV_NULL}")
4
+
5
+ unless PROJ.svn.root
6
+ info = %x/svn info ./
7
+ m = %r/^Repository Root:\s+(.*)$/.match(info)
8
+ PROJ.svn.root = (m.nil? ? '' : m[1])
9
+ end
10
+ PROJ.svn.root = File.join(PROJ.svn.root, PROJ.svn.path) unless PROJ.svn.path.empty?
11
+
12
+ namespace :svn do
13
+
14
+ desc 'Show tags from the SVN repository'
15
+ task :show_tags do |t|
16
+ tags = %x/svn list #{File.join(PROJ.svn.root, PROJ.svn.tags)}/
17
+ tags.gsub!(%r/\/$/, '')
18
+ tags = tags.split("\n").sort {|a,b| b <=> a}
19
+ puts tags
20
+ end
21
+
22
+ desc 'Create a new tag in the SVN repository'
23
+ task :create_tag do |t|
24
+ v = ENV['VERSION'] or abort 'Must supply VERSION=x.y.z'
25
+ abort "Versions don't match #{v} vs #{PROJ.version}" if v != PROJ.version
26
+
27
+ svn = PROJ.svn
28
+ trunk = File.join(svn.root, svn.trunk)
29
+ tag = "%s-%s" % [PROJ.name, PROJ.version]
30
+ tag = File.join(svn.root, svn.tags, tag)
31
+ msg = "Creating tag for #{PROJ.name} version #{PROJ.version}"
32
+
33
+ puts "Creating SVN tag '#{tag}'"
34
+ unless system "svn cp -m '#{msg}' #{trunk} #{tag}"
35
+ abort "Tag creation failed"
36
+ end
37
+ end
38
+
39
+ end # namespace :svn
40
+
41
+ task 'gem:release' => 'svn:create_tag'
42
+
43
+ end # if PROJ.svn.path
44
+
45
+ # EOF
data/tasks/test.rake ADDED
@@ -0,0 +1,38 @@
1
+ # $Id$
2
+
3
+ require 'rake/testtask'
4
+
5
+ namespace :test do
6
+
7
+ Rake::TestTask.new(:run) do |t|
8
+ t.libs = PROJ.libs
9
+ t.test_files = if test(?f, PROJ.test.file) then [PROJ.test.file]
10
+ else PROJ.test.files end
11
+ t.ruby_opts += PROJ.ruby_opts
12
+ t.ruby_opts += PROJ.test.opts
13
+ end
14
+
15
+ if HAVE_RCOV
16
+ desc 'Run rcov on the unit tests'
17
+ task :rcov => :clobber_rcov do
18
+ opts = PROJ.rcov.opts.dup << '-o' << PROJ.rcov.dir
19
+ opts = opts.join(' ')
20
+ files = if test(?f, PROJ.test.file) then [PROJ.test.file]
21
+ else PROJ.test.files end
22
+ files = files.join(' ')
23
+ sh "#{RCOV} #{files} #{opts}"
24
+ end
25
+
26
+ task :clobber_rcov do
27
+ rm_r 'coverage' rescue nil
28
+ end
29
+ end
30
+
31
+ end # namespace :test
32
+
33
+ desc 'Alias to test:run'
34
+ task :test => 'test:run'
35
+
36
+ task :clobber => 'test:clobber_rcov' if HAVE_RCOV
37
+
38
+ # EOF
@@ -0,0 +1,40 @@
1
+ # $Id$
2
+
3
+ require File.join(File.dirname(__FILE__), %w[.. setup])
4
+
5
+ module TestLogging
6
+ module TestAppenders
7
+
8
+ class TestStdout < Test::Unit::TestCase
9
+ include LoggingTestCase
10
+
11
+ def test_initialize
12
+ appender = ::Logging::Appenders::Stdout.new
13
+ assert_equal 'stdout', appender.name
14
+ assert_same STDOUT, appender.instance_variable_get(:@io)
15
+
16
+ appender.close
17
+ assert_equal true, appender.closed?
18
+ assert_equal false, STDOUT.closed?
19
+ end
20
+
21
+ end # class TestStdout
22
+
23
+ class TestStderr < Test::Unit::TestCase
24
+
25
+ def test_initialize
26
+ appender = ::Logging::Appenders::Stderr.new
27
+ assert_equal 'stderr', appender.name
28
+ assert_same STDERR, appender.instance_variable_get(:@io)
29
+
30
+ appender.close
31
+ assert_equal true, appender.closed?
32
+ assert_equal false, STDERR.closed?
33
+ end
34
+
35
+ end # class TestStderr
36
+
37
+ end # module TestAppenders
38
+ end # module TestLogging
39
+
40
+ # EOF
@@ -0,0 +1,167 @@
1
+ # $Id$
2
+
3
+ require File.join(File.dirname(__FILE__), %w[.. setup])
4
+ require 'flexmock'
5
+
6
+ module TestLogging
7
+ module TestAppenders
8
+
9
+ class TestEmail < Test::Unit::TestCase
10
+ include FlexMock::TestCase
11
+ include LoggingTestCase
12
+
13
+ def setup
14
+ super
15
+ ::Logging.init
16
+ @levels = ::Logging::LEVELS
17
+
18
+ flexmock(Net::SMTP).new_instances do |m|
19
+ m.should_receive(:start).at_least.once.with(
20
+ 'test.logging', 'test', 'test', :cram_md5, Proc).and_yield(m)
21
+ m.should_receive(:sendmail).at_least.once.with(String, 'me', ['you'])
22
+ end
23
+
24
+ @appender = ::Logging::Appenders::Email.new('email',
25
+ 'from' => 'me', 'to' => 'you',
26
+ :buffsize => '3', :immediate_at => 'error, fatal',
27
+ :domain => 'test.logging', :acct => 'test', :passwd => 'test'
28
+ )
29
+ end
30
+
31
+ def test_initialize
32
+ assert_raise(ArgumentError, 'Must specify from address') {
33
+ ::Logging::Appenders::Email.new('email')
34
+ }
35
+ assert_raise(ArgumentError, 'Must specify to address') {
36
+ ::Logging::Appenders::Email.new('email', :from => 'me')
37
+ }
38
+ assert_nothing_raised {
39
+ ::Logging::Appenders::Email.new('email', :from => 'me', :to => 'you')
40
+ }
41
+
42
+ appender = ::Logging::Appenders::Email.new('email',
43
+ 'from' => 'me', 'to' => 'you'
44
+ )
45
+
46
+ assert_equal(100, appender.instance_variable_get(:@buffsize))
47
+ assert_equal([], appender.instance_variable_get(:@immediate))
48
+ assert_equal('localhost', appender.server)
49
+ assert_equal(25, appender.port)
50
+
51
+ domain = ENV['HOSTNAME'] || 'localhost.localdomain'
52
+ assert_equal(domain, appender.domain)
53
+ assert_equal(nil, appender.acct)
54
+ assert_equal(:cram_md5, appender.authtype)
55
+ assert_equal("Message of #{$0}", appender.subject)
56
+
57
+ appender = ::Logging::Appenders::Email.new('email',
58
+ 'from' => 'lbrinn@gmail.com', 'to' => 'everyone',
59
+ :buffsize => '1000', :immediate_at => 'error, fatal',
60
+ :server => 'smtp.google.com', :port => '443',
61
+ :domain => 'google.com', :acct => 'lbrinn',
62
+ :passwd => '1234', :authtype => 'tls',
63
+ :subject => "I'm rich and you're not"
64
+ )
65
+
66
+ assert_equal('lbrinn@gmail.com', appender.instance_variable_get(:@from))
67
+ assert_equal(['everyone'], appender.instance_variable_get(:@to))
68
+ assert_equal(1000, appender.instance_variable_get(:@buffsize))
69
+ assert_equal('1234', appender.instance_variable_get(:@passwd))
70
+ assert_equal([nil, nil, nil, true, true],
71
+ appender.instance_variable_get(:@immediate))
72
+ assert_equal('smtp.google.com', appender.server)
73
+ assert_equal(443, appender.port)
74
+ assert_equal('google.com', appender.domain)
75
+ assert_equal('lbrinn', appender.acct)
76
+ assert_equal(:tls, appender.authtype)
77
+ assert_equal("I'm rich and you're not", appender.subject)
78
+ end
79
+
80
+ def test_append
81
+ # with a buffer size of 0, mail will be sent each time a log event
82
+ # occurs
83
+ @appender.instance_variable_set(:@buffsize, 0)
84
+ event = ::Logging::LogEvent.new('TestLogger', @levels['warn'],
85
+ [1, 2, 3, 4], false)
86
+ @appender.append event
87
+ assert_not_equal(@levels.length, @appender.level)
88
+ assert_equal(0, @appender.queued_messages)
89
+
90
+ # increase the buffer size and log a few events
91
+ @appender.instance_variable_set(:@buffsize, 3)
92
+ @appender.append event
93
+ @appender.append event
94
+ assert_equal(2, @appender.queued_messages)
95
+
96
+ @appender.append event
97
+ assert_not_equal(@levels.length, @appender.level)
98
+ assert_equal(0, @appender.queued_messages)
99
+
100
+ # error and fatal messages should be send immediately (no buffering)
101
+ error = ::Logging::LogEvent.new('ErrLogger', @levels['error'],
102
+ 'error message', false)
103
+ fatal = ::Logging::LogEvent.new('FatalLogger', @levels['fatal'],
104
+ 'fatal message', false)
105
+
106
+ @appender.append event
107
+ @appender.append fatal
108
+ assert_not_equal(@levels.length, @appender.level)
109
+ assert_equal(0, @appender.queued_messages)
110
+
111
+ @appender.append error
112
+ assert_not_equal(@levels.length, @appender.level)
113
+ assert_equal(0, @appender.queued_messages)
114
+
115
+ @appender.append event
116
+ assert_equal(1, @appender.queued_messages)
117
+ end
118
+
119
+ def test_concat
120
+ # with a buffer size of 0, mail will be sent each time a log event
121
+ # occurs
122
+ @appender.instance_variable_set(:@buffsize, 0)
123
+ @appender << 'test message'
124
+ assert_not_equal(@levels.length, @appender.level)
125
+ assert_equal(0, @appender.queued_messages)
126
+
127
+ # increase the buffer size and log a few events
128
+ @appender.instance_variable_set(:@buffsize, 3)
129
+ @appender << 'another test message'
130
+ @appender << 'a second test message'
131
+ assert_equal(2, @appender.queued_messages)
132
+
133
+ @appender << 'a third test message'
134
+ assert_not_equal(@levels.length, @appender.level)
135
+ assert_equal(0, @appender.queued_messages)
136
+ end
137
+
138
+ def test_flush
139
+ event = ::Logging::LogEvent.new('TestLogger', @levels['info'],
140
+ [1, 2, 3, 4], false)
141
+ @appender.append event
142
+ @appender << 'test message'
143
+ assert_equal(2, @appender.queued_messages)
144
+
145
+ @appender.flush
146
+ assert_not_equal(@levels.length, @appender.level)
147
+ assert_equal(0, @appender.queued_messages)
148
+ end
149
+
150
+ def test_close
151
+ event = ::Logging::LogEvent.new('TestLogger', @levels['info'],
152
+ [1, 2, 3, 4], false)
153
+ @appender.append event
154
+ @appender << 'test message'
155
+ assert_equal(2, @appender.queued_messages)
156
+
157
+ @appender.close
158
+ assert_not_equal(@levels.length, @appender.level)
159
+ assert_equal(0, @appender.queued_messages)
160
+ assert(@appender.closed?)
161
+ end
162
+
163
+ end # class TestEmail
164
+ end # module TestLogging
165
+ end # module TestAppenders
166
+
167
+ # EOF
@@ -0,0 +1,94 @@
1
+ # $Id$
2
+
3
+ require File.join(File.dirname(__FILE__), %w[.. setup])
4
+
5
+ module TestLogging
6
+ module TestAppenders
7
+
8
+ class TestFile < Test::Unit::TestCase
9
+ include LoggingTestCase
10
+
11
+ NAME = 'logfile'
12
+
13
+ def setup
14
+ super
15
+ ::Logging.init
16
+
17
+ FileUtils.mkdir [File.join(TMP, 'dir'), File.join(TMP, 'uw_dir')]
18
+ FileUtils.chmod 0555, File.join(TMP, 'uw_dir')
19
+ FileUtils.touch File.join(TMP, 'uw_file')
20
+ FileUtils.chmod 0444, File.join(TMP, 'uw_file')
21
+ end
22
+
23
+ def test_class_assert_valid_logfile
24
+ log = File.join(TMP, 'uw_dir', 'file.log')
25
+ assert_raise(ArgumentError) do
26
+ ::Logging::Appenders::File.assert_valid_logfile(log)
27
+ end
28
+
29
+ log = File.join(TMP, 'dir')
30
+ assert_raise(ArgumentError) do
31
+ ::Logging::Appenders::File.assert_valid_logfile(log)
32
+ end
33
+
34
+ log = File.join(TMP, 'uw_file')
35
+ assert_raise(ArgumentError) do
36
+ ::Logging::Appenders::File.assert_valid_logfile(log)
37
+ end
38
+
39
+ log = File.join(TMP, 'file.log')
40
+ assert ::Logging::Appenders::File.assert_valid_logfile(log)
41
+ end
42
+
43
+ def test_initialize
44
+ log = File.join(TMP, 'file.log')
45
+ appender = ::Logging::Appenders::File.new(NAME, 'filename' => log)
46
+ assert_equal 'logfile', appender.name
47
+ appender << "This will be the first line\n"
48
+ appender << "This will be the second line\n"
49
+ appender.flush
50
+ File.open(log, 'r') do |file|
51
+ assert_equal "This will be the first line\n", file.readline
52
+ assert_equal "This will be the second line\n", file.readline
53
+ assert_raise(EOFError) {file.readline}
54
+ end
55
+ cleanup
56
+
57
+ appender = ::Logging::Appenders::File.new NAME, :filename => log
58
+ assert_equal 'logfile', appender.name
59
+ appender << "This will be the third line\n"
60
+ appender.flush
61
+ File.open(log, 'r') do |file|
62
+ assert_equal "This will be the first line\n", file.readline
63
+ assert_equal "This will be the second line\n", file.readline
64
+ assert_equal "This will be the third line\n", file.readline
65
+ assert_raise(EOFError) {file.readline}
66
+ end
67
+ cleanup
68
+
69
+ appender = ::Logging::Appenders::File.new NAME, :filename => log,
70
+ :truncate => true
71
+ assert_equal 'logfile', appender.name
72
+ appender << "The file was truncated\n"
73
+ appender.flush
74
+ File.open(log, 'r') do |file|
75
+ assert_equal "The file was truncated\n", file.readline
76
+ assert_raise(EOFError) {file.readline}
77
+ end
78
+ cleanup
79
+ end
80
+
81
+ private
82
+ def cleanup
83
+ unless ::Logging::Appender[NAME].nil?
84
+ ::Logging::Appender[NAME].close false
85
+ ::Logging::Appender[NAME] = nil
86
+ end
87
+ end
88
+
89
+ end # class TestFile
90
+
91
+ end # module TestAppenders
92
+ end # module TestLogging
93
+
94
+ # EOF
@@ -0,0 +1,115 @@
1
+ # $Id$
2
+
3
+ require File.join(File.dirname(__FILE__), %w[.. setup])
4
+ require 'flexmock'
5
+
6
+ module TestLogging
7
+ module TestAppenders
8
+
9
+ class TestGrowl < Test::Unit::TestCase
10
+ include FlexMock::TestCase
11
+ include LoggingTestCase
12
+
13
+ def setup
14
+ super
15
+ ::Logging.init
16
+ @levels = ::Logging::LEVELS
17
+
18
+ @appender = ::Logging::Appenders::Growl.new('growl',
19
+ :coalesce => true, :separator => "\000",
20
+ :layout => Logging::Layouts::Pattern.new(:pattern => "%5l - Test\000%m")
21
+ )
22
+ @appender.level = :all
23
+ @growl = @appender.instance_variable_get(:@growl).dup
24
+ end
25
+
26
+ def test_initialize
27
+ assert_equal('growlnotify -w -n "growl" -t "%s" -m "%s" -p %d &',
28
+ @appender.instance_variable_get(:@growl))
29
+ assert_equal(true, @appender.instance_variable_get(:@coalesce))
30
+ assert_equal("\000", @appender.instance_variable_get(:@title_sep))
31
+ end
32
+
33
+ def test_append
34
+ info = ::Logging::LogEvent.new('TestLogger', @levels['info'],
35
+ 'info message', false)
36
+ warn = ::Logging::LogEvent.new('TestLogger', @levels['warn'],
37
+ 'warning message', false)
38
+
39
+ flexmock(@appender).should_receive(:system).once.with(
40
+ @growl % ['WARN - Test', "warning message\nwarning message\nwarning message", 0])
41
+
42
+ flexmock(@appender).should_receive(:system).once.with(
43
+ @growl % ['INFO - Test', "info message\ninfo message", -1])
44
+
45
+ flexmock(@appender).should_receive(:system).once.with(
46
+ @growl % ['WARN - Test', "warning message", 0])
47
+
48
+ @appender.append warn
49
+ @appender.append warn
50
+ @appender.append warn
51
+ @appender.append info
52
+ @appender.append info
53
+ @appender.append warn
54
+ sleep 0.7 # give the coalescing thread time to run
55
+ end
56
+
57
+ def test_append_without_coalescing
58
+ @appender.instance_variable_set(:@coalesce, false)
59
+ event = ::Logging::LogEvent.new('TestLogger', @levels['warn'],
60
+ 'warning message', false)
61
+
62
+ flexmock(@appender).should_receive(:system).twice.with(
63
+ @growl % ['WARN - Test', 'warning message', 0])
64
+
65
+ @appender.append event
66
+ @appender.append event
67
+ end
68
+
69
+ def test_concat
70
+ flexmock(@appender).should_receive(:system).once.with(
71
+ @growl % ['', "first message\nsecond message\nthird message", 0])
72
+
73
+ @appender << 'first message'
74
+ @appender << 'second message'
75
+ @appender << 'third message'
76
+ sleep 0.7 # give the coalescing thread time to run
77
+ end
78
+
79
+ def test_concat_without_coalescing
80
+ @appender.instance_variable_set(:@coalesce, false)
81
+
82
+ flexmock(@appender).should_receive(:system).twice.with(
83
+ @growl % ['', 'concat message', 0])
84
+
85
+ @appender << 'concat message'
86
+ @appender << 'concat message'
87
+ end
88
+
89
+ def test_map_eq
90
+ get_map = lambda {@appender.instance_variable_get(:@map)}
91
+ assert_equal([-2,-1,0,1,2], get_map.call)
92
+
93
+ @appender.map = {
94
+ 'fatal' => '0',
95
+ :error => -2,
96
+ :warn => '2',
97
+ 'INFO' => 1,
98
+ 'Debug' => -1
99
+ }
100
+ assert_equal([-1,1,2,-2,0], get_map.call)
101
+
102
+ assert_raise(ArgumentError) do
103
+ @appender.map = {:fatal => 'not a number', :error => 2}
104
+ end
105
+
106
+ assert_raise(ArgumentError) do
107
+ @appender.map = {:fatal => -3, :error => 3}
108
+ end
109
+ end
110
+
111
+ end # class TestGrowl
112
+ end # module TestLogging
113
+ end # module TestAppenders
114
+
115
+ # EOF