logjam 1.0.0 → 1.2.3

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.
@@ -1,390 +0,0 @@
1
- #! /usr/bin/env ruby
2
- #
3
- # Copyright (c), 2012 Peter Wood
4
- # See the license.txt for details of the licensing of the code in this file.
5
-
6
- require 'json'
7
- require 'logger'
8
- require 'stringio'
9
- require 'yaml'
10
-
11
- # This module defines the name space to be used by all code within the
12
- # LogJam library.
13
- module LogJam
14
- # Module constants.
15
- LOGGER_NAME = :name
16
- LOGGER_FILE = :file
17
- LOGGER_ROTATION = :rotation
18
- LOGGER_MAX_SIZE = :max_size
19
- LOGGER_LEVEL = :level
20
- LOGGER_DEFAULT = :default
21
- LOGGER_DATETIME_FORMAT = :datetime_format
22
- DEFAULT_FILE_NAMES = [".#{File::SEPARATOR}logging.yaml",
23
- ".#{File::SEPARATOR}logging.yml",
24
- ".#{File::SEPARATOR}logging.json",
25
- ".#{File::SEPARATOR}config#{File::SEPARATOR}logging.yaml",
26
- ".#{File::SEPARATOR}config#{File::SEPARATOR}logging.yml",
27
- ".#{File::SEPARATOR}config#{File::SEPARATOR}logging.json"]
28
-
29
- # Module static properties.
30
- @@logjam_modules = {}
31
- @@logjam_loggers = {}
32
-
33
- # This method is used to configure the LogJam module with the various loggers
34
- # it will use.
35
- #
36
- # ==== Parameters
37
- # source:: Either a String containing the path and name of the configuration
38
- # file containing the logging set up, an IO object from which the
39
- # configuration details can be read, a Hash containing a logging
40
- # configuration or nil.
41
- def self.configure(source)
42
- @@logjam_modules = {}
43
- @@logjam_loggers = {}
44
-
45
- # Check for default files if nil was passed in.
46
- source = LogJam.find_default_file if source.nil?
47
-
48
- if !source.kind_of?(Hash) && !source.nil?
49
- io = source.kind_of?(String) ? File.new(source) : source
50
- type = source.kind_of?(String) ? LogJam.guess_format(source) : nil
51
- LogJam.process_configuration(LogJam.load_configuration(io, type))
52
- elsif source.nil?
53
- LogJam.process_configuration({})
54
- else
55
- LogJam.process_configuration(source)
56
- end
57
- end
58
-
59
- # This method is used to install logging facilities at the class level for a
60
- # given class. Once 'logified' a class will possess two new methods. The
61
- # first, #log(), retrieves the logger associated with the class. The second,
62
- # #log=(), allows the assignment of the logger associated with the class.
63
- # Note that changing the logger associated with a class will impact all other
64
- # classes that use the same logger.
65
- #
66
- # ==== Parameters
67
- # target:: The target class that is to be extended.
68
- # name:: The name of the logger to be used by the class. Defaults to nil
69
- # to indicate use of the default logger.
70
- def self.apply(target, name=nil)
71
- target.extend(LogJam.get_module(name))
72
- target.send(:define_method, :log) {LogJam.get_logger(name)} if !target.method_defined?(:log)
73
- end
74
-
75
- # This method attempts to fetch the logger for a specified name. If this
76
- # logger does not exist then a default logger will be returned instead.
77
- #
78
- # ==== Parameters
79
- # name:: The name of the logger to retrieve.
80
- def self.get_logger(name=nil)
81
- LogJam.process_configuration(nil) if @@logjam_loggers.empty?
82
- @@logjam_loggers.fetch(name, @@logjam_loggers[nil])
83
- end
84
-
85
- # This method fetches a list of the names currently defined within the LogJam
86
- # internal settings.
87
- def self.names
88
- @@logjam_loggers.keys.compact
89
- end
90
-
91
- # A convenience mechanism that provides an instance level access to the
92
- # class level logger.
93
- def log
94
- self.class.log
95
- end
96
-
97
- private
98
-
99
- # This method fetches the module associated with a name. If the module does
100
- # not exist the default module is returned instead.
101
- #
102
- # ==== Parameters
103
- # name:: The name associated with the module to return.
104
- def self.get_module(name)
105
- LogJam.create_module(name)
106
- end
107
-
108
- # This method attempts to load a LogJam configuration from an IO object.
109
- #
110
- # ==== Parameters
111
- # source:: The IO object to read the configuration details from.
112
- # type:: An indicator of the format being used for the configuration. This
113
- # should be :yaml, :json or nil. Nil indicates that the library
114
- # will try to load the file in various formats.
115
- def self.load_configuration(source, type)
116
- configuration = nil
117
- if ![:yaml, :json].include?(type)
118
- begin
119
- # Read in the full details of the configuration.
120
- details = source.read
121
-
122
- # Try YAML format first.
123
- begin
124
- configuration = LogJam.load_yaml_configuration(StringIO.new(details))
125
- rescue LogJamError
126
- # Assume wrong format and ignore.
127
- configuration = nil
128
- end
129
-
130
- if configuration.nil?
131
- # Try JSON format second.
132
- begin
133
- configuration = LogJam.load_json_configuration(StringIO.new(details))
134
- rescue LogJamError
135
- # Assume wrong format and ignore.
136
- configuration = nil
137
- end
138
- end
139
- rescue => error
140
- raise LogJamError.new("Exception raised loading the LogJam "\
141
- "configuration.\nCause: #{error}", error)
142
- end
143
-
144
- # Check if the load was successful.
145
- if configuration.nil?
146
- raise LogJamError.new("Error loading the LogJam configuration. The "\
147
- "configuration is not in a recognised format "\
148
- "or contains errors. The configuration must "\
149
- "be in either YAML or JSON format.")
150
- end
151
- elsif type == :json
152
- configuration = LogJam.load_json_configuration(source)
153
- elsif type == :yaml
154
- configuration = LogJam.load_yaml_configuration(source)
155
- end
156
- configuration
157
- end
158
-
159
- # This method attempts to load a configuration for the LogJam library from
160
- # a file. The configuration is expected to be in YAML format.
161
- #
162
- # ==== Parameters
163
- # source:: An IO object from which the configuration will be read.
164
- def self.load_yaml_configuration(source)
165
- begin
166
- YAML.load(source)
167
- rescue => error
168
- raise LogJamError.new("Error loading LogJam configuration from YAML "\
169
- "source.\nCause: #{error}", error)
170
- end
171
- end
172
-
173
- # This method attempts to load a configuration for the LogJam library from
174
- # a file. The configuration is expected to be in JSON format.
175
- #
176
- # ==== Parameters
177
- # source:: An IO object from which the configuration will be read.
178
- def self.load_json_configuration(source)
179
- begin
180
- JSON.parse(source.read)
181
- rescue => error
182
- raise LogJamError.new("Error loading LogJam configuration from JSON "\
183
- "source.\nCause: #{error}", error)
184
- end
185
- end
186
-
187
- # This method processes a logger configuration and generates the appropriate
188
- # set of loggers and internal objects from it.
189
- #
190
- # ==== Parameters
191
- # configuration:: The configuration to be processed. If this is nil or empty
192
- # then a single default logger is generated that writes to the standard
193
- # output stream.
194
- def self.process_configuration(configuration)
195
- if !configuration.nil? && !configuration.empty?
196
- key = (configuration.include?(:loggers) ? :loggers : "loggers")
197
- if configuration.include?(key)
198
- loggers = configuration[key]
199
- if loggers.kind_of?(Array)
200
- configuration[key].each do |definition|
201
- LogJam.create_logger(definition)
202
- end
203
- elsif loggers.kind_of?(Hash)
204
- LogJam.create_logger(loggers)
205
- else
206
- raise LogJamError.new("The loggers configuration entry is in "\
207
- "an unrecognised format. Must be either "\
208
- "a Hash or an Array.")
209
- end
210
- end
211
- end
212
-
213
- # Set up any aliases that have been specified.
214
- if !@@logjam_loggers.empty? && !configuration.nil? && !configuration.empty?
215
- key = (configuration.include?(:loggers) ? :aliases : "aliases")
216
- if configuration.include?(key)
217
- configuration[key].each do |name, equivalent|
218
- @@logjam_loggers[name] = LogJam.get_logger(equivalent)
219
- @@logjam_modules[name] = LogJam.get_module(equivalent)
220
- end
221
- end
222
- end
223
-
224
- # Create a default logger if one hasn't been specified.
225
- if @@logjam_loggers[nil].nil?
226
- LogJam.create_logger({LOGGER_FILE => "STDOUT"})
227
- end
228
- end
229
-
230
- # This method is used to create an anonymous module under a given name (if it
231
- # doesn't already exist) and return it to the caller.
232
- #
233
- # ==== Parameters
234
- # name:: The name to create the module under.
235
- def self.create_module(name)
236
- if !@@logjam_modules.include?(name)
237
- # Create the anonymous module and add methods to it.
238
- @@logjam_modules[name] = Module.new
239
- @@logjam_modules[name].send(:define_method, :log) do
240
- LogJam.get_logger(name)
241
- end
242
- @@logjam_modules[name].send(:define_method, :log=) do |logger|
243
- LogJam.get_logger(name).logger = logger
244
- end
245
- end
246
- @@logjam_modules[name]
247
- end
248
-
249
- # This method extends a specified class with a named module.
250
- #
251
- # ==== Parameters
252
- # target:: The class that is to be extended.
253
- # name:: The name of the module to extend the class with.
254
- def self.extend_class(target, name)
255
- target.extend(LogJam.get_module(name))
256
- end
257
-
258
- # This method attempts to guess the format that configuration details will be
259
- # in given a file name. Guessing is done by looking at the file's extension.
260
- # Files ending in '.yaml' or '.yml' are considered YAML. Files ending '.json'
261
- # are considered JSON. The method returns nil if the path passed in has
262
- # neither of these extensions.
263
- #
264
- # ==== Parameters
265
- # path:: The path and name of the file to make the guess from.
266
- def self.guess_format(path)
267
- type = nil
268
- if path.nil? && path.include?(".")
269
- offset = path.length - path.reverse.index(".")
270
- extension = path[offset, path.length - offset].downcase
271
- case extension
272
- when 'yaml', 'yml'
273
- type = :yaml
274
-
275
- when 'json'
276
- type = :json
277
- end
278
- end
279
- type
280
- end
281
-
282
- # This method creates a logger from a given definition. A definition should
283
- # be a Hash containing the values that are used to configure the Logger with.
284
- #
285
- # ==== Parameters
286
- # definition:: A Hash containing the configuration details for the logger.
287
- def self.create_logger(definition)
288
- # Fetch the configuration values.
289
- name = LogJam.get_value(definition, LOGGER_NAME)
290
- path = LogJam.get_value(definition, LOGGER_FILE)
291
- rotation = LogJam.get_value(definition, LOGGER_ROTATION)
292
- max_size = LogJam.get_value(definition, LOGGER_MAX_SIZE)
293
- level = LogJam.get_value(definition, LOGGER_LEVEL)
294
- default = LogJam.get_value(definition, LOGGER_DEFAULT)
295
-
296
- device = nil
297
- if ["STDOUT", "STDERR"].include?(path)
298
- device = (path == "STDOUT" ? STDOUT : STDERR)
299
- else
300
- device = path
301
- end
302
-
303
- if rotation.kind_of?(String) && /^\s*\d+\s*$/ =~ rotation
304
- rotation = rotation.to_i
305
- rotation = 0 if rotation < 0
306
- end
307
-
308
- if !max_size.nil? && max_size.kind_of?(String)
309
- max_size = max_size.to_i
310
- end
311
- max_size = 1048576 if !max_size.nil? && max_size < 1024
312
-
313
- if !level.nil?
314
- case level.downcase
315
- when 'info'
316
- level = Logger::INFO
317
-
318
- when 'warn'
319
- level = Logger::WARN
320
-
321
- when 'error'
322
- level = Logger::ERROR
323
-
324
- when 'fatal'
325
- level = Logger::FATAL
326
-
327
- when 'unknown'
328
- level = Logger::UNKNOWN
329
-
330
- else
331
- level = Logger::DEBUG
332
- end
333
- else
334
- level = Logger::DEBUG
335
- end
336
-
337
- if default != true
338
- if default.kind_of?(String)
339
- default = ["true", "yes", "on", "1"].include?(default.downcase)
340
- else
341
- default = false
342
- end
343
- end
344
-
345
- # Create the actual logger and associated module.
346
- logger = LogJamLogger.new(device, rotation, max_size)
347
- logger.level = level
348
- logger.name = name
349
- logger.progname = name
350
- @@logjam_loggers[name] = logger
351
- logger_module = LogJam.create_module(name)
352
- if default
353
- @@logjam_loggers[nil] = logger
354
- @@logjam_modules[nil] = logger_module
355
- end
356
- logger
357
- end
358
-
359
- # This method attempts to fetch a value from a Hash. The key passed to the
360
- # method should be a symbol and this will be checked for first. If this is
361
- # not found then a check is made for the string equivalent. The first of
362
- # these that is present in the Hash generates the value returned. If neither
363
- # is present in the Hash then nil is returned.
364
- #
365
- # ==== Parameters
366
- # source:: The Hash that will be checked for the value.
367
- # key:: A symbol that will be checked as the key for the value.
368
- def self.get_value(source, key)
369
- if source.include?(key)
370
- source[key]
371
- elsif source.include?(key.to_s)
372
- source[key.to_s]
373
- else
374
- nil
375
- end
376
- end
377
-
378
- # This module level method is used to check for the existence of a
379
- # configuration file under one or a standard set of names. This method is
380
- # only used whenever the configure method is called and either passed nil
381
- # or no parameter.
382
- def self.find_default_file
383
- file_name = nil
384
- DEFAULT_FILE_NAMES.each do |name|
385
- file_name = name if File.exists?(name) && File.readable?(name)
386
- break if !file_name.nil?
387
- end
388
- file_name
389
- end
390
- end
@@ -1,202 +0,0 @@
1
- #! /usr/bin/env ruby
2
- #
3
- # Copyright (c), 2012 Peter Wood
4
- # See the license.txt for details of the licensing of the code in this file.
5
-
6
- module LogJam
7
- # This class represents a specialization of the Ruby Logger class. The class
8
- # retains a Ruby Logger instance within itself and delegates all standard
9
- # logger calls to this instance. This allows for changes to the underlying
10
- # logger without changing the containing one, thus bypassing people caching
11
- # an instance.
12
- class LogJamLogger < Logger
13
- # Constructor for the LogJamLogger class. All parameters are passed
14
- # straight through to create a standard Ruby Logger instance except
15
- # when the first parameter is a Logger instance. In this case the
16
- # Logger passed in is used rather than creating a new one.
17
- #
18
- # ==== Parameters
19
- # logdev:: The log device to be used by the logger. This should
20
- # either be a String containing a file path/name or an IO
21
- # object that the logging details will be written to.
22
- # shift_age:: The maximum number of old log files to retain or a String
23
- # containing the rotation frequency for the log.
24
- # shift_size:: The maximum size that the loggin output will be allowed
25
- # to grow to before rotation occurs.
26
- def initialize(logdev, shift_age=0, shift_size=1048576)
27
- if logdev.kind_of?(Logger)
28
- @log = logdev
29
- else
30
- @log = Logger.new(logdev, shift_age, shift_size)
31
- end
32
- @name = nil
33
- end
34
-
35
- # Attribute accessor/mutator declaration.
36
- attr_accessor :name
37
-
38
- # Overload of the property fetcher provided by the contained Logger
39
- # instance.
40
- def formatter
41
- @log.formatter
42
- end
43
-
44
- # Overload of the property updater provided by the contained Logger
45
- # instance.
46
- def formatter=(formatter)
47
- @log.formatter = formatter
48
- end
49
-
50
- # Overload of the property fetcher provided by the contained Logger
51
- # instance.
52
- def level
53
- @log.level
54
- end
55
-
56
- # Overload of the property updater provided by the contained Logger
57
- # instance.
58
- def level=(level)
59
- @log.level = level
60
- end
61
-
62
- # Overload of the property fetcher provided by the contained Logger
63
- # instance.
64
- def progname
65
- @log.progname
66
- end
67
-
68
- # Overload of the property updater provided by the contained Logger
69
- # instance.
70
- def progname=(name)
71
- @log.progname = name
72
- end
73
-
74
- # Overload of the property fetcher provided by the contained Logger
75
- # instance.
76
- def sev_threshold
77
- @log.sev_threshold
78
- end
79
-
80
- # Overload of the property updater provided by the contained Logger
81
- # instance.
82
- def sev_threshold=(threshold)
83
- @log.sev_threshold = threshold
84
- end
85
-
86
- # Overload of the corresponding method on the Logger class to pass the
87
- # call straight through to the contained logger.
88
- def <<(message)
89
- @log << message
90
- end
91
-
92
- # Overload of the corresponding method on the Logger class to pass the
93
- # call straight through to the contained logger.
94
- def add(severity, message=nil, program=nil, &block)
95
- @log.add(severity, message, program, &block)
96
- end
97
-
98
- # Overload of the corresponding method on the Logger class to pass the
99
- # call straight through to the contained logger.
100
- def close
101
- @log.close
102
- end
103
-
104
- # Overload of the corresponding method on the Logger class to pass the
105
- # call straight through to the contained logger.
106
- def datetime_format
107
- @log.datetime_format
108
- end
109
-
110
- # Overload of the corresponding method on the Logger class to pass the
111
- # call straight through to the contained logger.
112
- def datetime_format=(format)
113
- @log.datetime_format = format
114
- end
115
-
116
- # Overload of the corresponding method on the Logger class to pass the
117
- # call straight through to the contained logger.
118
- def debug(program=nil, &block)
119
- @log.debug(program, &block)
120
- end
121
-
122
- # Overload of the corresponding method on the Logger class to pass the
123
- # call straight through to the contained logger.
124
- def debug?
125
- @log.debug?
126
- end
127
-
128
- # Overload of the corresponding method on the Logger class to pass the
129
- # call straight through to the contained logger.
130
- def error(program=nil, &block)
131
- @log.error(program, &block)
132
- end
133
-
134
- # Overload of the corresponding method on the Logger class to pass the
135
- # call straight through to the contained logger.
136
- def error?
137
- @log.error?
138
- end
139
-
140
- # Overload of the corresponding method on the Logger class to pass the
141
- # call straight through to the contained logger.
142
- def fatal(program=nil, &block)
143
- @log.fatal(program, &block)
144
- end
145
-
146
- # Overload of the corresponding method on the Logger class to pass the
147
- # call straight through to the contained logger.
148
- def fatal?
149
- @log.fatal?
150
- end
151
-
152
- # Overload of the corresponding method on the Logger class to pass the
153
- # call straight through to the contained logger.
154
- def info(program=nil?, &block)
155
- @log.info(program, &block)
156
- end
157
-
158
- # Overload of the corresponding method on the Logger class to pass the
159
- # call straight through to the contained logger.
160
- def info?
161
- @log.info?
162
- end
163
-
164
- # Overload of the corresponding method on the Logger class to pass the
165
- # call straight through to the contained logger.
166
- def unknown(program=nil, &block)
167
- @log.unknown(program, &block)
168
- end
169
-
170
- # Overload of the corresponding method on the Logger class to pass the
171
- # call straight through to the contained logger.
172
- def warn(program=nil, &block)
173
- @log.warn(program, &block)
174
- end
175
-
176
- # Overload of the corresponding method on the Logger class to pass the
177
- # call straight through to the contained logger.
178
- def warn?
179
- @log.warn?
180
- end
181
-
182
- # This method fetches the standard Ruby Logger instance contained within
183
- # a LogJamLogger object.
184
- def logger
185
- @log
186
- end
187
-
188
- # This method updates the logger instance contained within a LogJamLogger
189
- # object.
190
- #
191
- # ==== Parameters
192
- # logger:: The object to set as the contained logger. This should be an
193
- # instance of the standard Ruby Logger class or something
194
- # compatible with this.
195
- def logger=(logger)
196
- @log = logger
197
- end
198
-
199
- # Aliases
200
- alias :log :add
201
- end
202
- end