tagged_logger 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -1
- data/README.html +91 -0
- data/README.markdown +90 -0
- data/Rakefile +0 -64
- data/VERSION +1 -1
- data/examples/one_log_per_classes.rb +1 -3
- data/examples/one_tag_per_classes.rb +1 -1
- data/examples/per_class_customization.rb +2 -5
- data/examples/rule_with_regex.rb +1 -3
- data/examples/simplest_customization.rb +1 -1
- data/examples/simplest_usage.rb +1 -1
- data/lib/tagged_logger.rb +11 -7
- data/tagged_logger.gemspec +7 -71
- data/test/test.rb +99 -88
- data/todo.txt +1 -0
- metadata +8 -70
- data/README.rdoc +0 -63
- data/active.log +0 -2
- data/database.log +0 -2
- data/network.log +0 -2
data/.gitignore
CHANGED
data/README.html
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<!DOCTYPE html PUBLIC
|
3
|
+
"-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN"
|
4
|
+
"http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">
|
5
|
+
<html xmlns:svg='http://www.w3.org/2000/svg' xml:lang='en' xmlns='http://www.w3.org/1999/xhtml'>
|
6
|
+
<head><meta content='application/xhtml+xml;charset=utf-8' http-equiv='Content-type' /><title>TaggedLogger</title></head>
|
7
|
+
<body>
|
8
|
+
<h1 id='taggedlogger'>TaggedLogger</h1>
|
9
|
+
|
10
|
+
<p>Detaches <strong>what</strong> is logged from <strong>how</strong> it is logged.</p>
|
11
|
+
|
12
|
+
<h2 id='what_is_it_for'>What is it for?</h2>
|
13
|
+
|
14
|
+
<p>Everytime you want to log something, simply write:</p>
|
15
|
+
|
16
|
+
<pre><code>logger.debug("verbose debug information") #warn, #info, #error, #fatal also work</code></pre>
|
17
|
+
|
18
|
+
<p>and do not worry about what kind of logger you use and how your code accesses it. You may confugure these things later, one day writing to STDOUT works for you, another day you’ll need something more sofisticated - like several log files each serving different components, and for different audience.</p>
|
19
|
+
|
20
|
+
<h2 id='installation'>Installation</h2>
|
21
|
+
|
22
|
+
<pre><code>$ sudo gem install tagged_logger --source=http://gemcutter.org</code></pre>
|
23
|
+
|
24
|
+
<h2 id='usage'>Usage</h2>
|
25
|
+
|
26
|
+
<p>The simplest way to turn logging on for every class whose methods calls <em>#logger</em></p>
|
27
|
+
|
28
|
+
<pre><code>TaggedLogger.rules do
|
29
|
+
out_everything_to Logger.new(STDOUT)
|
30
|
+
end</code></pre>
|
31
|
+
|
32
|
+
<p>From now on you may call <em>#logger</em> from anywhere, for example:</p>
|
33
|
+
|
34
|
+
<pre><code>class IWantToLogThis
|
35
|
+
def foo
|
36
|
+
logger.warn "foo"
|
37
|
+
end
|
38
|
+
end</code></pre>
|
39
|
+
|
40
|
+
<p>and after execution of:</p>
|
41
|
+
|
42
|
+
<pre><code>IWantToLogThis.new.foo</code></pre>
|
43
|
+
|
44
|
+
<p>you will see somewhat like:</p>
|
45
|
+
|
46
|
+
<pre><code>W, [2009-12-20T21:45:02.443524 #37166] WARN -- : IWantToLogThis: foo</code></pre>
|
47
|
+
|
48
|
+
<p>You may define your own formatting:</p>
|
49
|
+
|
50
|
+
<pre><code>TaggedLogger.rules do
|
51
|
+
out /.*/ do |level, tag, msg|
|
52
|
+
puts "#{level}-#{tag}: #{msg}"
|
53
|
+
end
|
54
|
+
end</code></pre>
|
55
|
+
|
56
|
+
<p>The ‘/.*/’ says that rule is applied for every class (i.e. class name matches /.*/). The <em>level</em> and <em>msg</em> semantics should be obvious, they are severity threshold and being logged message, but <em>tag</em> is something not so obvious - it is class name whose method calls <em>#logger</em>. In example above tag is “IWantToLogThis” since <em>IWantToLogThis#foo</em> calls <em>#logger</em>. Note the <em>#logger</em> does not have <em>tag</em> parameter - tags defined automatically and they are always class names.</p>
|
57
|
+
|
58
|
+
<p>If you decided to have separate log files for classes <em>Network</em> and <em>Database</em>:</p>
|
59
|
+
|
60
|
+
<pre><code>TaggedLogger.rules do
|
61
|
+
out Network => Logger.new("network.log")
|
62
|
+
out Database => Logger.new("database.log")
|
63
|
+
end</code></pre>
|
64
|
+
|
65
|
+
<p>In case you want to define common log for several classes:</p>
|
66
|
+
|
67
|
+
<pre><code>TaggedLogger.rules do
|
68
|
+
out [Ftp, Http, Sockets] => Logger.new("network.log")
|
69
|
+
end </code></pre>
|
70
|
+
|
71
|
+
<p>Or if you want to have all these classes showing up under common tag <em>Network</em> in standard output:</p>
|
72
|
+
|
73
|
+
<pre><code>TaggedLogger.rules do
|
74
|
+
out_everything_to Logger.new(STDOUT)
|
75
|
+
rename [Ftp, Http, Sockets] => :Network
|
76
|
+
end</code></pre>
|
77
|
+
|
78
|
+
<p>You may also use regular expressions in your rules:</p>
|
79
|
+
|
80
|
+
<pre><code>TaggedLogger.rules do
|
81
|
+
out /Active::/ => Logger.new("active.log")
|
82
|
+
end</code></pre>
|
83
|
+
|
84
|
+
<h2 id='license'>License</h2>
|
85
|
+
|
86
|
+
<p>TaggedLogger is released under the MIT license.</p>
|
87
|
+
|
88
|
+
<h2 id='shortcumings'>Shortcumings</h2>
|
89
|
+
|
90
|
+
<p>Was not tested with <em>log4r</em></p>
|
91
|
+
</body></html>
|
data/README.markdown
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
# TaggedLogger
|
2
|
+
Detaches **what** is logged from **how** it is logged.
|
3
|
+
|
4
|
+
## What is it for?
|
5
|
+
Every time you want to log something, simply write:
|
6
|
+
|
7
|
+
logger.debug("verbose debug information") #warn, #info, #error, #fatal also work
|
8
|
+
|
9
|
+
and do not worry about what kind of logger you use and how your code accesses it.
|
10
|
+
You may configure these things later, one day writing to STDOUT works for you, another
|
11
|
+
day you'll need something more sophisticated, like several log files each serving
|
12
|
+
different components and for different audience.
|
13
|
+
|
14
|
+
## Installation
|
15
|
+
$ sudo gem install tagged_logger --source=http://gemcutter.org
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
The simplest way to turn logging on for every class whose methods calls *#logger*
|
20
|
+
|
21
|
+
TaggedLogger.rules do
|
22
|
+
output_everything_to Logger.new(STDOUT)
|
23
|
+
end
|
24
|
+
|
25
|
+
From now on you may call *#logger* from anywhere, for example:
|
26
|
+
|
27
|
+
class IWantToLogThis
|
28
|
+
def foo
|
29
|
+
logger.warn "foo"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
and after execution of:
|
34
|
+
|
35
|
+
IWantToLogThis.new.foo
|
36
|
+
|
37
|
+
you will see somewhat like:
|
38
|
+
|
39
|
+
W, [2009-12-20T21:45:02.443524 #37166] WARN -- : IWantToLogThis: foo
|
40
|
+
|
41
|
+
|
42
|
+
You may define your own formatting:
|
43
|
+
|
44
|
+
TaggedLogger.rules do
|
45
|
+
output /.*/ do |level, tag, msg|
|
46
|
+
puts "#{level}-#{tag}: #{msg}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
The '/.\*/' says that rule is applied for every class (i.e. class name matches /.\*/).
|
51
|
+
The *level* and *msg* semantics should be obvious, they are severity threshold
|
52
|
+
and being logged message, but *tag* is something not so obvious - it is class name whose
|
53
|
+
method calls *#logger*. In example above tag is "IWantToLogThis" since *IWantToLogThis#foo*
|
54
|
+
calls *#logger*. Note the *#logger* does not have *tag* parameter - tags defined automatically
|
55
|
+
and they are always class names.
|
56
|
+
|
57
|
+
|
58
|
+
If you decided to have separate log files for classes *Network* and *Database*:
|
59
|
+
|
60
|
+
TaggedLogger.rules do
|
61
|
+
output Network => Logger.new("network.log")
|
62
|
+
output Database => Logger.new("database.log")
|
63
|
+
end
|
64
|
+
|
65
|
+
In case you want to define common log for several classes:
|
66
|
+
|
67
|
+
TaggedLogger.rules do
|
68
|
+
output [Ftp, Http, Sockets] => Logger.new("network.log")
|
69
|
+
end
|
70
|
+
|
71
|
+
Or if you want to have all these classes showing up under common
|
72
|
+
tag *Network* in standard output:
|
73
|
+
|
74
|
+
TaggedLogger.rules do
|
75
|
+
output_everything_to Logger.new(STDOUT)
|
76
|
+
rename [Ftp, Http, Sockets] => :Network
|
77
|
+
end
|
78
|
+
|
79
|
+
You may also use regular expressions in your rules:
|
80
|
+
|
81
|
+
TaggedLogger.rules do
|
82
|
+
output /Active::/ => Logger.new("active.log")
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
## License
|
87
|
+
TaggedLogger is released under the MIT license.
|
88
|
+
|
89
|
+
## Shortcomings
|
90
|
+
Was not tested with *log4r*
|
data/Rakefile
CHANGED
@@ -15,70 +15,6 @@ begin
|
|
15
15
|
s.summary = "Detaches _what_ is logged from _how_ it is logged."
|
16
16
|
s.email = "fkocherga@gmail.com"
|
17
17
|
s.homepage = "http://github.com/fkocherga/tagged_logger"
|
18
|
-
s.description = <<'END'
|
19
|
-
This gem supposed to help you to forget about how to expose logging
|
20
|
-
facitilities to the code you write. Any time you want to log something,
|
21
|
-
simply do one of:
|
22
|
-
logger.debug("verbose debug information") #or
|
23
|
-
logger.warn("warning") #or
|
24
|
-
logger.info("information you frequently want to see") #or
|
25
|
-
logger.error("errors") #or
|
26
|
-
logger.fatal("fatal errors")
|
27
|
-
|
28
|
-
and do not worry about where the '#logger' is and what it does at the moment,
|
29
|
-
you will have a chance to configure it in place where you confugure other things.
|
30
|
-
So you may focus on _what_ to put in the logging rather on how to set it up.
|
31
|
-
Later you may turn logging on for specific class or bunch of classes or in case
|
32
|
-
you have special logging demands for specific classes you also may specify it
|
33
|
-
in very simple way.
|
34
|
-
|
35
|
-
The simplest way to turn logging on for every class whose methods calls '#logger':
|
36
|
-
|
37
|
-
TaggedLogger.rules do
|
38
|
-
out_everything_to Logger.new(STDOUT)
|
39
|
-
end
|
40
|
-
|
41
|
-
or you may cook it in your special way:
|
42
|
-
|
43
|
-
TaggedLogger.rules do
|
44
|
-
out /.*/ do |level, tag, msg|
|
45
|
-
puts "#{level}-#{tag}: #{msg}"
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
Where 'tag' is the simple class name whose method calls '#logger'. Note,
|
50
|
-
you do not have to implement '#logger' method anywhere. It gets
|
51
|
-
automatically generated by specifying any of 'out' rules.
|
52
|
-
You may be even more picky about what and where to log. Imagine
|
53
|
-
you have 'Network' and 'Database' classes and you want to have
|
54
|
-
separate log files for them, it is easy:
|
55
|
-
|
56
|
-
TaggedLogger.rules do
|
57
|
-
out Network => Logger.new("network.log")
|
58
|
-
out Database => Logger.new("database.log")
|
59
|
-
end
|
60
|
-
|
61
|
-
In case you want to define common log for several classes:
|
62
|
-
|
63
|
-
TaggedLogger.rules do
|
64
|
-
out [Ftp, Http, Sockets] => Logger.new("network.log")
|
65
|
-
end
|
66
|
-
|
67
|
-
Or if you want to have all these classes showing up under common
|
68
|
-
tag 'Network' in standard output:
|
69
|
-
|
70
|
-
TaggedLogger.rules do
|
71
|
-
out_everything_to Logger.new(STDOUT)
|
72
|
-
rename [Ftp, Http, Sockets] => :Network
|
73
|
-
end
|
74
|
-
|
75
|
-
You may also use regular expressions in your rules:
|
76
|
-
|
77
|
-
TaggedLogger.rules do
|
78
|
-
out /Active::/ => Logger.new("active.log")
|
79
|
-
end
|
80
|
-
|
81
|
-
END
|
82
18
|
s.authors = ["Fedor Kocherga"]
|
83
19
|
s.test_files = ['test/test.rb']
|
84
20
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.1
|
@@ -12,10 +12,8 @@ Ftp = Class.new LogFoo
|
|
12
12
|
Http = Class.new LogFoo
|
13
13
|
Sockets = Class.new LogFoo
|
14
14
|
|
15
|
-
`rm -f network.log`
|
16
15
|
TaggedLogger.rules do
|
17
|
-
|
16
|
+
output [Ftp, Http, Sockets] => Logger.new(open("network.log", "w"))
|
18
17
|
end
|
19
18
|
|
20
19
|
[Ftp, Http, Sockets].each { |c| c.new.foo }
|
21
|
-
IO.foreach('network.log') { |line| puts line }
|
@@ -13,8 +13,8 @@ Http = Class.new { include LogFoo }
|
|
13
13
|
Sockets = Class.new { include LogFoo }
|
14
14
|
|
15
15
|
TaggedLogger.rules do
|
16
|
-
out_everything_to Logger.new(STDOUT)
|
17
16
|
rename [Ftp, Http, Sockets] => :Network
|
17
|
+
output :Network => Logger.new(STDOUT)
|
18
18
|
end
|
19
19
|
|
20
20
|
[Ftp, Http, Sockets].each { |c| c.new.foo }
|
@@ -11,12 +11,9 @@ end
|
|
11
11
|
Database = Class.new LogFoo
|
12
12
|
Network = Class.new LogFoo
|
13
13
|
|
14
|
-
`rm -f network.log`
|
15
|
-
`rm -f database.log`
|
16
|
-
|
17
14
|
TaggedLogger.rules do
|
18
|
-
|
19
|
-
|
15
|
+
output Network => Logger.new(open("network.log", "w"))
|
16
|
+
output Database => Logger.new(open("database.log", "w"))
|
20
17
|
end
|
21
18
|
|
22
19
|
Database.new.foo
|
data/examples/rule_with_regex.rb
CHANGED
data/examples/simplest_usage.rb
CHANGED
data/lib/tagged_logger.rb
CHANGED
@@ -24,23 +24,27 @@ class TaggedLogger
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
27
|
+
def init
|
28
|
+
add_logger_generator_in_Object
|
29
|
+
end
|
30
|
+
|
31
|
+
def output_everything_to(logger = nil, &block)
|
28
32
|
if logger && block
|
29
33
|
raise ArgumentError, "Either block or logger has to be specified, but not both."
|
30
34
|
end
|
31
|
-
|
32
|
-
|
35
|
+
output /.*/ => logger if logger
|
36
|
+
output &block if block
|
33
37
|
end
|
34
38
|
|
35
|
-
def
|
39
|
+
def output(spec, &block)
|
36
40
|
add_logger_generator_in_Object
|
37
41
|
if spec.is_a? Hash
|
38
42
|
spec.each do |what, where|
|
39
|
-
@tag_blocks[tag_matcher(what)] = lambda { |level, tag, msg | where.send(level, "#{tag}: #{msg}") }
|
43
|
+
@tag_blocks[tag_matcher(what)] = lambda { |level, tag, msg | where.send(level, "#{tag}: #{msg}\n") }
|
40
44
|
end
|
41
|
-
raise ArgumentError "No block should be specified in this '
|
45
|
+
raise ArgumentError "No block should be specified in this 'output' rule" if block
|
42
46
|
else
|
43
|
-
raise ArgumentError "Block has to be specified in this '
|
47
|
+
raise ArgumentError "Block has to be specified in this 'output' rule" unless block
|
44
48
|
@tag_blocks[tag_matcher(spec)] = block
|
45
49
|
end
|
46
50
|
end
|
data/tagged_logger.gemspec
CHANGED
@@ -5,86 +5,22 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{tagged_logger}
|
8
|
-
s.version = "0.2.
|
8
|
+
s.version = "0.2.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Fedor Kocherga"]
|
12
|
-
s.date = %q{
|
13
|
-
s.description = %q{This gem supposed to help you to forget about how to expose logging
|
14
|
-
facitilities to the code you write. Any time you want to log something,
|
15
|
-
simply do one of:
|
16
|
-
logger.debug("verbose debug information") #or
|
17
|
-
logger.warn("warning") #or
|
18
|
-
logger.info("information you frequently want to see") #or
|
19
|
-
logger.error("errors") #or
|
20
|
-
logger.fatal("fatal errors")
|
21
|
-
|
22
|
-
and do not worry about where the '#logger' is and what it does at the moment,
|
23
|
-
you will have a chance to configure it in place where you confugure other things.
|
24
|
-
So you may focus on _what_ to put in the logging rather on how to set it up.
|
25
|
-
Later you may turn logging on for specific class or bunch of classes or in case
|
26
|
-
you have special logging demands for specific classes you also may specify it
|
27
|
-
in very simple way.
|
28
|
-
|
29
|
-
The simplest way to turn logging on for every class whose methods calls '#logger':
|
30
|
-
|
31
|
-
TaggedLogger.rules do
|
32
|
-
out_everything_to Logger.new(STDOUT)
|
33
|
-
end
|
34
|
-
|
35
|
-
or you may cook it in your special way:
|
36
|
-
|
37
|
-
TaggedLogger.rules do
|
38
|
-
out /.*/ do |level, tag, msg|
|
39
|
-
puts "#{level}-#{tag}: #{msg}"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
Where 'tag' is the simple class name whose method calls '#logger'. Note,
|
44
|
-
you do not have to implement '#logger' method anywhere. It gets
|
45
|
-
automatically generated by specifying any of 'out' rules.
|
46
|
-
You may be even more picky about what and where to log. Imagine
|
47
|
-
you have 'Network' and 'Database' classes and you want to have
|
48
|
-
separate log files for them, it is easy:
|
49
|
-
|
50
|
-
TaggedLogger.rules do
|
51
|
-
out Network => Logger.new("network.log")
|
52
|
-
out Database => Logger.new("database.log")
|
53
|
-
end
|
54
|
-
|
55
|
-
In case you want to define common log for several classes:
|
56
|
-
|
57
|
-
TaggedLogger.rules do
|
58
|
-
out [Ftp, Http, Sockets] => Logger.new("network.log")
|
59
|
-
end
|
60
|
-
|
61
|
-
Or if you want to have all these classes showing up under common
|
62
|
-
tag 'Network' in standard output:
|
63
|
-
|
64
|
-
TaggedLogger.rules do
|
65
|
-
out_everything_to Logger.new(STDOUT)
|
66
|
-
rename [Ftp, Http, Sockets] => :Network
|
67
|
-
end
|
68
|
-
|
69
|
-
You may also use regular expressions in your rules:
|
70
|
-
|
71
|
-
TaggedLogger.rules do
|
72
|
-
out /Active::/ => Logger.new("active.log")
|
73
|
-
end
|
74
|
-
|
75
|
-
}
|
12
|
+
s.date = %q{2010-01-02}
|
76
13
|
s.email = %q{fkocherga@gmail.com}
|
77
14
|
s.extra_rdoc_files = [
|
78
|
-
"README.
|
15
|
+
"README.html",
|
16
|
+
"README.markdown"
|
79
17
|
]
|
80
18
|
s.files = [
|
81
19
|
".gitignore",
|
82
20
|
"MIT-LICENSE",
|
83
|
-
"README.
|
21
|
+
"README.markdown",
|
84
22
|
"Rakefile",
|
85
23
|
"VERSION",
|
86
|
-
"active.log",
|
87
|
-
"database.log",
|
88
24
|
"examples/one_log_per_classes.rb",
|
89
25
|
"examples/one_tag_per_classes.rb",
|
90
26
|
"examples/per_class_customization.rb",
|
@@ -92,10 +28,10 @@ You may also use regular expressions in your rules:
|
|
92
28
|
"examples/simplest_customization.rb",
|
93
29
|
"examples/simplest_usage.rb",
|
94
30
|
"lib/tagged_logger.rb",
|
95
|
-
"network.log",
|
96
31
|
"tagged_logger.gemspec",
|
97
32
|
"tagged_logger.rb",
|
98
|
-
"test/test.rb"
|
33
|
+
"test/test.rb",
|
34
|
+
"todo.txt"
|
99
35
|
]
|
100
36
|
s.homepage = %q{http://github.com/fkocherga/tagged_logger}
|
101
37
|
s.rdoc_options = ["--charset=UTF-8"]
|
data/test/test.rb
CHANGED
@@ -2,6 +2,7 @@ require 'rubygems'
|
|
2
2
|
require 'test/unit'
|
3
3
|
require 'shoulda'
|
4
4
|
require 'logger'
|
5
|
+
require 'rr'
|
5
6
|
|
6
7
|
require File.dirname(__FILE__) + '/../tagged_logger'
|
7
8
|
|
@@ -15,121 +16,131 @@ class TestLogDevice
|
|
15
16
|
end
|
16
17
|
|
17
18
|
class TaggedLoggerTest < Test::Unit::TestCase
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
include RR::Adapters::TestUnit
|
20
|
+
|
21
|
+
context "@standard_logger writing to device @out1" do
|
22
|
+
setup do
|
21
23
|
@out1 = TestLogDevice.new
|
22
|
-
standard_logger = Logger.new(@out1)
|
24
|
+
@standard_logger = Logger.new(@out1)
|
23
25
|
@formatter = lambda {|severity, datetime, progname, msg| "#{msg}"}
|
24
|
-
standard_logger.formatter = @formatter
|
25
|
-
TaggedLogger.rules do
|
26
|
-
reset
|
27
|
-
out_everything_to standard_logger
|
28
|
-
end
|
26
|
+
@standard_logger.formatter = @formatter
|
29
27
|
end
|
30
28
|
|
31
|
-
should "
|
29
|
+
should "be able to intialize with minimal effort" do
|
30
|
+
TaggedLogger.init
|
31
|
+
dont_allow(@out1).write
|
32
32
|
assert Class.new.methods.include? "logger"
|
33
|
+
assert_nothing_raised { Class.new.logger }
|
33
34
|
end
|
34
35
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
assert_equal "#{obj.class}: #{method}", @out1.to_s
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
context "class A and class B with logging;" do
|
46
|
-
setup do
|
47
|
-
module Foo
|
48
|
-
def foo
|
49
|
-
logger.info("foo")
|
50
|
-
end
|
36
|
+
context "any attempt to log something goes to @standard_logger" do
|
37
|
+
setup do
|
38
|
+
logger = @standard_logger
|
39
|
+
TaggedLogger.rules do
|
40
|
+
reset
|
41
|
+
output_everything_to logger
|
51
42
|
end
|
52
|
-
class A;include Foo; end
|
53
|
-
class B;include Foo; end
|
54
|
-
@a = A.new
|
55
|
-
@b = B.new
|
56
43
|
end
|
57
44
|
|
58
|
-
should "
|
59
|
-
|
60
|
-
|
45
|
+
should "do logging with different levels" do
|
46
|
+
NewClass = Class.new
|
47
|
+
obj = NewClass.new
|
48
|
+
%w[debug info warn error fatal].each do |method|
|
49
|
+
assert obj.logger.methods.include? method
|
50
|
+
obj.logger.send(method.intern, method)
|
51
|
+
assert_equal "#{obj.class}: #{method}\n", @out1.to_s
|
61
52
|
end
|
62
|
-
|
63
|
-
@a.foo
|
64
|
-
assert_equal "TEST: foo", @out1.to_s
|
65
|
-
@out1.clear
|
66
|
-
|
67
|
-
@b.foo
|
68
|
-
assert_equal "TEST: foo", @out1.to_s
|
69
53
|
end
|
70
54
|
|
71
|
-
context "
|
72
|
-
setup do
|
73
|
-
|
74
|
-
|
75
|
-
|
55
|
+
context "class A and class B with logging;" do
|
56
|
+
setup do
|
57
|
+
module Foo
|
58
|
+
def foo
|
59
|
+
logger.info("foo")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
class A;include Foo; end
|
63
|
+
class B;include Foo; end
|
64
|
+
@a = A.new
|
65
|
+
@b = B.new
|
76
66
|
end
|
77
67
|
|
78
|
-
should "be possible to
|
79
|
-
logger2 = @logger2
|
68
|
+
should "be possible to replace tags for A, B classes with single tag TEST making rules for A and B obsolete" do
|
80
69
|
TaggedLogger.rules do
|
81
|
-
|
70
|
+
rename [A,B] => :TEST
|
82
71
|
end
|
72
|
+
|
83
73
|
@a.foo
|
84
|
-
assert_equal "
|
85
|
-
|
86
|
-
|
74
|
+
assert_equal "TEST: foo\n", @out1.to_s
|
75
|
+
@out1.clear
|
76
|
+
|
87
77
|
@b.foo
|
88
|
-
assert_equal "
|
89
|
-
assert_equal "", @out2.to_s
|
78
|
+
assert_equal "TEST: foo\n", @out1.to_s
|
90
79
|
end
|
91
80
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
81
|
+
context "specialized logging" do
|
82
|
+
setup do
|
83
|
+
@out2 = TestLogDevice.new
|
84
|
+
@logger2 = Logger.new(@out2)
|
85
|
+
@logger2.formatter = @formatter
|
86
|
+
end
|
87
|
+
|
88
|
+
should "be possible to speialize logging for tag A by specifying different logger" do
|
89
|
+
logger2 = @logger2
|
90
|
+
TaggedLogger.rules do
|
91
|
+
output A => logger2
|
97
92
|
end
|
93
|
+
@a.foo
|
94
|
+
assert_equal "#{self.class}::A: foo\n", @out1.to_s
|
95
|
+
assert_equal "#{self.class}::A: foo\n", @out2.to_s
|
96
|
+
@out2.clear
|
97
|
+
@b.foo
|
98
|
+
assert_equal "#{self.class}::B: foo\n", @out1.to_s
|
99
|
+
assert_equal "", @out2.to_s
|
98
100
|
end
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
101
|
+
|
102
|
+
should "be possible to speialize logging for tag A by providing block" do
|
103
|
+
logger2 = @logger2
|
104
|
+
TaggedLogger.rules do
|
105
|
+
output A do |level, tag, msg|
|
106
|
+
logger2.send(level, msg)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
@a.foo
|
110
|
+
assert_equal "#{self.class}::A: foo\n", @out1.to_s
|
111
|
+
assert_equal "foo", @out2.to_s
|
112
|
+
@out2.clear
|
113
|
+
@b.foo
|
114
|
+
assert_equal "#{self.class}::B: foo\n", @out1.to_s
|
115
|
+
assert_equal "", @out2.to_s
|
113
116
|
end
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
117
|
+
|
118
|
+
should "be possible to replace tags for A, B classes with single tag TEST and specialize logging for it" do
|
119
|
+
logger2 = @logger2
|
120
|
+
TaggedLogger.rules do
|
121
|
+
rename [A, B] => :TEST
|
122
|
+
output :TEST => logger2
|
123
|
+
end
|
124
|
+
@a.foo
|
125
|
+
assert_equal "TEST: foo\n", @out1.to_s
|
126
|
+
assert_equal "TEST: foo\n", @out2.to_s
|
127
|
+
@out1.clear
|
128
|
+
@out2.clear
|
129
|
+
@b.foo
|
130
|
+
assert_equal "TEST: foo\n", @out1.to_s
|
131
|
+
assert_equal "TEST: foo\n", @out2.to_s
|
132
|
+
end
|
133
|
+
|
134
|
+
should "use default tag equal to class name for class methods" do
|
135
|
+
def A.bar
|
136
|
+
logger.info "bar"
|
137
|
+
end
|
138
|
+
A.bar
|
139
|
+
assert_equal "#{self.class}::A: bar\n", @out1.to_s
|
127
140
|
end
|
128
|
-
A.bar
|
129
|
-
assert_equal "#{self.class}::A: bar", @out1.to_s
|
130
141
|
end
|
142
|
+
|
131
143
|
end
|
132
|
-
|
133
144
|
end
|
134
145
|
end
|
135
146
|
|
data/todo.txt
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1. Simplest configuration with warning
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tagged_logger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fedor Kocherga
|
@@ -9,88 +9,25 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2010-01-02 00:00:00 -06:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
16
|
-
description:
|
17
|
-
This gem supposed to help you to forget about how to expose logging
|
18
|
-
facitilities to the code you write. Any time you want to log something,
|
19
|
-
simply do one of:
|
20
|
-
logger.debug("verbose debug information") #or
|
21
|
-
logger.warn("warning") #or
|
22
|
-
logger.info("information you frequently want to see") #or
|
23
|
-
logger.error("errors") #or
|
24
|
-
logger.fatal("fatal errors")
|
25
|
-
|
26
|
-
and do not worry about where the '#logger' is and what it does at the moment,
|
27
|
-
you will have a chance to configure it in place where you confugure other things.
|
28
|
-
So you may focus on _what_ to put in the logging rather on how to set it up.
|
29
|
-
Later you may turn logging on for specific class or bunch of classes or in case
|
30
|
-
you have special logging demands for specific classes you also may specify it
|
31
|
-
in very simple way.
|
32
|
-
|
33
|
-
The simplest way to turn logging on for every class whose methods calls '#logger':
|
34
|
-
|
35
|
-
TaggedLogger.rules do
|
36
|
-
out_everything_to Logger.new(STDOUT)
|
37
|
-
end
|
38
|
-
|
39
|
-
or you may cook it in your special way:
|
40
|
-
|
41
|
-
TaggedLogger.rules do
|
42
|
-
out /.*/ do |level, tag, msg|
|
43
|
-
puts "#{level}-#{tag}: #{msg}"
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
Where 'tag' is the simple class name whose method calls '#logger'. Note,
|
48
|
-
you do not have to implement '#logger' method anywhere. It gets
|
49
|
-
automatically generated by specifying any of 'out' rules.
|
50
|
-
You may be even more picky about what and where to log. Imagine
|
51
|
-
you have 'Network' and 'Database' classes and you want to have
|
52
|
-
separate log files for them, it is easy:
|
53
|
-
|
54
|
-
TaggedLogger.rules do
|
55
|
-
out Network => Logger.new("network.log")
|
56
|
-
out Database => Logger.new("database.log")
|
57
|
-
end
|
58
|
-
|
59
|
-
In case you want to define common log for several classes:
|
60
|
-
|
61
|
-
TaggedLogger.rules do
|
62
|
-
out [Ftp, Http, Sockets] => Logger.new("network.log")
|
63
|
-
end
|
64
|
-
|
65
|
-
Or if you want to have all these classes showing up under common
|
66
|
-
tag 'Network' in standard output:
|
67
|
-
|
68
|
-
TaggedLogger.rules do
|
69
|
-
out_everything_to Logger.new(STDOUT)
|
70
|
-
rename [Ftp, Http, Sockets] => :Network
|
71
|
-
end
|
72
|
-
|
73
|
-
You may also use regular expressions in your rules:
|
74
|
-
|
75
|
-
TaggedLogger.rules do
|
76
|
-
out /Active::/ => Logger.new("active.log")
|
77
|
-
end
|
78
|
-
|
16
|
+
description:
|
79
17
|
email: fkocherga@gmail.com
|
80
18
|
executables: []
|
81
19
|
|
82
20
|
extensions: []
|
83
21
|
|
84
22
|
extra_rdoc_files:
|
85
|
-
- README.
|
23
|
+
- README.html
|
24
|
+
- README.markdown
|
86
25
|
files:
|
87
26
|
- .gitignore
|
88
27
|
- MIT-LICENSE
|
89
|
-
- README.
|
28
|
+
- README.markdown
|
90
29
|
- Rakefile
|
91
30
|
- VERSION
|
92
|
-
- active.log
|
93
|
-
- database.log
|
94
31
|
- examples/one_log_per_classes.rb
|
95
32
|
- examples/one_tag_per_classes.rb
|
96
33
|
- examples/per_class_customization.rb
|
@@ -98,10 +35,11 @@ files:
|
|
98
35
|
- examples/simplest_customization.rb
|
99
36
|
- examples/simplest_usage.rb
|
100
37
|
- lib/tagged_logger.rb
|
101
|
-
- network.log
|
102
38
|
- tagged_logger.gemspec
|
103
39
|
- tagged_logger.rb
|
104
40
|
- test/test.rb
|
41
|
+
- todo.txt
|
42
|
+
- README.html
|
105
43
|
has_rdoc: true
|
106
44
|
homepage: http://github.com/fkocherga/tagged_logger
|
107
45
|
licenses: []
|
data/README.rdoc
DELETED
@@ -1,63 +0,0 @@
|
|
1
|
-
= TaggedLogger
|
2
|
-
Split your logging by using tags-based rules (tags are generated automatically)
|
3
|
-
|
4
|
-
== What is it for?
|
5
|
-
When you need to use logging for different code in different ways,
|
6
|
-
here is help for you: create tags-based rules for logging. Tags are
|
7
|
-
class names by default, so you do not have to specify them in
|
8
|
-
+logger.info+, +logger.warn+ and similar calls. Rules are just code blocks,
|
9
|
-
so any logging facility could be used underneath: standard library
|
10
|
-
+Logger+, +log4r+, writing to +STDOUT+ or something else.
|
11
|
-
|
12
|
-
|
13
|
-
== Installation
|
14
|
-
|
15
|
-
$ sudo gem install tagged_logger --source=http://gemcutter.org
|
16
|
-
|
17
|
-
== Usage
|
18
|
-
|
19
|
-
require 'rubygems'
|
20
|
-
require 'tagged_logger'
|
21
|
-
require 'logger'
|
22
|
-
|
23
|
-
#for class A the tag 'A' is used implicitly, no need to specify it
|
24
|
-
class A
|
25
|
-
def foo; logger.info("#{self.class}...".downcase); end
|
26
|
-
end
|
27
|
-
|
28
|
-
file_logger = Logger.new('my_log.log')
|
29
|
-
file_logger.formatter = lambda {|severity, datetime, progname, msg| "#{msg}"}
|
30
|
-
|
31
|
-
#If we want to have #logger in every class doing whatever we need
|
32
|
-
TaggedLogger.use_in_every_class do |level, tag, what|
|
33
|
-
file_logger.send(level, "#{tag}: #{what}\n")
|
34
|
-
end
|
35
|
-
A.new.foo #'A: a...' printed in 'my_log.log'
|
36
|
-
|
37
|
-
#Adding special logging for class A (or everything with tag 'A')
|
38
|
-
TaggedLogger.for_tag A do |level, tag, what|
|
39
|
-
STDOUT << "#{level}---#{tag}---#{what}\n"
|
40
|
-
end
|
41
|
-
A.new.foo #'A: a...' printed in 'my_log.log', 'info---A---a...' - in STDOUT
|
42
|
-
B = Class.new(A)
|
43
|
-
B.new.foo #'B: b...' printed in 'my_log.log', but not in STDOUT
|
44
|
-
|
45
|
-
#Rule for A and B says: logging within these classes happens with tag 'COMBINED':
|
46
|
-
TaggedLogger.replace_tags [A, B], :with => :COMBINED
|
47
|
-
A.new.foo #'COMBINED: a...' printed in 'my_log.log', but nothing in STDOUT
|
48
|
-
B.new.foo #'COMBINED: b...' printed in 'my_log.log'
|
49
|
-
|
50
|
-
#Adding special rule for 'COMBINED' tag
|
51
|
-
TaggedLogger.for_tag :COMBINED do |level, tag, what|
|
52
|
-
STDERR << "Oh my gosh!!! #{what}\n"
|
53
|
-
end
|
54
|
-
A.new.foo #'Oh my gosh!!! a...' printed in 'my_log.log' and in STDERR
|
55
|
-
B.new.foo #'Oh my gosh!!! b...' printed in 'my_log.log' and in STDERR
|
56
|
-
|
57
|
-
#Hope you've got the idea, do not hesitate to ask/fix me something...
|
58
|
-
|
59
|
-
== License
|
60
|
-
TaggedLogger is released under the MIT license.
|
61
|
-
|
62
|
-
= Shortcumings
|
63
|
-
Was not tested with log4r
|
data/active.log
DELETED
data/database.log
DELETED
data/network.log
DELETED