tagged_logger 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -12,16 +12,72 @@ begin
12
12
  require 'jeweler'
13
13
  Jeweler::Tasks.new do |s|
14
14
  s.name = "tagged_logger"
15
- s.summary = "Split your logging by using tags-based rules (tags are generated automatically)"
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
- When you need to use logging for different code in different ways,
20
- here is help for you: create tags-based rules for logging. Tags are
21
- class names by default, so you do not have to specify them in
22
- logger's #info, #warn and similar calls. Rules are just code blocks,
23
- so any logging facility could be used underneath: standard library
24
- Logger, log4r, writing to STDOUT or something else.
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
+
25
81
  END
26
82
  s.authors = ["Fedor Kocherga"]
27
83
  s.test_files = ['test/test.rb']
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.2.0
data/active.log ADDED
@@ -0,0 +1,2 @@
1
+ # Logfile created on Sun Dec 20 19:27:33 -0600 2009 by /
2
+ I, [2009-12-20T19:27:33.951440 #36852] INFO -- : Active::Base: foo
data/database.log ADDED
@@ -0,0 +1,2 @@
1
+ # Logfile created on Sun Dec 20 19:27:20 -0600 2009 by /
2
+ I, [2009-12-20T19:27:20.352239 #36844] INFO -- : Database: foo
@@ -0,0 +1,21 @@
1
+ require 'rubygems'
2
+ require 'tagged_logger'
3
+ require 'logger'
4
+
5
+ class LogFoo
6
+ def foo
7
+ logger.info("foo")
8
+ end
9
+ end
10
+
11
+ Ftp = Class.new LogFoo
12
+ Http = Class.new LogFoo
13
+ Sockets = Class.new LogFoo
14
+
15
+ `rm -f network.log`
16
+ TaggedLogger.rules do
17
+ out [Ftp, Http, Sockets] => Logger.new("network.log")
18
+ end
19
+
20
+ [Ftp, Http, Sockets].each { |c| c.new.foo }
21
+ IO.foreach('network.log') { |line| puts line }
@@ -0,0 +1,21 @@
1
+ require 'rubygems'
2
+ require 'tagged_logger'
3
+ require 'logger'
4
+
5
+ module LogFoo
6
+ def foo
7
+ logger.info("#{self.class}#foo")
8
+ end
9
+ end
10
+
11
+ Ftp = Class.new { include LogFoo }
12
+ Http = Class.new { include LogFoo }
13
+ Sockets = Class.new { include LogFoo }
14
+
15
+ TaggedLogger.rules do
16
+ out_everything_to Logger.new(STDOUT)
17
+ rename [Ftp, Http, Sockets] => :Network
18
+ end
19
+
20
+ [Ftp, Http, Sockets].each { |c| c.new.foo }
21
+
@@ -0,0 +1,23 @@
1
+ require 'rubygems'
2
+ require 'tagged_logger'
3
+ require 'logger'
4
+
5
+ class LogFoo
6
+ def foo
7
+ logger.info("foo")
8
+ end
9
+ end
10
+
11
+ Database = Class.new LogFoo
12
+ Network = Class.new LogFoo
13
+
14
+ `rm -f network.log`
15
+ `rm -f database.log`
16
+
17
+ TaggedLogger.rules do
18
+ out Network => Logger.new("network.log")
19
+ out Database => Logger.new("database.log")
20
+ end
21
+
22
+ Database.new.foo
23
+ Network.new.foo
@@ -0,0 +1,19 @@
1
+ require 'rubygems'
2
+ require 'tagged_logger'
3
+ require 'logger'
4
+
5
+ module Active
6
+ class Base
7
+ def foo
8
+ logger.info("foo")
9
+ end
10
+ end
11
+ end
12
+
13
+ `rm -f active.log`
14
+
15
+ TaggedLogger.rules do
16
+ out /Active::/ => Logger.new("active.log")
17
+ end
18
+
19
+ Active::Base.new.foo
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'tagged_logger'
3
+
4
+ TaggedLogger.rules do
5
+ out /.*/ do |level, tag, msg|
6
+ puts "#{level}-#{tag}: #{msg}"
7
+ end
8
+ end
9
+
10
+ logger.info("message")
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'tagged_logger'
3
+ require 'logger'
4
+
5
+ TaggedLogger.rules do
6
+ out_everything_to Logger.new(STDOUT)
7
+ end
8
+
9
+ class A
10
+ def foo
11
+ logger.warn "foo"
12
+ end
13
+ logger.debug "A parsed"
14
+ end
15
+
16
+
17
+ logger.info("Hello word!")
18
+ A.new.foo
data/lib/tagged_logger.rb CHANGED
@@ -1,60 +1,107 @@
1
1
  require 'delegate'
2
+ require 'facets/dictionary'
2
3
 
3
4
  class TaggedLogger
4
-
5
- attr_reader :tags_map
6
- def initialize()
7
- @tags_map = {}
8
- end
9
-
10
- @@tagged_logger = self.new
11
-
12
- def log(level, tag, msg)
13
- remapped_tag = remap(tag)
14
- find_blocks(remapped_tag).each { |b| b.call(level, remapped_tag, msg) }
15
- end
5
+ @logger_generator_exists = false
6
+ @rename_rules = Dictionary.new
7
+ @tag_blocks = Dictionary.new
16
8
 
17
- def for_tag(*args, &block)
18
- tags = args
19
- tags.each do |tag|
20
- case tag
21
- when Regexp then rules[args.first] = block
22
- when Class then rules[Regexp.new("^#{tag.to_s}$")] = block
23
- when Array then args.first.each {|e| for_tag(tag, block)}
24
- when Symbol then rules[Regexp.new("^#{tag.to_s}$")] = block
9
+ class << self
10
+ def reset
11
+ @rename_rules = Dictionary.new
12
+ @tag_blocks = Dictionary.new
13
+ end
14
+
15
+ def rules(&block)
16
+ instance_eval(&block)
17
+ end
18
+
19
+ def log(level, tag, msg)
20
+ tag_aliases(tag) do |tag_alias|
21
+ tag_blocks(tag_alias) do |tag_block|
22
+ tag_block.call(level, tag_alias, msg)
23
+ end
25
24
  end
26
25
  end
27
- end
28
-
29
-
30
- class << self
31
26
 
32
- def replace_tags(tags, with)
33
- with_tag = with[:with]
34
- raise ArgumentError.new(":with => <tag> has to be specified") unless with_tag
35
- @@tagged_logger.instance_eval do
36
- tags.each {|t| @tags_map[t.to_s] = with_tag}
27
+ def out_everything_to(logger = nil, &block)
28
+ if logger && block
29
+ raise ArgumentError, "Either block or logger has to be specified, but not both."
37
30
  end
31
+ out /.*/ => logger if logger
32
+ oout &block if block
38
33
  end
39
34
 
40
- def reset
41
- @@tagged_logger.instance_eval do
42
- @rules = {}
43
- @tags_map = {}
35
+ def out(spec, &block)
36
+ add_logger_generator_in_Object
37
+ if spec.is_a? Hash
38
+ spec.each do |what, where|
39
+ @tag_blocks[tag_matcher(what)] = lambda { |level, tag, msg | where.send(level, "#{tag}: #{msg}") }
40
+ end
41
+ raise ArgumentError "No block should be specified in this 'out' rule" if block
42
+ else
43
+ raise ArgumentError "Block has to be specified in this 'out' rule" unless block
44
+ @tag_blocks[tag_matcher(spec)] = block
44
45
  end
45
46
  end
46
-
47
- def use_in_every_class
48
- #Object#logger when called generates <self.class>#logger (only once)
49
- #returning logger knowing what tags to use for self.class and passing them to delegator which is
50
- #instance (singleton) of TaggedLogger
47
+
48
+ def rename(renames)
49
+ renames.each { |from, to| @rename_rules[tag_matcher(from)] = to }
50
+ end
51
+
52
+ private
53
+ class TagMatcher
54
+ attr_reader :match_spec
55
+
56
+ def initialize(match_spec)
57
+ @match_spec = match_spec
58
+ end
59
+
60
+ def match?(tag)
61
+ self.class.match?(@match_spec, tag)
62
+ end
63
+
64
+ def self.match?(spec, tag)
65
+ t = tag.to_s
66
+ case spec
67
+ when Regexp
68
+ t =~ spec
69
+ when Class
70
+ t == spec.name
71
+ when Array
72
+ spec.any? {|s| match?(s, tag)}
73
+ else
74
+ spec.to_s == t
75
+ end
76
+ end
77
+ end #TagMatcher
78
+
79
+ def tag_matcher(tag)
80
+ TagMatcher.new(tag)
81
+ end
82
+
83
+ def tag_aliases(tag, &block)
84
+ current_name = tag
85
+ @rename_rules.each { |from, to| current_name = to if from.match?(tag) }
86
+ block.call(current_name)
87
+ end
88
+
89
+ def tag_blocks(tag, &block)
90
+ @tag_blocks.each do |matcher, block|
91
+ yield block if matcher.match? tag
92
+ end
93
+ end
94
+
95
+ def add_logger_generator_in_Object
96
+ return if @logger_generator_exists
97
+ @logger_generator_exists = true
51
98
  Object.send(:define_method, "logger") do
52
99
  self.class.class_eval do
53
100
  attr_reader :class_logger
54
101
  @class_logger = nil
55
102
  def logger
56
103
  return class_logger if class_logger
57
- @class_logger = SimpleDelegator.new(@@tagged_logger)
104
+ @class_logger = SimpleDelegator.new(TaggedLogger)
58
105
  class_logging_tag = self.class == Class ? self.to_s : self.class.to_s
59
106
  [:debug, :warn, :info, :error, :fatal].each do |method|
60
107
  (class << @class_logger;self;end).instance_eval do
@@ -68,34 +115,7 @@ class TaggedLogger
68
115
  end
69
116
  logger
70
117
  end
71
- if block_given?
72
- @@tagged_logger.for_tag /.*/ do |level, tag, what|
73
- yield(level, tag, what)
74
- end
75
- end
76
118
  end
77
119
 
78
- def for_tag(*args, &block)
79
- @@tagged_logger.for_tag(*args, &block)
80
- end
81
120
  end # class methods
82
-
83
- private
84
- def rules
85
- @rules ||= {}
86
- end
87
-
88
- def find_blocks(tag)
89
- compare_with = tag.to_s
90
- result = []
91
- rules.each do |rule, block|
92
- result << block if compare_with =~ rule
93
- end
94
- result
95
- end
96
-
97
- def remap(tag)
98
- return tag unless @tags_map.key? tag
99
- @tags_map[tag]
100
- end
101
121
  end
data/network.log ADDED
@@ -0,0 +1,2 @@
1
+ # Logfile created on Sun Dec 20 19:27:20 -0600 2009 by /
2
+ I, [2009-12-20T19:27:20.356509 #36844] INFO -- : Network: foo
@@ -1,21 +1,77 @@
1
1
  # Generated by jeweler
2
- # DO NOT EDIT THIS FILE
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{tagged_logger}
8
- s.version = "0.1.2"
8
+ s.version = "0.2.0"
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{2009-10-13}
13
- s.description = %q{When you need to use logging for different code in different ways,
14
- here is help for you: create tags-based rules for logging. Tags are
15
- class names by default, so you do not have to specify them in
16
- logger's #info, #warn and similar calls. Rules are just code blocks,
17
- so any logging facility could be used underneath: standard library
18
- Logger, log4r, writing to STDOUT or something else.
12
+ s.date = %q{2009-12-20}
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
+
19
75
  }
20
76
  s.email = %q{fkocherga@gmail.com}
21
77
  s.extra_rdoc_files = [
@@ -27,7 +83,16 @@ Logger, log4r, writing to STDOUT or something else.
27
83
  "README.rdoc",
28
84
  "Rakefile",
29
85
  "VERSION",
86
+ "active.log",
87
+ "database.log",
88
+ "examples/one_log_per_classes.rb",
89
+ "examples/one_tag_per_classes.rb",
90
+ "examples/per_class_customization.rb",
91
+ "examples/rule_with_regex.rb",
92
+ "examples/simplest_customization.rb",
93
+ "examples/simplest_usage.rb",
30
94
  "lib/tagged_logger.rb",
95
+ "network.log",
31
96
  "tagged_logger.gemspec",
32
97
  "tagged_logger.rb",
33
98
  "test/test.rb"
@@ -36,7 +101,7 @@ Logger, log4r, writing to STDOUT or something else.
36
101
  s.rdoc_options = ["--charset=UTF-8"]
37
102
  s.require_paths = ["lib"]
38
103
  s.rubygems_version = %q{1.3.5}
39
- s.summary = %q{Split your logging by using tags-based rules (tags are generated automatically)}
104
+ s.summary = %q{Detaches _what_ is logged from _how_ it is logged.}
40
105
  s.test_files = [
41
106
  "test/test.rb"
42
107
  ]
@@ -51,3 +116,4 @@ Logger, log4r, writing to STDOUT or something else.
51
116
  else
52
117
  end
53
118
  end
119
+
data/test/test.rb CHANGED
@@ -16,29 +16,29 @@ end
16
16
 
17
17
  class TaggedLoggerTest < Test::Unit::TestCase
18
18
 
19
- context "#logger() generated for every class, logging goes to String @out;" do
19
+ context "#logger() generated for every class, logging goes to String @out1;" do
20
20
  setup do
21
- @out = TestLogDevice.new
22
- @standard_logger = Logger.new(@out)
21
+ @out1 = TestLogDevice.new
22
+ standard_logger = Logger.new(@out1)
23
23
  @formatter = lambda {|severity, datetime, progname, msg| "#{msg}"}
24
- @standard_logger.formatter = @formatter
25
- TaggedLogger.reset
26
- TaggedLogger.use_in_every_class do |level, tag, what|
27
- @standard_logger.send(level, "#{tag}: #{what}")
24
+ standard_logger.formatter = @formatter
25
+ TaggedLogger.rules do
26
+ reset
27
+ out_everything_to standard_logger
28
28
  end
29
29
  end
30
30
 
31
31
  should "include #logger in every class" do
32
32
  assert Class.new.methods.include? "logger"
33
33
  end
34
-
34
+
35
35
  should "do logging with different levels" do
36
36
  NewClass = Class.new
37
37
  obj = NewClass.new
38
38
  %w[debug info warn error fatal].each do |method|
39
39
  assert obj.logger.methods.include? method
40
40
  obj.logger.send(method.intern, method)
41
- assert_equal "#{obj.class}: #{method}", @out.to_s
41
+ assert_equal "#{obj.class}: #{method}", @out1.to_s
42
42
  end
43
43
  end
44
44
 
@@ -56,11 +56,16 @@ class TaggedLoggerTest < Test::Unit::TestCase
56
56
  end
57
57
 
58
58
  should "be possible to replace tags for A, B classes with single tag TEST making rules for A and B obsolete" do
59
- TaggedLogger.replace_tags [A, B], :with => :TEST
59
+ TaggedLogger.rules do
60
+ rename [A,B] => :TEST
61
+ end
62
+
60
63
  @a.foo
61
- assert_equal "TEST: foo", @out.to_s
64
+ assert_equal "TEST: foo", @out1.to_s
65
+ @out1.clear
66
+
62
67
  @b.foo
63
- assert_equal "TEST: foo", @out.to_s
68
+ assert_equal "TEST: foo", @out1.to_s
64
69
  end
65
70
 
66
71
  context "specialized logging" do
@@ -70,32 +75,50 @@ class TaggedLoggerTest < Test::Unit::TestCase
70
75
  @logger2.formatter = @formatter
71
76
  end
72
77
 
73
- should "be possible to speialize logging for tag A" do
74
- TaggedLogger.for_tag A do |level, tag, what|
75
- @logger2.send(level, "#{level}---#{tag}---#{what}")
78
+ should "be possible to speialize logging for tag A by specifying different logger" do
79
+ logger2 = @logger2
80
+ TaggedLogger.rules do
81
+ out A => logger2
82
+ end
83
+ @a.foo
84
+ assert_equal "#{self.class}::A: foo", @out1.to_s
85
+ assert_equal "#{self.class}::A: foo", @out2.to_s
86
+ @out2.clear
87
+ @b.foo
88
+ assert_equal "#{self.class}::B: foo", @out1.to_s
89
+ assert_equal "", @out2.to_s
90
+ end
91
+
92
+ should "be possible to speialize logging for tag A by providing block" do
93
+ logger2 = @logger2
94
+ TaggedLogger.rules do
95
+ out A do |level, tag, msg|
96
+ logger2.send(level, msg)
97
+ end
76
98
  end
77
99
  @a.foo
78
- assert_equal "#{self.class}::A: foo", @out.to_s
79
- assert_equal "info---#{self.class}::A---foo", @out2.to_s
100
+ assert_equal "#{self.class}::A: foo", @out1.to_s
101
+ assert_equal "foo", @out2.to_s
80
102
  @out2.clear
81
103
  @b.foo
82
- assert_equal "#{self.class}::B: foo", @out.to_s
104
+ assert_equal "#{self.class}::B: foo", @out1.to_s
83
105
  assert_equal "", @out2.to_s
84
106
  end
85
107
 
86
108
  should "be possible to replace tags for A, B classes with single tag TEST and specialize logging for it" do
87
- TaggedLogger.replace_tags [A, B], :with => :TEST
88
- TaggedLogger.for_tag :TEST do |level, tag, what|
89
- @logger2.send(level, "#{level}---#{tag}---#{what}")
109
+ logger2 = @logger2
110
+ TaggedLogger.rules do
111
+ rename [A, B] => :TEST
112
+ out :TEST => logger2
90
113
  end
91
114
  @a.foo
92
- assert_equal "TEST: foo", @out.to_s
93
- assert_equal "info---TEST---foo", @out2.to_s
94
- @out.clear
115
+ assert_equal "TEST: foo", @out1.to_s
116
+ assert_equal "TEST: foo", @out2.to_s
117
+ @out1.clear
95
118
  @out2.clear
96
119
  @b.foo
97
- assert_equal "TEST: foo", @out.to_s
98
- assert_equal "info---TEST---foo", @out2.to_s
120
+ assert_equal "TEST: foo", @out1.to_s
121
+ assert_equal "TEST: foo", @out2.to_s
99
122
  end
100
123
 
101
124
  should "use default tag equal to class name for class methods" do
@@ -103,7 +126,7 @@ class TaggedLoggerTest < Test::Unit::TestCase
103
126
  logger.info "bar"
104
127
  end
105
128
  A.bar
106
- assert_equal "#{self.class}::A: bar", @out.to_s
129
+ assert_equal "#{self.class}::A: bar", @out1.to_s
107
130
  end
108
131
  end
109
132
 
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.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fedor Kocherga
@@ -9,18 +9,73 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-13 00:00:00 +04:00
12
+ date: 2009-12-20 00:00:00 -06:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
16
- description: |
17
- When you need to use logging for different code in different ways,
18
- here is help for you: create tags-based rules for logging. Tags are
19
- class names by default, so you do not have to specify them in
20
- logger's #info, #warn and similar calls. Rules are just code blocks,
21
- so any logging facility could be used underneath: standard library
22
- Logger, log4r, writing to STDOUT or something else.
23
-
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
+
24
79
  email: fkocherga@gmail.com
25
80
  executables: []
26
81
 
@@ -34,7 +89,16 @@ files:
34
89
  - README.rdoc
35
90
  - Rakefile
36
91
  - VERSION
92
+ - active.log
93
+ - database.log
94
+ - examples/one_log_per_classes.rb
95
+ - examples/one_tag_per_classes.rb
96
+ - examples/per_class_customization.rb
97
+ - examples/rule_with_regex.rb
98
+ - examples/simplest_customization.rb
99
+ - examples/simplest_usage.rb
37
100
  - lib/tagged_logger.rb
101
+ - network.log
38
102
  - tagged_logger.gemspec
39
103
  - tagged_logger.rb
40
104
  - test/test.rb
@@ -65,6 +129,6 @@ rubyforge_project:
65
129
  rubygems_version: 1.3.5
66
130
  signing_key:
67
131
  specification_version: 3
68
- summary: Split your logging by using tags-based rules (tags are generated automatically)
132
+ summary: Detaches _what_ is logged from _how_ it is logged.
69
133
  test_files:
70
134
  - test/test.rb