logeasy 0.0.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.
@@ -0,0 +1,52 @@
1
+ #
2
+ # Suraj Vijayakumar
3
+ # 19-02-2011
4
+ #
5
+
6
+ require "logeasy"
7
+
8
+ # Configuring the self logger. The self logger will log internal logger messages.
9
+
10
+ file_appender_1 = LogEasy::FileAppender.new("easylog_self.log") # Simple file logger.
11
+ self_logger = LogEasy::Logger.self_logger # Get the handle to the self logger.
12
+ self_logger.change_min_level(LogEasy::Level::ALL) # Change the minimum level, since the default level for the self logger is OFF.
13
+ self_logger.add_appender(file_appender_1) # Add the appenders to the self logger. New appenders are assigned the logger's level.
14
+
15
+
16
+ # Using a custom formatter. Takes a log item (instance of EasyLog::Log) as an argument. Return the formatted message.
17
+ timestamp_format = "%d-%m-%Y %H:%M:%S.%L"
18
+ custom_formatter = proc do |log_item|
19
+ logger_name = log_item.logger.name # By default the to_s method returns the logger's full name.
20
+ level = log_item.level # By default the to_s method returns the level's name.
21
+ message = log_item.message
22
+ timestamp = log_item.timestamp.strftime(timestamp_format)
23
+
24
+ "%-5s [#{timestamp}] -- (%s) - %s\n" % [level, logger_name, message]
25
+ end
26
+
27
+
28
+ # Configuring the root logger.
29
+
30
+ file_appender_2 = LogEasy::FileAppender.new("easylog_example.log") # Simple file logger.
31
+ file_appender_2.min_level = LogEasy::Level::INFO # Specific level of INFO for the appender. The logger's level will not be applied to this appender now.
32
+ console_appender_2 = LogEasy::ConsoleAppender.new # Simple console appender.
33
+ console_appender_2.formatter = custom_formatter
34
+ root_logger = LogEasy::Logger.root_logger # Get the handle to the root logger. The root logger's default level is ALL.
35
+ root_logger.add_appender(console_appender_2) # Add the appenders to the root logger.
36
+ root_logger.add_appender(file_appender_2)
37
+
38
+ # Logging to a child logger, sends messages to the parent loggers too (by default).
39
+ custom_logger = LogEasy::Logger.get_logger("Parent::Child") # Creates a logger. The '::' or '.' characters can be used to separate logger names.
40
+ custom_logger.fine("FINE message")
41
+ custom_logger.trace("TRACE message")
42
+ custom_logger.debug("DEBUG message")
43
+ custom_logger.conf("CONF message")
44
+ custom_logger.info("INFO message")
45
+ custom_logger.warn("WARN message")
46
+ custom_logger.error("ERROR message")
47
+ custom_logger.fatal("FATAL message")
48
+ custom_logger << "UNFORMATTED message"
49
+
50
+ # Adding a custom level.
51
+ custom_level = LogEasy::Level.new("FINER", 500) # ALL < FINER < FINE
52
+ custom_logger.log(custom_level, "Custom level message")
data/lib/logeasy.rb ADDED
@@ -0,0 +1,39 @@
1
+ #
2
+ # Suraj Vijayakumar
3
+ # 18-02-2011
4
+ #
5
+
6
+ # Easy logger module.
7
+ # This module is not thread safe.
8
+ #
9
+ # Usage:
10
+ #
11
+ # To create a new logger:
12
+ # LogEasy::Logger.get_logger(<logger_name>)
13
+ # logger_name - this should be a '.' separated or '::' separated hierarchy of loggers.
14
+ # eg. LogEasy::Logger.get_logger("ModuleName::SubModule::ClassName")
15
+ #
16
+ # To change the level of a logger.
17
+ # LogEasy::Logger.get_logger(<logger_name>).change_min_level(<new_level>) # Recursively changes this logger and all child loggers.
18
+ # LogEasy::Logger.get_logger(<logger_name>).min_level = <new_level> # Only change this logger's level.
19
+ # logger_name - the logger name.
20
+ # new_level - the new level to set (instance of LogEasy::Level).
21
+ # eg. LogEasy::Logger.get_logger("ModuleName::SubModule::ClassName").change_min_level(LogEasy::Level::INFO)
22
+ #
23
+ # To add an appender to a logger.
24
+ # LogEasy::Logger.get_logger(<logger_name>).add_appender(<appender>)
25
+ # logger_name - the logger name.
26
+ # appender - the appender to add (instance of LogEasy::Appender).
27
+ # eg. LogEasy::Logger.get_logger("ModuleName::SubModule::ClassName").add_appender(LogEasy::ConsoleAppender.new)
28
+ #
29
+ # By default all sub-loggers will also use this appender. A logger can be told not to use a parent's appender using the
30
+ # 'use_parent_logger' flag. So by adding an appender to the root logger, logs sent to any logger will, by default,
31
+ # be logged by the root logger's appender(s) also.
32
+ #
33
+ # Right now the only way to configure the loggers is using code. Look at example/example.rb for how to do that.
34
+ #
35
+ module LogEasy
36
+
37
+ require "logeasy/logger"
38
+
39
+ end
@@ -0,0 +1,120 @@
1
+ #
2
+ # Suraj Vijayakumar
3
+ # 19-02-2011
4
+ #
5
+
6
+ require "time"
7
+
8
+ module LogEasy
9
+
10
+ # Appender super class. An instance of this class should not be created. It must be sub-classed.
11
+ # Sub-classes must provide a 'write' method that will output a message to the target device.
12
+ # A simple console logger and file logger are provided.
13
+ class Appender
14
+
15
+ # Timestamp format for use by log formatters.
16
+ LOG_TIMESTAMP = "%d-%m-%Y %H:%M:%S.%L %z"
17
+
18
+ # Default formatter that prints messages in the format [TIMESTAMP] [LEVEL] -- [LOGGER] - [MESSAGE]
19
+ DEFAULT_FORMATTER = proc do |log_item|
20
+ logger_name = log_item.logger.name
21
+ level = log_item.level
22
+ message = log_item.message
23
+ timestamp = log_item.timestamp.strftime(LOG_TIMESTAMP)
24
+
25
+ "[#{timestamp}] %-5s -- (%s) - %s\n" % [level, logger_name, message]
26
+ end
27
+
28
+ # Custom formatter that prints messages in the format [TIMESTAMP] [LEVEL] -- [LOGGER_FULL_NAME] - [MESSAGE]
29
+ FULL_LOGGER_NAME_FORMATTER = proc do |log_item|
30
+ logger_name = log_item.logger.full_name
31
+ level = log_item.level
32
+ message = log_item.message
33
+ timestamp = log_item.timestamp.strftime(LOG_TIMESTAMP)
34
+
35
+ "[#{timestamp}] %-5s -- (%s) - %s\n" % [level, logger_name, message]
36
+ end
37
+
38
+ attr_accessor :formatter
39
+ attr_accessor :logger
40
+ attr_accessor :min_level
41
+ attr_accessor :allow_unformatted_messages
42
+
43
+ # Write this log item.
44
+ # If this appender's level is higher than the log item's level, this method will return immediately.
45
+ #
46
+ # 'log_item' - The log to write.
47
+ def do_log(log_item)
48
+ return if log_item.level < min_level
49
+ # Format the message and log it.
50
+ # If the log item is marked as unformatted, then simple print, do not format.
51
+ message = log_item.unformatted ? log_item.message : formatter.call(log_item)
52
+ write(message)
53
+ end
54
+
55
+ private
56
+
57
+ # Creates a new appender.
58
+ def initialize
59
+ @formatter = DEFAULT_FORMATTER
60
+ @allow_unformatted_messages = true
61
+ end
62
+
63
+ # Override to_s to return the class name.
64
+ def to_s
65
+ self.class.name
66
+ end
67
+
68
+ # The write message place holder. This method should be provided by implementations.
69
+ def write(message)
70
+ raise "Error! The write method needs to be overridden."
71
+ end
72
+
73
+ end
74
+
75
+ # Console appender that writes all messages to the console (STDOUT).
76
+ class ConsoleAppender < Appender
77
+
78
+ private
79
+
80
+ # New console appender.
81
+ def initialize
82
+ super
83
+ end
84
+
85
+ # Writes the message to STDOUT.
86
+ def write(message)
87
+ puts message
88
+ end
89
+
90
+ end
91
+
92
+ # File appenders write messages to a file.
93
+ class FileAppender < Appender
94
+
95
+ private
96
+
97
+ attr_reader :file
98
+
99
+ # Creates a new file appender.
100
+ # If the specified file already exists, it is overwritten.
101
+ def initialize(file_path)
102
+ super()
103
+ @file = File.open(file_path, "w")
104
+ end
105
+
106
+ # Closes this appender. This will also remove the appender from its logger.
107
+ def close
108
+ file.close
109
+ logger.remove_appender(self) if not logger.nil?
110
+ end
111
+
112
+ # Writes the message to the file.
113
+ # If the appender has been closed, does nothing.
114
+ def write(message)
115
+ file.puts(message) if not file.closed?
116
+ end
117
+
118
+ end
119
+
120
+ end
@@ -0,0 +1,78 @@
1
+ #
2
+ # Suraj Vijayakumar
3
+ # 19-02-2011
4
+ #
5
+
6
+ module LogEasy
7
+
8
+ # A level represents the severity of a log message. The predefined levels are;
9
+ # ALL < FINE_TRACE < TRACE < DEBUG < CONFIG < INFO < WARN < ERROR < FATAL < UNFORMATTED < OFF
10
+ class Level
11
+
12
+ attr_reader :name
13
+ attr_reader :weight
14
+
15
+ # New logging level.
16
+ #
17
+ # 'name' - The name of the level. Formatted log messages will print this value.
18
+ # 'weight' - The severity of this level. The higher the value, the more severe.
19
+ def initialize(name, weight)
20
+ @name = name
21
+ @weight = weight
22
+ end
23
+
24
+ # Overload the > operator to compare the weights of the levels.
25
+ #
26
+ # 'other' - The level to compare this level with.
27
+ def >(other)
28
+ self.weight > other.weight
29
+ end
30
+
31
+ # Overload the >= operator to compare the weights of the levels.
32
+ #
33
+ # 'other' - The level to compare this level with.
34
+ def >=(other)
35
+ self.weight >= other.weight
36
+ end
37
+
38
+ # Overload the == operator to compare the weights of the levels.
39
+ #
40
+ # 'other' - The level to compare this level with.
41
+ def ==(other)
42
+ self.weight == other.weight
43
+ end
44
+
45
+ # Overload the < operator to compare the weights of the levels.
46
+ #
47
+ # 'other' - The level to compare this level with.
48
+ def <(other)
49
+ self.weight < other.weight
50
+ end
51
+
52
+ # Overload the <= operator to compare the weights of the levels.
53
+ #
54
+ # 'other' - The level to compare this level with.
55
+ def <=(other)
56
+ self.weight <= other.weight
57
+ end
58
+
59
+ # Overrides 'to_s' to return the name of the level.
60
+ def to_s
61
+ name
62
+ end
63
+
64
+ ALL = new("ALL", 0)
65
+ FINE_TRACE = new("FINE", 1000)
66
+ TRACE = new("TRACE", 2000)
67
+ DEBUG = new("DEBUG", 3000)
68
+ CONF = new("CONF", 4000)
69
+ INFO = new("INFO", 5000)
70
+ WARN = new("WARN", 6000)
71
+ ERROR = new("ERROR", 7000)
72
+ FATAL = new("FATAL", 8000)
73
+ UNFORMATTED = new("UNF", 9000)
74
+ OFF = new("OFF", 10000)
75
+
76
+ end
77
+
78
+ end
@@ -0,0 +1,33 @@
1
+ #
2
+ # Suraj Vijayakumar
3
+ # 19-02-2011
4
+ #
5
+
6
+ module LogEasy
7
+
8
+ # Represents the actual log message. Simply a wrapper for the log information (i.e. level, logger, timestamp, message, etc...).
9
+ class Log
10
+
11
+ attr_reader :logger
12
+ attr_reader :level
13
+ attr_reader :message
14
+ attr_reader :timestamp
15
+ attr_reader :unformatted
16
+
17
+ # New log item.
18
+ #
19
+ # 'logger' - The logger that received this log message.
20
+ # 'level' - The severity of this log.
21
+ # 'message' - The message to log.
22
+ # 'unformatted' - Optional. Default is false, but if set to true, this log item will not be formatted.
23
+ def initialize(logger, level, message, unformatted = false)
24
+ @logger = logger
25
+ @level = level
26
+ @message = message
27
+ @timestamp = Time.now
28
+ @unformatted = unformatted
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,256 @@
1
+ #
2
+ # Suraj Vijayakumar
3
+ # 19-02-2011
4
+ #
5
+
6
+ require "logeasy/level"
7
+ require "logeasy/log"
8
+ require "logeasy/appender"
9
+
10
+ module LogEasy
11
+
12
+ # The logger class. Use the 'get_logger' method to create and use loggers.
13
+ class Logger
14
+
15
+ # Get the logger identified by the specified name. If a logger does not exist, a new one is created and returned.
16
+ #
17
+ # 'logger_name' - The name of the logger. The name should be a hierarchy of logger names separated by the '.' or "::" characters.
18
+ def Logger.get_logger(logger_name)
19
+ # Return immediately if the logger was found.
20
+ return @@loggers[logger_name] if @@loggers.has_key?(logger_name)
21
+ # Logger does not exist. Create each part.
22
+ parent = root_logger
23
+ logger_name_parts = logger_name.split(/\.|::/)
24
+ logger_name_parts.each do |part|
25
+ # Each part must be at least one character long (i.e. 2 consecutive '.' are not allowed).
26
+ raise "Invalid logger name '#{logger_name}'!" if part.length == 0
27
+ # Add this part to the current parent. If the logger is already present in this parent, then nothing is done.
28
+ parent = parent.add_logger(part)
29
+ end
30
+ # Finally, the parent is the required logger.
31
+ parent
32
+ end
33
+
34
+ # Get the root logger. The root logger is special, since it does not have a parent.
35
+ #
36
+ # Returns => Logger
37
+ def Logger.root_logger
38
+ @@root_logger = new(nil, "Root") if @@root_logger.nil?
39
+ @@root_logger
40
+ end
41
+
42
+ # Get the internal logger. By default this logger is switched off.
43
+ # This logger is special too, since it has no parent.
44
+ #
45
+ # Returns => Logger
46
+ def Logger.self_logger
47
+ if @@self_logger.nil?
48
+ @@self_logger = new(nil, "EasyLog")
49
+ @@self_logger.min_level = Level::OFF
50
+ end
51
+ @@self_logger
52
+ end
53
+
54
+ attr_reader :parent
55
+ attr_reader :name
56
+ attr_reader :full_name
57
+ attr_accessor :min_level
58
+ attr_accessor :use_parent_logger
59
+
60
+ # Writes the specified log without any formatting to the output.
61
+ # This is treated as any other log message (i.e. the level restrictions apply), only the output is not formatted.
62
+ # By default the level is UNFORMATTED (higher than FATAL).
63
+ #
64
+ # 'message' - The message to print.
65
+ # 'level' - The level of the message. Default is UNFORMATTED.
66
+ def <<(message, level = Level::UNFORMATTED)
67
+ # The unformatted log item.
68
+ log_item = Log.new(self, level, message, true)
69
+ do_log(log_item)
70
+ end
71
+
72
+ # Adds an appender to this logger. Removes the appender from any other logger it was associated with.
73
+ #
74
+ # 'appender' - The appender to add.
75
+ def add_appender(appender)
76
+ # Remove the appender from its earlier logger, if it exists.
77
+ logger = appender.logger
78
+ logger.remove_appender(appender) if not logger.nil?
79
+ # Save the new logger and add it to the appender list.
80
+ # Update the min_level to this logger's min level, if the appender's min level was nil (i.e. a new appender).
81
+ appender.logger = self
82
+ appender.min_level = self.min_level if appender.min_level.nil?
83
+ appenders << appender
84
+ Logger.self_logger.fine("Added '#{appender}' to '#{self}'.")
85
+ end
86
+
87
+ # Adds a child logger of the specified name. If a child already exists then nothing is done.
88
+ # The method will always return the child logger (new or old).
89
+ # This method is used internally to create loggers. Users should use the 'get_logger' method instead to create logger.
90
+ #
91
+ # 'logger_name' - The name of the logger.
92
+ #
93
+ # Returns => Logger
94
+ def add_logger(logger_name)
95
+ if not children.has_key?(logger_name)
96
+ logger = Logger.new(self, logger_name)
97
+ children[logger_name] = logger
98
+ Logger.self_logger.fine("Created new logger '#{logger}'.")
99
+ end
100
+ # Return the logger.
101
+ children[logger_name]
102
+ end
103
+
104
+ # Logs a CONF level message.
105
+ #
106
+ # 'message' - The log's message.
107
+ def conf(message)
108
+ log(Level::CONF, message)
109
+ end
110
+
111
+ # Logs a DEBUG level message.
112
+ #
113
+ # 'message' - The log's message.
114
+ def debug(message)
115
+ log(Level::DEBUG, message)
116
+ end
117
+
118
+ # Logs a ERROR level message.
119
+ #
120
+ # 'message' - The log's message.
121
+ def error(message)
122
+ log(Level::ERROR, message)
123
+ end
124
+
125
+ # Logs a FATAL level message.
126
+ #
127
+ # 'message' - The log's message.
128
+ def fatal(message)
129
+ log(Level::FATAL, message)
130
+ end
131
+
132
+ # Logs a FINE_TRACE level message.
133
+ #
134
+ # 'message' - The log's message.
135
+ def fine(message)
136
+ log(Level::FINE_TRACE, message)
137
+ end
138
+
139
+ # Logs a INFO level message.
140
+ #
141
+ # 'message' - The log's message.
142
+ def info(message)
143
+ log(Level::INFO, message)
144
+ end
145
+
146
+ # Creates a new log and dispatches it.
147
+ # If this logger's level is higher than the specified level, this method will return immediately.
148
+ #
149
+ # 'level' - The level to log the message at.
150
+ # 'message' - The log's message.
151
+ def log(level, message)
152
+ return if level < min_level
153
+ log_item = Log.new(self, level, message)
154
+ do_log_no_check(log_item)
155
+ end
156
+
157
+ # Recursively change the level of this logger and all child loggers.
158
+ # Use min_level= to limit the change to this logger only.
159
+ #
160
+ # 'new_level' - The new level to set.
161
+ def change_min_level(new_level)
162
+ self.min_level = new_level
163
+ Logger.self_logger.fine("Changed minimum level for '#{self}' to '#{new_level}'.")
164
+ # Cascade to all children.
165
+ children.each_value { |child| child.change_min_level(new_level) }
166
+ end
167
+
168
+ # Remove the specified appender from the list of appenders for this logger.
169
+ #
170
+ # 'appender' - The appender to remove.
171
+ def remove_appender(appender)
172
+ @appenders.reject! { |item| appender.eql?(item) }
173
+ appender.logger = nil
174
+ Logger.self_logger.fine("Removed '#{appender}' from '#{self}'.")
175
+ end
176
+
177
+ # Override to_s to return the full name of this logger.
178
+ def to_s
179
+ full_name
180
+ end
181
+
182
+ # Logs a TRACE level message.
183
+ #
184
+ # 'message' - The log's message.
185
+ def trace(message)
186
+ log(Level::TRACE, message)
187
+ end
188
+
189
+ # Logs a WARN level message.
190
+ #
191
+ # 'message' - The log's message.
192
+ def warn(message)
193
+ log(Level::WARN, message)
194
+ end
195
+
196
+ protected
197
+
198
+ # Dispatch the log to all registered appenders.
199
+ # If the 'use_parent_logger' flag is true, then the log is dispatched to the parent also.
200
+ # A check of the logger's level is not done. This method is called by the 'log' method after it has performed that check.
201
+ #
202
+ # 'log_item' - The log object.
203
+ def do_log_no_check(log_item)
204
+ # Dispatch it.
205
+ appenders.each { |appender| appender.do_log(log_item) }
206
+ # If the 'use_parent_logger' flag is true then dispatch the log to the parent.
207
+ # The root logger and self logger are exceptions, since they do not have a parent.
208
+ parent.do_log(log_item) if use_parent_logger and not parent.nil?
209
+ end
210
+
211
+ # Dispatch the log to all registered appenders.
212
+ # If the 'use_parent_logger' flag is true, then the log is dispatched to the parent also.
213
+ # If the log's level is less than the minimum level of this logger, the method will return immediately.
214
+ #
215
+ # 'log_item' - The log object.
216
+ def do_log(log_item)
217
+ return if log_item.level < self.min_level
218
+ # Needs to be logged. Dispatch it.
219
+ appenders.each { |appender| appender.do_log(log_item) }
220
+ # If the 'use_parent_logger' flag is true then dispatch the log to the parent.
221
+ # The root logger and self logger are exceptions, since they do not have a parent.
222
+ parent.do_log(log_item) if use_parent_logger and not parent.nil?
223
+ end
224
+
225
+ private
226
+
227
+ @@loggers = {}
228
+ @@root_logger = nil
229
+ @@self_logger = nil
230
+
231
+ attr_reader :appenders
232
+ attr_reader :children
233
+
234
+ # Create a new logger.
235
+ #
236
+ # 'parent_logger' - The parent logger of this logger. Only the root logger is created with this value as nil.
237
+ # 'name' - The name of this logger.
238
+ # 'initial_level' - Optional, if omitted the parent's minimum level is used.
239
+ #
240
+ # Returns => Logger
241
+ def initialize(parent_logger, name, initial_level = nil)
242
+ @appenders = []
243
+ @children = {}
244
+ @use_parent_logger = true
245
+
246
+ @parent = parent_logger
247
+ @name = name
248
+ @full_name = @parent.nil? ? @name : "#{@parent.full_name}.#{@name}"
249
+ # The minimum value. If omitted, it is taken from the parent, for the root logger / self logger it will default to ALL.
250
+ # The self logger's level is immediately turned OFF after this.
251
+ @min_level = initial_level.nil? ? (@parent.nil? ? Level::ALL : @parent.min_level) : initial_level
252
+ end
253
+
254
+ end
255
+
256
+ end
metadata ADDED
@@ -0,0 +1,53 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: logeasy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Suraj Vijayakumar
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-02-19 00:00:00.000000000 +05:30
13
+ default_executable:
14
+ dependencies: []
15
+ description: Hierarchical logger for Ruby. The loggers are arranged in a tree. Output
16
+ can be controlled using Levels, Appenders and Formatters.
17
+ email: vijayakumar.suraj@gmail.com
18
+ executables: []
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - lib/logeasy.rb
23
+ - lib/logeasy/appender.rb
24
+ - lib/logeasy/level.rb
25
+ - lib/logeasy/log.rb
26
+ - lib/logeasy/logger.rb
27
+ - lib/example/example.rb
28
+ has_rdoc: true
29
+ homepage: http://rubyforge.org/projects/logeasy/
30
+ licenses: []
31
+ post_install_message:
32
+ rdoc_options: []
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ none: false
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ requirements: []
48
+ rubyforge_project: logeasy
49
+ rubygems_version: 1.5.2
50
+ signing_key:
51
+ specification_version: 3
52
+ summary: A simple hierarchical logger.
53
+ test_files: []