rails_analyzer_tools 1.1.0 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/Manifest.txt +4 -4
- data/{README → README.txt} +11 -12
- data/Rakefile +13 -57
- data/bin/bench +2 -2
- data/bin/rails_stat +3 -6
- data/lib/analyzer_tools.rb +9 -0
- data/lib/analyzer_tools/bench.rb +1 -1
- data/lib/analyzer_tools/crawl.rb +1 -1
- data/lib/analyzer_tools/rails_stat.rb +93 -31
- metadata +52 -29
- data/lib/analyzer_tools/syslog_logger.rb +0 -171
- data/test/test_syslog_logger.rb +0 -443
data/History.txt
ADDED
data/Manifest.txt
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
+
History.txt
|
1
2
|
Manifest.txt
|
3
|
+
README.txt
|
2
4
|
Rakefile
|
3
|
-
README
|
4
5
|
bin/bench
|
5
6
|
bin/crawl
|
6
7
|
bin/rails_stat
|
7
|
-
lib/
|
8
|
+
lib/analyzer_tools.rb
|
8
9
|
lib/analyzer_tools/bench.rb
|
9
10
|
lib/analyzer_tools/crawl.rb
|
10
11
|
lib/analyzer_tools/rails_stat.rb
|
11
|
-
lib/
|
12
|
-
test/test_syslog_logger.rb
|
12
|
+
lib/io_tail.rb
|
data/{README → README.txt}
RENAMED
@@ -1,12 +1,16 @@
|
|
1
|
-
|
2
|
-
SyslogLogger libraries, and the programs bench, crawl and rails_stat based on
|
3
|
-
these libraries.
|
1
|
+
= rails_analyzer_tools
|
4
2
|
|
5
|
-
|
6
|
-
43things.com, determine if HyperThreading would give a performance benefit or
|
7
|
-
not (it did) and find a fatal threading bug in MySQL.
|
3
|
+
Tools for analyzing the performance of web sites.
|
8
4
|
|
9
|
-
|
5
|
+
Rails Analyzer Tools contains Bench, a simple web page benchmarker,
|
6
|
+
Crawler, a tool for beating up on web sites, RailsStat, a tool for
|
7
|
+
monitoring Rails web sites, and IOTail, a tail(1) method for Ruby IOs.
|
8
|
+
|
9
|
+
http://seattlerb.rubyforge.org/rails_analyzer_tools
|
10
|
+
|
11
|
+
Bug reports:
|
12
|
+
|
13
|
+
http://rubyforge.org/tracker/?func=add&group_id=1513&atid=5921
|
10
14
|
|
11
15
|
== Bench
|
12
16
|
|
@@ -51,11 +55,6 @@ path to your production log for a live Rails site and you're done:
|
|
51
55
|
$ rails_stat /var/log/production.log
|
52
56
|
~ 2.1 req/sec, 23.0 queries/sec, 32.8 lines/sec
|
53
57
|
|
54
|
-
== SyslogLogger
|
55
|
-
|
56
|
-
SyslogLogger is a Logger replacement that logs to syslog. It is almost
|
57
|
-
drop-in with a few caveats.
|
58
|
-
|
59
58
|
== IOTail
|
60
59
|
|
61
60
|
IOTail tails a file like the tail system utility. This lets you collect data
|
data/Rakefile
CHANGED
@@ -1,61 +1,17 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
s.author = 'Eric Hodel'
|
15
|
-
s.email = 'eric@robotcoop.com'
|
16
|
-
|
17
|
-
s.has_rdoc = true
|
18
|
-
s.files = File.read('Manifest.txt').split($/)
|
19
|
-
s.require_path = 'lib'
|
20
|
-
s.executables = %w[rails_stat bench crawl]
|
21
|
-
end
|
22
|
-
|
23
|
-
desc 'Run tests'
|
24
|
-
task :default => [ :test ]
|
25
|
-
|
26
|
-
Rake::TestTask.new('test') do |t|
|
27
|
-
t.libs << 'test'
|
28
|
-
t.libs << 'lib'
|
29
|
-
t.pattern = 'test/test_*.rb'
|
30
|
-
t.verbose = true
|
31
|
-
end
|
32
|
-
|
33
|
-
desc 'Generate RDoc'
|
34
|
-
Rake::RDocTask.new :rdoc do |rd|
|
35
|
-
rd.rdoc_dir = 'doc'
|
36
|
-
rd.rdoc_files.add 'lib', 'README'
|
37
|
-
rd.main = 'README'
|
38
|
-
rd.options << '-d' if `which dot` =~ /\/dot/
|
39
|
-
end
|
40
|
-
|
41
|
-
desc 'Build Gem'
|
42
|
-
Rake::GemPackageTask.new spec do |pkg|
|
43
|
-
pkg.need_tar = true
|
1
|
+
require 'hoe'
|
2
|
+
require './lib/analyzer_tools'
|
3
|
+
|
4
|
+
Hoe.new 'rails_analyzer_tools', AnalyzerTools::VERSION do |p|
|
5
|
+
p.rubyforge_name = 'seattlerb'
|
6
|
+
p.author = 'Eric Hodel'
|
7
|
+
p.email = 'drbrain@segment7.net'
|
8
|
+
p.summary = p.paragraphs_of('README.txt', 1).join ' '
|
9
|
+
p.description = p.paragraphs_of('README.txt', 2).join ' '
|
10
|
+
p.url = p.paragraphs_of('README.txt', 3).join ' '
|
11
|
+
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
12
|
+
|
13
|
+
p.extra_deps << ['SyslogLogger', '>= 1.4.0']
|
44
14
|
end
|
45
15
|
|
46
|
-
desc 'Sends RDoc to RubyForge'
|
47
|
-
task :send_rdoc => [ :rerdoc ] do
|
48
|
-
publisher = Rake::SshDirPublisher.new('drbrain@rubyforge.org',
|
49
|
-
'/var/www/gforge-projects/rails-analyzer/hacks',
|
50
|
-
'doc')
|
51
|
-
publisher.upload
|
52
|
-
end
|
53
|
-
|
54
|
-
desc 'Clean up'
|
55
|
-
task :clean => [ :clobber_rdoc, :clobber_package ]
|
56
|
-
|
57
|
-
desc 'Clean up'
|
58
|
-
task :clobber => [ :clean ]
|
59
|
-
|
60
16
|
# vim: syntax=Ruby
|
61
17
|
|
data/bin/bench
CHANGED
data/bin/rails_stat
CHANGED
@@ -3,13 +3,10 @@
|
|
3
3
|
require 'io_tail'
|
4
4
|
require 'analyzer_tools/rails_stat'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
if filename.nil? then
|
10
|
-
STDERR.puts "Usage: #{$0} RAILS_LOG [PRINT_INTERVAL]"
|
6
|
+
if ARGV.length < 1 then
|
7
|
+
$stderr.puts "Usage: #{$0} RAILS_LOG [...] [PRINT_INTERVAL]"
|
11
8
|
exit 1
|
12
9
|
end
|
13
10
|
|
14
|
-
RailsStat.start
|
11
|
+
RailsStat.start(*ARGV)
|
15
12
|
|
data/lib/analyzer_tools/bench.rb
CHANGED
data/lib/analyzer_tools/crawl.rb
CHANGED
@@ -1,72 +1,133 @@
|
|
1
1
|
require 'thread'
|
2
|
+
require 'curses' rescue nil
|
2
3
|
|
3
4
|
##
|
4
|
-
# RailsStat displays a the current requests
|
5
|
-
#
|
5
|
+
# RailsStat displays a the current requests and lines logged per second.
|
6
|
+
# Default interval is 10 seconds.
|
6
7
|
|
7
8
|
class RailsStat
|
8
|
-
|
9
|
+
|
10
|
+
class << self
|
11
|
+
attr_reader :lines
|
12
|
+
end
|
13
|
+
|
9
14
|
##
|
10
|
-
#
|
15
|
+
# RailsStat.start 'online-43things.log', 'online-43people.log', 10
|
16
|
+
#
|
17
|
+
# Starts a new RailsStat for +filenames+ that prints every +interval+
|
18
|
+
# seconds.
|
19
|
+
#
|
20
|
+
# Stats for multiple log files requires curses.
|
21
|
+
|
22
|
+
def self.start(*args)
|
23
|
+
interval = 10
|
24
|
+
interval = Float(args.pop) if Float(args.last) rescue nil
|
25
|
+
|
26
|
+
stats = []
|
27
|
+
|
28
|
+
if args.length > 1 and not defined? Curses then
|
29
|
+
$stderr.puts "Multiple logfile support requires curses"
|
30
|
+
exit 1
|
31
|
+
end
|
32
|
+
|
33
|
+
if defined? Curses then
|
34
|
+
Curses.init_screen
|
35
|
+
Curses.clear
|
36
|
+
Curses.addstr "Collecting data...\n"
|
37
|
+
Curses.refresh
|
38
|
+
@lines = []
|
39
|
+
end
|
11
40
|
|
12
|
-
|
13
|
-
|
14
|
-
|
41
|
+
args.each_with_index do |filename, offset|
|
42
|
+
stat = self.new File.open(filename), interval, offset
|
43
|
+
stat.start
|
44
|
+
stats << stat
|
15
45
|
end
|
46
|
+
|
47
|
+
stats.each { |stat| stat.thread.join }
|
16
48
|
end
|
17
49
|
|
18
50
|
##
|
19
|
-
#
|
51
|
+
# The log reading thread
|
52
|
+
|
53
|
+
attr_reader :thread
|
54
|
+
|
55
|
+
##
|
56
|
+
# Current status line
|
20
57
|
|
21
|
-
|
58
|
+
attr_reader :status
|
59
|
+
|
60
|
+
##
|
61
|
+
# Creates a new RailsStat that will listen on +io+ and print every
|
62
|
+
# +interval+ seconds. +offset+ is only used for multi-file support.
|
63
|
+
|
64
|
+
def initialize(io, interval, offset = 0)
|
22
65
|
@io = io
|
66
|
+
@io_path = File.basename io.path rescue 'unknown'
|
67
|
+
@interval = interval.to_f
|
68
|
+
@offset = offset
|
69
|
+
|
23
70
|
@mutex = Mutex.new
|
71
|
+
@status = ''
|
72
|
+
@last_len = 0
|
24
73
|
@lines = 0
|
25
74
|
@count = 0
|
26
|
-
@
|
75
|
+
@thread = nil
|
27
76
|
end
|
28
77
|
|
29
78
|
##
|
30
79
|
# Starts the RailsStat running. This method never returns.
|
31
80
|
|
32
|
-
def start
|
33
|
-
trap
|
34
|
-
|
81
|
+
def start
|
82
|
+
trap 'INT' do
|
83
|
+
Curses.close_screen if defined? Curses
|
84
|
+
exit
|
85
|
+
end
|
86
|
+
start_printer
|
35
87
|
read_log
|
36
88
|
end
|
37
89
|
|
90
|
+
def print
|
91
|
+
if defined? Curses then
|
92
|
+
Curses.setpos @offset, 0
|
93
|
+
Curses.addstr ' ' * @last_len
|
94
|
+
Curses.setpos @offset, 0
|
95
|
+
Curses.addstr "#{@io_path}\t#{@status}"
|
96
|
+
Curses.refresh
|
97
|
+
else
|
98
|
+
print "\r"
|
99
|
+
print ' ' * @last_len
|
100
|
+
print "\r"
|
101
|
+
print @status
|
102
|
+
$stdout.flush
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
38
106
|
private
|
39
107
|
|
40
108
|
##
|
41
109
|
# Starts a thread that prints log information every +interval+ seconds.
|
42
110
|
|
43
|
-
def start_printer
|
44
|
-
interval = interval.to_f
|
111
|
+
def start_printer
|
45
112
|
Thread.start do
|
46
|
-
last_len = 0
|
47
113
|
lines_sec = 0
|
48
114
|
count_sec = 0
|
49
|
-
queries_sec = 0
|
50
115
|
|
51
116
|
loop do
|
52
|
-
sleep interval
|
117
|
+
sleep @interval
|
53
118
|
|
54
119
|
@mutex.synchronize do
|
55
|
-
lines_sec = @lines / interval
|
56
|
-
count_sec = @count / interval
|
57
|
-
queries_sec = @queries / interval
|
120
|
+
lines_sec = @lines / @interval
|
121
|
+
count_sec = @count / @interval
|
58
122
|
@lines = 0
|
59
123
|
@count = 0
|
60
|
-
@queries = 0
|
61
124
|
end
|
62
125
|
|
63
|
-
status =
|
64
|
-
count_sec, queries_sec, lines_sec)
|
126
|
+
@status = "%5.1f req/sec, %6.1f lines/sec" % [count_sec, lines_sec]
|
65
127
|
|
66
|
-
print
|
67
|
-
STDOUT.flush
|
128
|
+
print
|
68
129
|
|
69
|
-
last_len = status.length
|
130
|
+
@last_len = status.length
|
70
131
|
end
|
71
132
|
end
|
72
133
|
end
|
@@ -76,10 +137,11 @@ class RailsStat
|
|
76
137
|
# goes.
|
77
138
|
|
78
139
|
def read_log
|
79
|
-
@
|
80
|
-
@
|
81
|
-
|
82
|
-
|
140
|
+
@thread = Thread.start do
|
141
|
+
@io.tail_lines do |line|
|
142
|
+
@mutex.synchronize { @lines += 1 }
|
143
|
+
@mutex.synchronize { @count += 1 } if line =~ /Completed in /
|
144
|
+
end
|
83
145
|
end
|
84
146
|
end
|
85
147
|
|
metadata
CHANGED
@@ -1,53 +1,76 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.
|
2
|
+
rubygems_version: 0.9.2
|
3
3
|
specification_version: 1
|
4
4
|
name: rails_analyzer_tools
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.
|
7
|
-
date:
|
6
|
+
version: 1.4.0
|
7
|
+
date: 2007-05-15 00:00:00 -07:00
|
8
8
|
summary: Tools for analyzing the performance of web sites.
|
9
9
|
require_paths:
|
10
|
-
|
11
|
-
email:
|
12
|
-
homepage:
|
13
|
-
rubyforge_project:
|
14
|
-
description:
|
10
|
+
- lib
|
11
|
+
email: drbrain@segment7.net
|
12
|
+
homepage: http://seattlerb.rubyforge.org/rails_analyzer_tools
|
13
|
+
rubyforge_project: seattlerb
|
14
|
+
description: Rails Analyzer Tools contains Bench, a simple web page benchmarker, Crawler, a tool for beating up on web sites, RailsStat, a tool for monitoring Rails web sites, and IOTail, a tail(1) method for Ruby IOs.
|
15
15
|
autorequire:
|
16
16
|
default_executable:
|
17
17
|
bindir: bin
|
18
18
|
has_rdoc: true
|
19
19
|
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
20
|
requirements:
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
version: 0.0.0
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
25
24
|
version:
|
26
25
|
platform: ruby
|
27
26
|
signing_key:
|
28
27
|
cert_chain:
|
28
|
+
post_install_message:
|
29
29
|
authors:
|
30
|
-
|
30
|
+
- Eric Hodel
|
31
31
|
files:
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
32
|
+
- History.txt
|
33
|
+
- Manifest.txt
|
34
|
+
- README.txt
|
35
|
+
- Rakefile
|
36
|
+
- bin/bench
|
37
|
+
- bin/crawl
|
38
|
+
- bin/rails_stat
|
39
|
+
- lib/analyzer_tools.rb
|
40
|
+
- lib/analyzer_tools/bench.rb
|
41
|
+
- lib/analyzer_tools/crawl.rb
|
42
|
+
- lib/analyzer_tools/rails_stat.rb
|
43
|
+
- lib/io_tail.rb
|
44
44
|
test_files: []
|
45
|
+
|
45
46
|
rdoc_options: []
|
47
|
+
|
46
48
|
extra_rdoc_files: []
|
49
|
+
|
47
50
|
executables:
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
+
- bench
|
52
|
+
- crawl
|
53
|
+
- rails_stat
|
51
54
|
extensions: []
|
55
|
+
|
52
56
|
requirements: []
|
53
|
-
|
57
|
+
|
58
|
+
dependencies:
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: SyslogLogger
|
61
|
+
version_requirement:
|
62
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: 1.4.0
|
67
|
+
version:
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: hoe
|
70
|
+
version_requirement:
|
71
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.2.0
|
76
|
+
version:
|
@@ -1,171 +0,0 @@
|
|
1
|
-
require 'syslog'
|
2
|
-
require 'logger'
|
3
|
-
|
4
|
-
##
|
5
|
-
# SyslogLogger is a Logger work-alike that logs via syslog instead of to a
|
6
|
-
# file. You can add SyslogLogger to your Rails production environment to
|
7
|
-
# aggregate logs between multiple machines.
|
8
|
-
#
|
9
|
-
# By default, SyslogLogger uses the program name 'rails', but this can be
|
10
|
-
# changed via the first argument to SyslogLogger.new.
|
11
|
-
#
|
12
|
-
# NOTE! You can only set the SyslogLogger program name when you initialize
|
13
|
-
# SyslogLogger for the first time. This is a limitation of the way
|
14
|
-
# SyslogLogger uses syslog (and in some ways, a the way syslog(3) works).
|
15
|
-
# Attempts to change SyslogLogger's program name after the first
|
16
|
-
# initialization will be ignored.
|
17
|
-
#
|
18
|
-
# = Sample usage with Rails
|
19
|
-
#
|
20
|
-
# == config/environment/production.rb
|
21
|
-
#
|
22
|
-
# Add the following lines:
|
23
|
-
#
|
24
|
-
# require 'production_log/syslog_logger'
|
25
|
-
# RAILS_DEFAULT_LOGGER = SyslogLogger.new
|
26
|
-
#
|
27
|
-
# == config/environment.rb
|
28
|
-
#
|
29
|
-
# In 0.10.0, change this line:
|
30
|
-
#
|
31
|
-
# RAILS_DEFAULT_LOGGER = Logger.new("#{RAILS_ROOT}/log/#{RAILS_ENV}.log")
|
32
|
-
#
|
33
|
-
# to:
|
34
|
-
#
|
35
|
-
# RAILS_DEFAULT_LOGGER ||= Logger.new("#{RAILS_ROOT}/log/#{RAILS_ENV}.log")
|
36
|
-
#
|
37
|
-
# Other versions of Rails should have a similar change.
|
38
|
-
#
|
39
|
-
# == /etc/syslog.conf
|
40
|
-
#
|
41
|
-
# Add the following lines:
|
42
|
-
#
|
43
|
-
# !rails
|
44
|
-
# *.* /var/log/production.log
|
45
|
-
#
|
46
|
-
# Then touch /var/log/production.log and signal syslogd with a HUP
|
47
|
-
# (killall -HUP syslogd, on FreeBSD).
|
48
|
-
#
|
49
|
-
# == /etc/newsyslog.conf
|
50
|
-
#
|
51
|
-
# Add the following line:
|
52
|
-
#
|
53
|
-
# /var/log/production.log 640 7 * @T00 Z
|
54
|
-
#
|
55
|
-
# This creates a log file that is rotated every day at midnight, gzip'd, then
|
56
|
-
# kept for 7 days. Consult newsyslog.conf(5) for more details.
|
57
|
-
#
|
58
|
-
# Now restart your Rails app. Your production logs should now be showing up
|
59
|
-
# in /var/log/production.log. If you have mulitple machines, you can log them
|
60
|
-
# all to a central machine with remote syslog logging for analysis. Consult
|
61
|
-
# your syslogd(8) manpage for further details.
|
62
|
-
|
63
|
-
class SyslogLogger
|
64
|
-
|
65
|
-
##
|
66
|
-
# Maps Logger warning types to syslog(3) warning types.
|
67
|
-
|
68
|
-
LOGGER_MAP = {
|
69
|
-
:unknown => :alert,
|
70
|
-
:fatal => :err,
|
71
|
-
:error => :warning,
|
72
|
-
:warn => :notice,
|
73
|
-
:info => :info,
|
74
|
-
:debug => :debug,
|
75
|
-
}
|
76
|
-
|
77
|
-
##
|
78
|
-
# Maps Logger log levels to their values so we can silence.
|
79
|
-
|
80
|
-
LOGGER_LEVEL_MAP = {}
|
81
|
-
|
82
|
-
LOGGER_MAP.each_key do |key|
|
83
|
-
LOGGER_LEVEL_MAP[key] = Logger.const_get key.to_s.upcase
|
84
|
-
end
|
85
|
-
|
86
|
-
##
|
87
|
-
# Maps Logger log level values to syslog log levels.
|
88
|
-
|
89
|
-
LEVEL_LOGGER_MAP = {}
|
90
|
-
|
91
|
-
LOGGER_LEVEL_MAP.invert.each do |level, severity|
|
92
|
-
LEVEL_LOGGER_MAP[level] = LOGGER_MAP[severity]
|
93
|
-
end
|
94
|
-
|
95
|
-
##
|
96
|
-
# Builds a logging method for level +meth+.
|
97
|
-
|
98
|
-
def self.log_method(meth)
|
99
|
-
eval <<-EOM, nil, __FILE__, __LINE__ + 1
|
100
|
-
def #{meth}(message = nil)
|
101
|
-
return true if #{LOGGER_LEVEL_MAP[meth]} < @level
|
102
|
-
SYSLOG.#{LOGGER_MAP[meth]} clean(message || yield)
|
103
|
-
return true
|
104
|
-
end
|
105
|
-
EOM
|
106
|
-
end
|
107
|
-
|
108
|
-
LOGGER_MAP.each_key do |level|
|
109
|
-
log_method level
|
110
|
-
end
|
111
|
-
|
112
|
-
##
|
113
|
-
# Log level for Logger compatibility.
|
114
|
-
|
115
|
-
attr_accessor :level
|
116
|
-
|
117
|
-
##
|
118
|
-
# Fills in variables for Logger compatibility. If this is the first
|
119
|
-
# instance of SyslogLogger, +program_name+ may be set to change the logged
|
120
|
-
# program name.
|
121
|
-
#
|
122
|
-
# Due to the way syslog works, only one program name may be chosen.
|
123
|
-
|
124
|
-
def initialize(program_name = 'rails')
|
125
|
-
@level = Logger::DEBUG
|
126
|
-
|
127
|
-
return if defined? SYSLOG
|
128
|
-
self.class.const_set :SYSLOG, Syslog.open(program_name)
|
129
|
-
end
|
130
|
-
|
131
|
-
##
|
132
|
-
# Almost duplicates Logger#add. +progname+ is ignored.
|
133
|
-
|
134
|
-
def add(severity, message = nil, progname = nil, &block)
|
135
|
-
severity ||= Logger::UNKNOWN
|
136
|
-
return true if severity < @level
|
137
|
-
message = clean(message || block.call)
|
138
|
-
SYSLOG.send LEVEL_LOGGER_MAP[severity], clean(message)
|
139
|
-
return true
|
140
|
-
end
|
141
|
-
|
142
|
-
##
|
143
|
-
# Allows messages of a particular log level to be ignored temporarily.
|
144
|
-
#
|
145
|
-
# Can you say "Broken Windows"?
|
146
|
-
|
147
|
-
def silence(temporary_level = Logger::ERROR)
|
148
|
-
old_logger_level = @level
|
149
|
-
@level = temporary_level
|
150
|
-
yield
|
151
|
-
ensure
|
152
|
-
@level = old_logger_level
|
153
|
-
end
|
154
|
-
|
155
|
-
private
|
156
|
-
|
157
|
-
##
|
158
|
-
# Clean up messages so they're nice and pretty.
|
159
|
-
|
160
|
-
def clean(message)
|
161
|
-
message = message.to_s.dup
|
162
|
-
message.strip!
|
163
|
-
message.gsub!(/%/, '%%') # syslog(3) freaks on % (printf)
|
164
|
-
message.gsub!(/\e\[[^m]*m/, '') # remove useless ansi color codes
|
165
|
-
return message
|
166
|
-
end
|
167
|
-
|
168
|
-
end
|
169
|
-
|
170
|
-
# vim: ts=4 sts=4 sw=4
|
171
|
-
|
data/test/test_syslog_logger.rb
DELETED
@@ -1,443 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require 'tempfile'
|
3
|
-
require 'analyzer_tools/syslog_logger'
|
4
|
-
|
5
|
-
module MockSyslog; end
|
6
|
-
|
7
|
-
class << MockSyslog
|
8
|
-
|
9
|
-
@line = nil
|
10
|
-
|
11
|
-
SyslogLogger::LOGGER_MAP.values.uniq.each do |level|
|
12
|
-
eval <<-EOM
|
13
|
-
def #{level}(message)
|
14
|
-
@line = "#{level.to_s.upcase} - \#{message}"
|
15
|
-
end
|
16
|
-
EOM
|
17
|
-
end
|
18
|
-
|
19
|
-
attr_reader :line
|
20
|
-
attr_reader :program_name
|
21
|
-
|
22
|
-
def open(program_name)
|
23
|
-
@program_name = program_name
|
24
|
-
end
|
25
|
-
|
26
|
-
def reset
|
27
|
-
@line = ''
|
28
|
-
end
|
29
|
-
|
30
|
-
end
|
31
|
-
|
32
|
-
SyslogLogger.const_set :SYSLOG, MockSyslog
|
33
|
-
|
34
|
-
class TestLogger < Test::Unit::TestCase
|
35
|
-
|
36
|
-
LEVEL_LABEL_MAP = {
|
37
|
-
Logger::DEBUG => 'DEBUG',
|
38
|
-
Logger::INFO => 'INFO',
|
39
|
-
Logger::WARN => 'WARN',
|
40
|
-
Logger::ERROR => 'ERROR',
|
41
|
-
Logger::FATAL => 'FATAL',
|
42
|
-
Logger::UNKNOWN => 'ANY',
|
43
|
-
}
|
44
|
-
|
45
|
-
def setup
|
46
|
-
@logger = Logger.new(nil)
|
47
|
-
end
|
48
|
-
|
49
|
-
class Log
|
50
|
-
attr_reader :line, :label, :datetime, :pid, :severity, :progname, :msg
|
51
|
-
def initialize(line)
|
52
|
-
@line = line
|
53
|
-
/\A(\w+), \[([^#]*)#(\d+)\]\s+(\w+) -- (\w*): ([\x0-\xff]*)/ =~ @line
|
54
|
-
@label, @datetime, @pid, @severity, @progname, @msg = $1, $2, $3, $4, $5, $6
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
def log_add(severity, msg, progname = nil, &block)
|
59
|
-
log(:add, severity, msg, progname, &block)
|
60
|
-
end
|
61
|
-
|
62
|
-
def log(msg_id, *arg, &block)
|
63
|
-
Log.new(log_raw(msg_id, *arg, &block))
|
64
|
-
end
|
65
|
-
|
66
|
-
def log_raw(msg_id, *arg, &block)
|
67
|
-
logdev = Tempfile.new(File.basename(__FILE__) + '.log')
|
68
|
-
@logger.instance_eval { @logdev = Logger::LogDevice.new(logdev) }
|
69
|
-
assert_equal true, @logger.__send__(msg_id, *arg, &block)
|
70
|
-
logdev.open
|
71
|
-
msg = logdev.read
|
72
|
-
logdev.close
|
73
|
-
msg
|
74
|
-
end
|
75
|
-
|
76
|
-
def test_initialize
|
77
|
-
assert_equal Logger::DEBUG, @logger.level
|
78
|
-
end
|
79
|
-
|
80
|
-
def test_add
|
81
|
-
msg = log_add nil, 'unknown level message' # nil == unknown
|
82
|
-
assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
|
83
|
-
|
84
|
-
msg = log_add Logger::FATAL, 'fatal level message'
|
85
|
-
assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
|
86
|
-
|
87
|
-
msg = log_add Logger::ERROR, 'error level message'
|
88
|
-
assert_equal LEVEL_LABEL_MAP[Logger::ERROR], msg.severity
|
89
|
-
|
90
|
-
msg = log_add Logger::WARN, 'warn level message'
|
91
|
-
assert_equal LEVEL_LABEL_MAP[Logger::WARN], msg.severity
|
92
|
-
|
93
|
-
msg = log_add Logger::INFO, 'info level message'
|
94
|
-
assert_equal LEVEL_LABEL_MAP[Logger::INFO], msg.severity
|
95
|
-
|
96
|
-
msg = log_add Logger::DEBUG, 'debug level message'
|
97
|
-
assert_equal LEVEL_LABEL_MAP[Logger::DEBUG], msg.severity
|
98
|
-
end
|
99
|
-
|
100
|
-
def test_add_level_unknown
|
101
|
-
@logger.level = Logger::UNKNOWN
|
102
|
-
|
103
|
-
msg = log_add nil, 'unknown level message' # nil == unknown
|
104
|
-
assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
|
105
|
-
|
106
|
-
msg = log_add Logger::FATAL, 'fatal level message'
|
107
|
-
assert_equal '', msg.line
|
108
|
-
|
109
|
-
msg = log_add Logger::ERROR, 'error level message'
|
110
|
-
assert_equal '', msg.line
|
111
|
-
|
112
|
-
msg = log_add Logger::WARN, 'warn level message'
|
113
|
-
assert_equal '', msg.line
|
114
|
-
|
115
|
-
msg = log_add Logger::INFO, 'info level message'
|
116
|
-
assert_equal '', msg.line
|
117
|
-
|
118
|
-
msg = log_add Logger::DEBUG, 'debug level message'
|
119
|
-
assert_equal '', msg.line
|
120
|
-
end
|
121
|
-
|
122
|
-
def test_add_level_fatal
|
123
|
-
@logger.level = Logger::FATAL
|
124
|
-
|
125
|
-
msg = log_add nil, 'unknown level message' # nil == unknown
|
126
|
-
assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
|
127
|
-
|
128
|
-
msg = log_add Logger::FATAL, 'fatal level message'
|
129
|
-
assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
|
130
|
-
|
131
|
-
msg = log_add Logger::ERROR, 'error level message'
|
132
|
-
assert_equal '', msg.line
|
133
|
-
|
134
|
-
msg = log_add Logger::WARN, 'warn level message'
|
135
|
-
assert_equal '', msg.line
|
136
|
-
|
137
|
-
msg = log_add Logger::INFO, 'info level message'
|
138
|
-
assert_equal '', msg.line
|
139
|
-
|
140
|
-
msg = log_add Logger::DEBUG, 'debug level message'
|
141
|
-
assert_equal '', msg.line
|
142
|
-
end
|
143
|
-
|
144
|
-
def test_add_level_error
|
145
|
-
@logger.level = Logger::ERROR
|
146
|
-
|
147
|
-
msg = log_add nil, 'unknown level message' # nil == unknown
|
148
|
-
assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
|
149
|
-
|
150
|
-
msg = log_add Logger::FATAL, 'fatal level message'
|
151
|
-
assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
|
152
|
-
|
153
|
-
msg = log_add Logger::ERROR, 'error level message'
|
154
|
-
assert_equal LEVEL_LABEL_MAP[Logger::ERROR], msg.severity
|
155
|
-
|
156
|
-
msg = log_add Logger::WARN, 'warn level message'
|
157
|
-
assert_equal '', msg.line
|
158
|
-
|
159
|
-
msg = log_add Logger::INFO, 'info level message'
|
160
|
-
assert_equal '', msg.line
|
161
|
-
|
162
|
-
msg = log_add Logger::DEBUG, 'debug level message'
|
163
|
-
assert_equal '', msg.line
|
164
|
-
end
|
165
|
-
|
166
|
-
def test_add_level_warn
|
167
|
-
@logger.level = Logger::WARN
|
168
|
-
|
169
|
-
msg = log_add nil, 'unknown level message' # nil == unknown
|
170
|
-
assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
|
171
|
-
|
172
|
-
msg = log_add Logger::FATAL, 'fatal level message'
|
173
|
-
assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
|
174
|
-
|
175
|
-
msg = log_add Logger::ERROR, 'error level message'
|
176
|
-
assert_equal LEVEL_LABEL_MAP[Logger::ERROR], msg.severity
|
177
|
-
|
178
|
-
msg = log_add Logger::WARN, 'warn level message'
|
179
|
-
assert_equal LEVEL_LABEL_MAP[Logger::WARN], msg.severity
|
180
|
-
|
181
|
-
msg = log_add Logger::INFO, 'info level message'
|
182
|
-
assert_equal '', msg.line
|
183
|
-
|
184
|
-
msg = log_add Logger::DEBUG, 'debug level message'
|
185
|
-
assert_equal '', msg.line
|
186
|
-
end
|
187
|
-
|
188
|
-
def test_add_level_info
|
189
|
-
@logger.level = Logger::INFO
|
190
|
-
|
191
|
-
msg = log_add nil, 'unknown level message' # nil == unknown
|
192
|
-
assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
|
193
|
-
|
194
|
-
msg = log_add Logger::FATAL, 'fatal level message'
|
195
|
-
assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
|
196
|
-
|
197
|
-
msg = log_add Logger::ERROR, 'error level message'
|
198
|
-
assert_equal LEVEL_LABEL_MAP[Logger::ERROR], msg.severity
|
199
|
-
|
200
|
-
msg = log_add Logger::WARN, 'warn level message'
|
201
|
-
assert_equal LEVEL_LABEL_MAP[Logger::WARN], msg.severity
|
202
|
-
|
203
|
-
msg = log_add Logger::INFO, 'info level message'
|
204
|
-
assert_equal LEVEL_LABEL_MAP[Logger::INFO], msg.severity
|
205
|
-
|
206
|
-
msg = log_add Logger::DEBUG, 'debug level message'
|
207
|
-
assert_equal '', msg.line
|
208
|
-
end
|
209
|
-
|
210
|
-
def test_add_level_debug
|
211
|
-
@logger.level = Logger::DEBUG
|
212
|
-
|
213
|
-
msg = log_add nil, 'unknown level message' # nil == unknown
|
214
|
-
assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
|
215
|
-
|
216
|
-
msg = log_add Logger::FATAL, 'fatal level message'
|
217
|
-
assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
|
218
|
-
|
219
|
-
msg = log_add Logger::ERROR, 'error level message'
|
220
|
-
assert_equal LEVEL_LABEL_MAP[Logger::ERROR], msg.severity
|
221
|
-
|
222
|
-
msg = log_add Logger::WARN, 'warn level message'
|
223
|
-
assert_equal LEVEL_LABEL_MAP[Logger::WARN], msg.severity
|
224
|
-
|
225
|
-
msg = log_add Logger::INFO, 'info level message'
|
226
|
-
assert_equal LEVEL_LABEL_MAP[Logger::INFO], msg.severity
|
227
|
-
|
228
|
-
msg = log_add Logger::DEBUG, 'debug level message'
|
229
|
-
assert_equal LEVEL_LABEL_MAP[Logger::DEBUG], msg.severity
|
230
|
-
end
|
231
|
-
|
232
|
-
def test_unknown
|
233
|
-
msg = log :unknown, 'unknown level message'
|
234
|
-
assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
|
235
|
-
|
236
|
-
@logger.level = Logger::UNKNOWN
|
237
|
-
msg = log :unknown, 'unknown level message'
|
238
|
-
assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
|
239
|
-
|
240
|
-
@logger.level = Logger::FATAL
|
241
|
-
msg = log :unknown, 'unknown level message'
|
242
|
-
assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
|
243
|
-
|
244
|
-
@logger.level = Logger::ERROR
|
245
|
-
msg = log :unknown, 'unknown level message'
|
246
|
-
assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
|
247
|
-
|
248
|
-
@logger.level = Logger::WARN
|
249
|
-
msg = log :unknown, 'unknown level message'
|
250
|
-
assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
|
251
|
-
|
252
|
-
@logger.level = Logger::INFO
|
253
|
-
msg = log :unknown, 'unknown level message'
|
254
|
-
assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
|
255
|
-
|
256
|
-
@logger.level = Logger::DEBUG
|
257
|
-
msg = log :unknown, 'unknown level message'
|
258
|
-
assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
|
259
|
-
end
|
260
|
-
|
261
|
-
def test_fatal
|
262
|
-
msg = log :fatal, 'fatal level message'
|
263
|
-
assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
|
264
|
-
|
265
|
-
@logger.level = Logger::UNKNOWN
|
266
|
-
msg = log :fatal, 'fatal level message'
|
267
|
-
assert_equal '', msg.line
|
268
|
-
|
269
|
-
@logger.level = Logger::FATAL
|
270
|
-
msg = log :fatal, 'fatal level message'
|
271
|
-
assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
|
272
|
-
|
273
|
-
@logger.level = Logger::ERROR
|
274
|
-
msg = log :fatal, 'fatal level message'
|
275
|
-
assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
|
276
|
-
|
277
|
-
@logger.level = Logger::WARN
|
278
|
-
msg = log :fatal, 'fatal level message'
|
279
|
-
assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
|
280
|
-
|
281
|
-
@logger.level = Logger::INFO
|
282
|
-
msg = log :fatal, 'fatal level message'
|
283
|
-
assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
|
284
|
-
|
285
|
-
@logger.level = Logger::DEBUG
|
286
|
-
msg = log :fatal, 'fatal level message'
|
287
|
-
assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
|
288
|
-
end
|
289
|
-
|
290
|
-
def test_error
|
291
|
-
msg = log :error, 'error level message'
|
292
|
-
assert_equal LEVEL_LABEL_MAP[Logger::ERROR], msg.severity
|
293
|
-
|
294
|
-
@logger.level = Logger::UNKNOWN
|
295
|
-
msg = log :error, 'error level message'
|
296
|
-
assert_equal '', msg.line
|
297
|
-
|
298
|
-
@logger.level = Logger::FATAL
|
299
|
-
msg = log :error, 'error level message'
|
300
|
-
assert_equal '', msg.line
|
301
|
-
|
302
|
-
@logger.level = Logger::ERROR
|
303
|
-
msg = log :error, 'error level message'
|
304
|
-
assert_equal LEVEL_LABEL_MAP[Logger::ERROR], msg.severity
|
305
|
-
|
306
|
-
@logger.level = Logger::WARN
|
307
|
-
msg = log :error, 'error level message'
|
308
|
-
assert_equal LEVEL_LABEL_MAP[Logger::ERROR], msg.severity
|
309
|
-
|
310
|
-
@logger.level = Logger::INFO
|
311
|
-
msg = log :error, 'error level message'
|
312
|
-
assert_equal LEVEL_LABEL_MAP[Logger::ERROR], msg.severity
|
313
|
-
|
314
|
-
@logger.level = Logger::DEBUG
|
315
|
-
msg = log :error, 'error level message'
|
316
|
-
assert_equal LEVEL_LABEL_MAP[Logger::ERROR], msg.severity
|
317
|
-
end
|
318
|
-
|
319
|
-
def test_warn
|
320
|
-
msg = log :warn, 'warn level message'
|
321
|
-
assert_equal LEVEL_LABEL_MAP[Logger::WARN], msg.severity
|
322
|
-
|
323
|
-
@logger.level = Logger::UNKNOWN
|
324
|
-
msg = log :warn, 'warn level message'
|
325
|
-
assert_equal '', msg.line
|
326
|
-
|
327
|
-
@logger.level = Logger::FATAL
|
328
|
-
msg = log :warn, 'warn level message'
|
329
|
-
assert_equal '', msg.line
|
330
|
-
|
331
|
-
@logger.level = Logger::ERROR
|
332
|
-
msg = log :warn, 'warn level message'
|
333
|
-
assert_equal '', msg.line
|
334
|
-
|
335
|
-
@logger.level = Logger::WARN
|
336
|
-
msg = log :warn, 'warn level message'
|
337
|
-
assert_equal LEVEL_LABEL_MAP[Logger::WARN], msg.severity
|
338
|
-
|
339
|
-
@logger.level = Logger::INFO
|
340
|
-
msg = log :warn, 'warn level message'
|
341
|
-
assert_equal LEVEL_LABEL_MAP[Logger::WARN], msg.severity
|
342
|
-
|
343
|
-
@logger.level = Logger::DEBUG
|
344
|
-
msg = log :warn, 'warn level message'
|
345
|
-
assert_equal LEVEL_LABEL_MAP[Logger::WARN], msg.severity
|
346
|
-
end
|
347
|
-
|
348
|
-
def test_info
|
349
|
-
msg = log :info, 'info level message'
|
350
|
-
assert_equal LEVEL_LABEL_MAP[Logger::INFO], msg.severity
|
351
|
-
|
352
|
-
@logger.level = Logger::UNKNOWN
|
353
|
-
msg = log :info, 'info level message'
|
354
|
-
assert_equal '', msg.line
|
355
|
-
|
356
|
-
@logger.level = Logger::FATAL
|
357
|
-
msg = log :info, 'info level message'
|
358
|
-
assert_equal '', msg.line
|
359
|
-
|
360
|
-
@logger.level = Logger::ERROR
|
361
|
-
msg = log :info, 'info level message'
|
362
|
-
assert_equal '', msg.line
|
363
|
-
|
364
|
-
@logger.level = Logger::WARN
|
365
|
-
msg = log :info, 'info level message'
|
366
|
-
assert_equal '', msg.line
|
367
|
-
|
368
|
-
@logger.level = Logger::INFO
|
369
|
-
msg = log :info, 'info level message'
|
370
|
-
assert_equal LEVEL_LABEL_MAP[Logger::INFO], msg.severity
|
371
|
-
|
372
|
-
@logger.level = Logger::DEBUG
|
373
|
-
msg = log :info, 'info level message'
|
374
|
-
assert_equal LEVEL_LABEL_MAP[Logger::INFO], msg.severity
|
375
|
-
end
|
376
|
-
|
377
|
-
def test_debug
|
378
|
-
msg = log :debug, 'debug level message'
|
379
|
-
assert_equal LEVEL_LABEL_MAP[Logger::DEBUG], msg.severity
|
380
|
-
|
381
|
-
@logger.level = Logger::UNKNOWN
|
382
|
-
msg = log :debug, 'debug level message'
|
383
|
-
assert_equal '', msg.line
|
384
|
-
|
385
|
-
@logger.level = Logger::FATAL
|
386
|
-
msg = log :debug, 'debug level message'
|
387
|
-
assert_equal '', msg.line
|
388
|
-
|
389
|
-
@logger.level = Logger::ERROR
|
390
|
-
msg = log :debug, 'debug level message'
|
391
|
-
assert_equal '', msg.line
|
392
|
-
|
393
|
-
@logger.level = Logger::WARN
|
394
|
-
msg = log :debug, 'debug level message'
|
395
|
-
assert_equal '', msg.line
|
396
|
-
|
397
|
-
@logger.level = Logger::INFO
|
398
|
-
msg = log :debug, 'debug level message'
|
399
|
-
assert_equal '', msg.line
|
400
|
-
|
401
|
-
@logger.level = Logger::DEBUG
|
402
|
-
msg = log :debug, 'debug level message'
|
403
|
-
assert_equal LEVEL_LABEL_MAP[Logger::DEBUG], msg.severity
|
404
|
-
end
|
405
|
-
|
406
|
-
end
|
407
|
-
|
408
|
-
class TestSyslogLogger < TestLogger
|
409
|
-
|
410
|
-
def setup
|
411
|
-
super
|
412
|
-
@logger = SyslogLogger.new
|
413
|
-
end
|
414
|
-
|
415
|
-
class Log
|
416
|
-
attr_reader :line, :label, :datetime, :pid, :severity, :progname, :msg
|
417
|
-
def initialize(line)
|
418
|
-
@line = line
|
419
|
-
return unless /\A(\w+) - (.*)\Z/ =~ @line
|
420
|
-
severity, @msg = $1, $2
|
421
|
-
severity = SyslogLogger::LOGGER_MAP.invert[severity.downcase.intern]
|
422
|
-
@severity = severity.to_s.upcase
|
423
|
-
@severity = 'ANY' if @severity == 'UNKNOWN'
|
424
|
-
end
|
425
|
-
end
|
426
|
-
|
427
|
-
def log_add(severity, msg, progname = nil, &block)
|
428
|
-
log(:add, severity, msg, progname, &block)
|
429
|
-
end
|
430
|
-
|
431
|
-
def log(msg_id, *arg, &block)
|
432
|
-
Log.new(log_raw(msg_id, *arg, &block))
|
433
|
-
end
|
434
|
-
|
435
|
-
def log_raw(msg_id, *arg, &block)
|
436
|
-
assert_equal true, @logger.__send__(msg_id, *arg, &block)
|
437
|
-
msg = MockSyslog.line
|
438
|
-
MockSyslog.reset
|
439
|
-
return msg
|
440
|
-
end
|
441
|
-
|
442
|
-
end
|
443
|
-
|