logbert 0.6.4

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c133267e75a816038c4abdafba21f850d4a0731f
4
+ data.tar.gz: 6bd905d93430880aa4889e11e4ceb063f1581673
5
+ SHA512:
6
+ metadata.gz: 26f685bcedaf8d2fbfec4dc5caff3f212d5e9a3c10d547f07c785a95497e9fa0ca7c2d02b4efbd7faaa721c4278def872b34001f829671131f7035a1e3084d83
7
+ data.tar.gz: be0035b051689de397e889f75a3777bbecd806ad99720ea5201ff937ed39ede1506838e4f23b6e1b9a2c6e2c8d87d90e4fdf61cae53915c973cf635a4abc2cda
@@ -0,0 +1,41 @@
1
+
2
+ require 'logbert/message'
3
+
4
+ module Logbert
5
+
6
+ module Formatters
7
+
8
+ class Formatter
9
+ def format(msg)
10
+ raise NotImplementedError
11
+ end
12
+ end
13
+
14
+ class SimpleFormatter < Formatter
15
+ def format(msg)
16
+ level = msg.level.to_s.upcase.ljust(8)
17
+ "#{level} [time='#{msg.time}' pid='#{msg.pid}' logger='#{msg.logger}'] : #{msg.content}"
18
+ end
19
+ end
20
+
21
+
22
+ class ProcFormatter < Formatter
23
+ attr_accessor :proc
24
+
25
+ def initialize(&block)
26
+ raise ArgumentError, "ProcFormatter must be initialized with a block" unless block_given?
27
+ @proc = block
28
+ end
29
+
30
+ def format(msg)
31
+ @proc.call msg
32
+ end
33
+ end
34
+
35
+ def self.fmt(&block)
36
+ ProcFormatter.new(&block)
37
+ end
38
+
39
+ end
40
+ end
41
+
@@ -0,0 +1,45 @@
1
+
2
+ require 'logbert/formatters'
3
+
4
+ module Logbert
5
+ module Handlers
6
+
7
+
8
+ class BaseHandler
9
+
10
+ def formatter
11
+ @formatter ||= Logbert::Formatters::SimpleFormatter.new
12
+ end
13
+
14
+ def formatter=(value)
15
+ @formatter = value
16
+ end
17
+
18
+ def publish(message)
19
+ emit self.formatter.format(message)
20
+ end
21
+
22
+
23
+ def emit(output)
24
+ raise NotImplementedError
25
+ end
26
+
27
+ end
28
+
29
+
30
+ class StreamHandler < BaseHandler
31
+ attr_accessor :stream
32
+
33
+ def initialize(stream = $stderr)
34
+ @stream = stream
35
+ end
36
+
37
+ def emit(output)
38
+ @stream.puts output
39
+ end
40
+
41
+ end
42
+
43
+
44
+ end
45
+ end
@@ -0,0 +1,106 @@
1
+
2
+ module Logbert
3
+
4
+ DefaultLevels = {
5
+ debug: 100,
6
+ info: 200,
7
+ warning: 300,
8
+ error: 400,
9
+ fatal: 500,
10
+ }
11
+
12
+
13
+ class Level
14
+ attr_reader :name, :value
15
+
16
+ def initialize(name, value)
17
+ @name = name
18
+ @value = value
19
+ end
20
+
21
+ def to_s
22
+ @name.to_s
23
+ end
24
+ end
25
+
26
+ # This class doubles as a mixin. Bazinga!
27
+ class LevelManager < Module
28
+
29
+ def initialize
30
+ @name_to_level = {}
31
+ @value_to_level = {}
32
+
33
+ @quick_lookup = {}
34
+
35
+ Logbert::DefaultLevels.each{|name, value| self.define_level(name, value)}
36
+ end
37
+
38
+ def names
39
+ @name_to_level.keys
40
+ end
41
+
42
+ def values
43
+ @value_to_level.keys
44
+ end
45
+
46
+ def levels
47
+ @name_to_level.values
48
+ end
49
+
50
+
51
+ def define_level(name, value)
52
+ unless name.instance_of?(Symbol) or name.instance_of?(String)
53
+ raise ArgumentError, "The Level's name must be a Symbol or a String"
54
+ end
55
+ raise ArgumentError, "The Level's value must be an Integer" unless value.is_a? Integer
56
+
57
+ # TODO: Verify that the name/value are not already taken
58
+ raise KeyError, "A Level with that name is already defined: #{name}" if @name_to_level.has_key? name
59
+ raise KeyError, "A Level with that value is already defined: #{value}" if @value_to_level.has_key? value
60
+
61
+ level = Level.new(name, value)
62
+
63
+ @name_to_level[name] = level
64
+ @value_to_level[value] = level
65
+ @quick_lookup[name] = @quick_lookup[value] = @quick_lookup[level] = level
66
+
67
+ self.create_logging_method(name)
68
+ self.create_predicate_method(name, value)
69
+ end
70
+
71
+
72
+ def [](x)
73
+ @quick_lookup[x] or begin
74
+ if x.is_a? Integer
75
+ # Return either the pre-defined level, or produce a virtual level.
76
+ level = @value_to_level[x] || Logbert::Level.new("LEVEL_#{x}".to_sym, x)
77
+ return level
78
+ elsif x.is_a? String
79
+ level = @name_to_level[x.to_sym]
80
+ return level if level
81
+ end
82
+
83
+ raise KeyError, "No Level could be found for input: #{x}"
84
+ end
85
+ end
86
+
87
+
88
+ protected
89
+
90
+ def create_logging_method(level_name)
91
+ define_method level_name do |content = nil, &block|
92
+ self.log(level_name, content, &block)
93
+ end
94
+ end
95
+
96
+ def create_predicate_method(level_name, level_value)
97
+ define_method "#{level_name}?" do
98
+ self.level.value <= level_value
99
+ end
100
+ end
101
+
102
+
103
+ end
104
+
105
+
106
+ end
@@ -0,0 +1,68 @@
1
+
2
+ require 'logbert/message'
3
+ require 'logbert/handlers'
4
+
5
+ module Logbert
6
+
7
+ class Logger
8
+
9
+ attr_reader :factory, :level_manager, :name, :handlers
10
+
11
+ def initialize(factory, level_manager, name)
12
+ @factory = factory
13
+ @level_manager = level_manager
14
+
15
+ @name = name.dup.freeze
16
+ @handlers = []
17
+ end
18
+
19
+ def level_inherited?
20
+ !!@level
21
+ end
22
+
23
+ def level
24
+ @level || self.parent.level
25
+ end
26
+
27
+ def level=(x)
28
+ @level = @level_manager[x]
29
+ end
30
+
31
+
32
+ def parent
33
+ unless @parent_defined
34
+ @parent = @factory.parent_for(self)
35
+ @parent_defined = true
36
+ end
37
+ return @parent
38
+ end
39
+
40
+ def root
41
+ self.factory.root
42
+ end
43
+
44
+ def log(level, content = nil, &block)
45
+ message = Logbert::Message.create(self, @level_manager[level], content, &block)
46
+ handle_message(message)
47
+ end
48
+
49
+
50
+ def to_s
51
+ @name
52
+ end
53
+
54
+ protected
55
+
56
+ def handle_message(message)
57
+ if message.level.value >= self.level.value
58
+ @handlers.each{|h| h.publish message}
59
+ end
60
+
61
+ p = self.parent
62
+ p.handle_message(message) if p
63
+ end
64
+
65
+ end
66
+
67
+ end
68
+
@@ -0,0 +1,44 @@
1
+
2
+ require 'logbert/naming'
3
+ require 'logbert/logger'
4
+ require 'logbert/levels'
5
+
6
+ module Logbert
7
+
8
+ class LoggerFactory
9
+
10
+ attr_reader :level_manager
11
+
12
+ def initialize(level_manager = LevelManager.new)
13
+ @inventory = {}
14
+ @level_manager = level_manager
15
+ self.root.level = @level_manager[:warning]
16
+ end
17
+
18
+ def [](name_or_module)
19
+ name = Logbert.name_for(name_or_module)
20
+ @inventory[name] ||= begin
21
+ l = Logger.new(self, @level_manager, name)
22
+ l.extend @level_manager
23
+ end
24
+ end
25
+
26
+ def root
27
+ @root ||= self['']
28
+ end
29
+
30
+ def parent_for(logger)
31
+ n = logger.name
32
+ unless n.empty?
33
+ components = Logbert.split_name(n)
34
+ components.pop
35
+ parent_name = components.join(Logbert::NameSeparator)
36
+ return self[parent_name]
37
+ end
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+
44
+
@@ -0,0 +1,37 @@
1
+
2
+ module Logbert
3
+
4
+ class Message
5
+ attr_reader :logger, :level, :time, :pid, :content_proc
6
+
7
+ def initialize(logger, level, time, pid, content = nil, &content_proc)
8
+ @logger = logger
9
+ @level = level
10
+ @time = time
11
+ @pid = pid
12
+
13
+ @content = content
14
+ @content_proc = content_proc
15
+ end
16
+
17
+ def self.create(logger, level, content = nil, &content_proc)
18
+ Message.new logger, level, Time.now, Process.pid, content, &content_proc
19
+ end
20
+
21
+ # Returns the content. If the content has not been created yet,
22
+ # then call @content_proc and save the value.
23
+ def content
24
+ @content ||= begin
25
+ if @content_proc
26
+ @content_proc.call.to_s
27
+ else
28
+ ""
29
+ end
30
+ end
31
+ end
32
+
33
+ end
34
+
35
+
36
+ end
37
+
@@ -0,0 +1,20 @@
1
+
2
+ module Logbert
3
+
4
+ NameSeparator = "/"
5
+
6
+ def self.split_name(name)
7
+ name.split(Logbert::NameSeparator).reject{|n| n.empty?}
8
+ end
9
+
10
+ def self.name_for(n)
11
+ if n.is_a? Module
12
+ n.name.gsub("::", Logbert::NameSeparator)
13
+ else
14
+ Logbert.split_name(n.to_s).join(Logbert::NameSeparator)
15
+ end
16
+ end
17
+
18
+ end
19
+
20
+
data/lib/logbert.rb ADDED
@@ -0,0 +1,20 @@
1
+
2
+ require 'logbert/levels'
3
+ require 'logbert/logger_factory'
4
+
5
+ module Logbert
6
+
7
+ def self.factory
8
+ @factory ||= LoggerFactory.new
9
+ end
10
+
11
+ def self.[](name)
12
+ self.factory[name]
13
+ end
14
+
15
+ def self.root
16
+ self.factory.root
17
+ end
18
+
19
+ end
20
+
metadata ADDED
@@ -0,0 +1,51 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: logbert
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.6.4
5
+ platform: ruby
6
+ authors:
7
+ - Brian Lauber
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-06-14 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Change your logging behaviors without mucking with your code!
14
+ email: constructible.truth@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/logbert/formatters.rb
20
+ - lib/logbert/handlers.rb
21
+ - lib/logbert/levels.rb
22
+ - lib/logbert/logger.rb
23
+ - lib/logbert/logger_factory.rb
24
+ - lib/logbert/message.rb
25
+ - lib/logbert/naming.rb
26
+ - lib/logbert.rb
27
+ homepage:
28
+ licenses:
29
+ - MIT
30
+ metadata: {}
31
+ post_install_message:
32
+ rdoc_options: []
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ requirements: []
46
+ rubyforge_project:
47
+ rubygems_version: 2.0.3
48
+ signing_key:
49
+ specification_version: 4
50
+ summary: Logging for winners.
51
+ test_files: []