logeasy 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []