tagged_logger 0.1.2 → 0.2.0

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.
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