logjam 0.0.1
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/README +265 -0
- data/lib/logjam/exceptions.rb +40 -0
- data/lib/logjam/logjam-original.rb +129 -0
- data/lib/logjam/logjam.rb +382 -0
- data/lib/logjam/logjam_logger.rb +202 -0
- data/lib/logjam.rb +10 -0
- data/license.txt +21 -0
- metadata +82 -0
data/README
ADDED
@@ -0,0 +1,265 @@
|
|
1
|
+
LogJam
|
2
|
+
======
|
3
|
+
LogJam is a library that attempts to allow for the aggregation the distributing
|
4
|
+
logger facilities across a range of classes. Goals in creating this library
|
5
|
+
were...
|
6
|
+
|
7
|
+
* Easy of use. Fall back on defaults as much as possible and allow the
|
8
|
+
functionality to be integrated and used with the least amount of work.
|
9
|
+
|
10
|
+
* Flexibility. After easy of use is taken into consideration it should be
|
11
|
+
possible to use the library in a more advanced fashion if that is called
|
12
|
+
for.
|
13
|
+
|
14
|
+
* Minimize the code to use it. It shouldn't require a great deal of code to
|
15
|
+
deploy or use the facilities and there should be no code required to pass
|
16
|
+
entities such as loggers around.
|
17
|
+
|
18
|
+
* Usable in libraries. I found myself writing a lot of common logging code
|
19
|
+
when writing libraries and application and wanted to abstract that out. I
|
20
|
+
wanted to minimize the burden this placed on library users at the same
|
21
|
+
time.
|
22
|
+
|
23
|
+
Configuration & Setup
|
24
|
+
---------------------
|
25
|
+
The LogJam library is configured through a call to the configure() method on the
|
26
|
+
LogJam module. This method accepts a single parameter that may be either a
|
27
|
+
String, a Hash, an IO object or nil.
|
28
|
+
|
29
|
+
If you pass a String in this is expected to contain the path and name of a file
|
30
|
+
that contains the logging configuration. Logging configuration files can be
|
31
|
+
provided in either YAML or JSON format. If you pass an IO object this is
|
32
|
+
expected to be the source of the configuration and, again, this configuration
|
33
|
+
should be in either YAML or JSON format. In either case, where a String or IO
|
34
|
+
is specified, the data read must be translatable into a Hash, which brings us
|
35
|
+
to the other type that the configure() method accepts as a parameter.
|
36
|
+
|
37
|
+
A Hash passed to the configure() method is expected to contain a set of values
|
38
|
+
that can be converted into a logging set up. Passing an empty Hash will result
|
39
|
+
in set up containing a single, universal logger attached to the standard output
|
40
|
+
stream being created and used by all classes that have LogJam functionality.
|
41
|
+
|
42
|
+
The Hash passed to the configure() method can contain two keys that the library
|
43
|
+
will recognise and use. The first of these is 'loggers', in either Symbol or
|
44
|
+
String form. The value under the loggers key is expected to be an Array
|
45
|
+
containing zero or more logger definitions. A logger definition is a Hash in
|
46
|
+
which the following keys are recognised (either as Strings or Symbols)...
|
47
|
+
|
48
|
+
Key Description
|
49
|
+
----------------------- --------------------------------------------------
|
50
|
+
default A boolean indicating whether this logger is the
|
51
|
+
default (i.e. the one to be used when no other
|
52
|
+
fits the bill).
|
53
|
+
datetime_format The date/time format to be used by the logger. See
|
54
|
+
the documentation for the standard Ruby Logger
|
55
|
+
class for more details.
|
56
|
+
file The path and name of the file that logging details
|
57
|
+
will be written to. Two special values are
|
58
|
+
recognised in this value. STDOUT and STDERR are
|
59
|
+
translated to mean the standard output or error
|
60
|
+
streams respectively.
|
61
|
+
level The logging level to set on the logger.
|
62
|
+
max_size When rotation is set to an integer value this value
|
63
|
+
can be set to indicate the maximum permitted file
|
64
|
+
size for a log file.
|
65
|
+
name The name to associate with the logger. This allows
|
66
|
+
loggers to be tied to classes or for the creation
|
67
|
+
of aliases that tie multiple names to a single
|
68
|
+
logger.
|
69
|
+
rotation The frequency with which the log file is rotated.
|
70
|
+
This may be an integer to indicate how many old log
|
71
|
+
files are retained or may be a String such as
|
72
|
+
"daily", "weekly" or "monthly".
|
73
|
+
|
74
|
+
A note on logger names. Logger names (including alias names) aren't hierarchical
|
75
|
+
and should be unique.
|
76
|
+
|
77
|
+
The second key recognised in the configuration Hash is 'aliases', again as
|
78
|
+
either a String or Symbol. The value under the aliases key is expected to be a
|
79
|
+
Hash that maps String keys to String values. The key values are expected to be
|
80
|
+
alias names and the mapped values are expected to be the name of a logger
|
81
|
+
declared in the logger section. An entry in the aliases Hash creates an alias
|
82
|
+
for an existing logger under a different name.
|
83
|
+
|
84
|
+
If you pass nil to the configure method it behaves in a slightly different
|
85
|
+
fashion. In this case the method searches for a configuration file that it can
|
86
|
+
use given a default set of files names (basically logging.yaml, logging.yml and
|
87
|
+
logging.json in the current working directory and in a subdirectory of the
|
88
|
+
current working directory called config). The first of these files that it finds
|
89
|
+
it attempts to use as configuration for the logging set up.
|
90
|
+
|
91
|
+
See the end of this document for some example configurations.
|
92
|
+
|
93
|
+
Logging With The Library
|
94
|
+
------------------------
|
95
|
+
The stated goals of the LogJam library are to avoid the need to pass Logger
|
96
|
+
instances around while still allowing potentially complex configuration with a
|
97
|
+
minimum of code. The first step in this process has been covered in the
|
98
|
+
Configuration & Setup section in which it's explained how to configure logging
|
99
|
+
from a single Hash or file. This section will provide details on how to deploy
|
100
|
+
loggers to various classes.
|
101
|
+
|
102
|
+
The LogJam library works by providing an extension to any class that uses it
|
103
|
+
that provides access to the logger to be used by the class. To make use of this
|
104
|
+
functionality a class must call the apply() method of the LogJam module. A
|
105
|
+
typical call to this method might look like...
|
106
|
+
|
107
|
+
LogJam.apply(self, "my_logger")
|
108
|
+
|
109
|
+
This line would appear somewhere inside the definition for the class that will
|
110
|
+
use logging. The first parameter to the call is the class that is to be extended
|
111
|
+
with the LogJam functionality. The second parameter is the name of the logger
|
112
|
+
that the class will use. Note that this parameter is optional and, if not
|
113
|
+
specified or if a matching logger does not exist, the class will fall back in
|
114
|
+
using the default logger.
|
115
|
+
|
116
|
+
Once this line has been added to the class definition it will cause the class to
|
117
|
+
be extended with two methods - one called log() and one called log=(). The first
|
118
|
+
of these retrieves the Logger instance to be used by the class instances. The
|
119
|
+
second allows the Logger instance associated with a class to be altered.
|
120
|
+
|
121
|
+
The following complete (although contrived) example gives an overview of how
|
122
|
+
this would work...
|
123
|
+
|
124
|
+
require 'rubygems'
|
125
|
+
require 'logjam'
|
126
|
+
|
127
|
+
class Writer
|
128
|
+
LogJam.apply(self, "echo")
|
129
|
+
|
130
|
+
def initialize(stream=STDOUT)
|
131
|
+
@stream = stream
|
132
|
+
end
|
133
|
+
|
134
|
+
def echo(message)
|
135
|
+
Writer.log.debug("Echoed: #{message}")
|
136
|
+
@stream.puts message
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
begin
|
141
|
+
LogJam.configure({:loggers => [{:name => "echo",
|
142
|
+
:file => "echo.log"}]})
|
143
|
+
|
144
|
+
writer = Writer.new
|
145
|
+
writer.echo "This is a string containing my message."
|
146
|
+
rescue => error
|
147
|
+
puts "ERROR: #{error}\n" + error.backtrace.join("\n")
|
148
|
+
end
|
149
|
+
|
150
|
+
In this example we create a Writer class that can echo a String on a stream. In
|
151
|
+
doing this it also logs the message echoed at the debug level. We use the
|
152
|
+
LogJam.apply() method to extend this class with logging capabilities so that, in
|
153
|
+
the echo() method, we can simply call Writer.log() to get the class logger.
|
154
|
+
|
155
|
+
In the later section of the code we configure the LogJam system to have a single
|
156
|
+
Logger that writes to the echo.log file. We then create a Writer instance and
|
157
|
+
use it to write a simple message. This message should appear on the standard
|
158
|
+
output stream and be logged to the echo.log file.
|
159
|
+
|
160
|
+
Advanced Usage
|
161
|
+
--------------
|
162
|
+
The hope would be that this library can be used in the creation of other
|
163
|
+
libraries and allow for control of the logging generated by those libraries
|
164
|
+
without having to dig into the workings of the library or to pass around Logger
|
165
|
+
instances are constructor parameters or static data. In this case I recommend
|
166
|
+
explicitly declaring logger names when using the apply() method and making the
|
167
|
+
name that the library uses available with the library documentation so that the
|
168
|
+
libraries logging can be switched off or on as needed.
|
169
|
+
|
170
|
+
It's intended that, in general, the configure() method on the LogJam module
|
171
|
+
should only be called once. Calling it a second time will clear all existing
|
172
|
+
logging configuration and set up. This may or may not be an issue depending on
|
173
|
+
whether you decide to cache logger inside class instances instead of always
|
174
|
+
accessing them through the class level accessor.
|
175
|
+
|
176
|
+
The Logger instance returned from a LogJam are intended to be fully compatible
|
177
|
+
with the class defined within the standard Ruby Logger library. If you need to
|
178
|
+
change elements, such as the formatter, you should just do so on the logger in
|
179
|
+
the normal fashion. If you define multiple Logger instances then you will have
|
180
|
+
to change each individually.
|
181
|
+
|
182
|
+
Using the log=() method that is added to each class by the LogJam facilities it
|
183
|
+
is possible to change the Logger being used. If you want to use this method
|
184
|
+
please note that changing a Logger that is created via an alias will change the
|
185
|
+
original Logger and thereby affect all classes that make use of that Logger (and
|
186
|
+
not necessarily just the one making the change). If you want to do this give the
|
187
|
+
class it's own logger instance.
|
188
|
+
|
189
|
+
Finally, any logger can be fetched from the library using it's name and making
|
190
|
+
a call to the LogJam.get_logger() method. Note if you omit the name or pass in
|
191
|
+
nil you will retrieve the libraries default logger.
|
192
|
+
|
193
|
+
Example Configurations
|
194
|
+
----------------------
|
195
|
+
This section contains some example configurations. A short explanation is given
|
196
|
+
for each configuration and then the configuration itself in Hash, YAML and JSON
|
197
|
+
formats is provided.
|
198
|
+
|
199
|
+
This represents the most basic configuration possible. In passing an empty Hash
|
200
|
+
to the configure method the system creates a single, default logger that writes
|
201
|
+
everything on the standard output stream...
|
202
|
+
|
203
|
+
Hash
|
204
|
+
{}
|
205
|
+
|
206
|
+
YAML
|
207
|
+
---
|
208
|
+
{}
|
209
|
+
|
210
|
+
JSON
|
211
|
+
{}
|
212
|
+
|
213
|
+
The following simple configuration writes all logging output to a file called
|
214
|
+
application.log in the current working directory. If a logging level is not
|
215
|
+
explicitly specified then DEBUG is the default...
|
216
|
+
|
217
|
+
Hash
|
218
|
+
{:loggers => [{:default => true, :file => "application.log"}]}
|
219
|
+
|
220
|
+
YAML
|
221
|
+
---
|
222
|
+
:loggers:
|
223
|
+
- :default: true
|
224
|
+
:file: application.log
|
225
|
+
|
226
|
+
JSON
|
227
|
+
{"loggers": {"default": true, "file": "application.log"}}
|
228
|
+
|
229
|
+
This configuration declares two loggers. The first is called 'silent' and will
|
230
|
+
log nothing. The silent logger is the default and so will be used for any class
|
231
|
+
that doesn't have an explicitly named logger. The second is called 'verbose' and
|
232
|
+
logs everything from the debug level up on the standard output stream. The
|
233
|
+
configuration also declares an alias pointing the name 'database' to refer to
|
234
|
+
the verbose logger. An class that declares it uses the 'database' logger will
|
235
|
+
generate output while all others will be silenced.
|
236
|
+
|
237
|
+
Hash
|
238
|
+
{:loggers => [{:default => true,
|
239
|
+
:file => "STDOUT",
|
240
|
+
:level => "UNKNOWN",
|
241
|
+
:name => "silent"},
|
242
|
+
{:file => "STDOUT",
|
243
|
+
:name => "verbose"}],
|
244
|
+
:aliases => {"database" => "verbose"}}
|
245
|
+
|
246
|
+
YAML
|
247
|
+
---
|
248
|
+
:loggers:
|
249
|
+
- :default: true
|
250
|
+
:file: STDOUT
|
251
|
+
:level: UNKNOWN
|
252
|
+
:name: silent
|
253
|
+
- :file: STDOUT
|
254
|
+
:name: verbose
|
255
|
+
:aliases:
|
256
|
+
database: verbose
|
257
|
+
|
258
|
+
JSON
|
259
|
+
{"loggers": [{"default":true,
|
260
|
+
"file": "STDOUT",
|
261
|
+
"level": "UNKNOWN",
|
262
|
+
"name": "silent"},
|
263
|
+
{"file": "STDOUT",
|
264
|
+
"name": "verbose"}],
|
265
|
+
"aliases": {"database":"verbose"}}
|
@@ -0,0 +1,40 @@
|
|
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 'stringio'
|
7
|
+
|
8
|
+
module LogJam
|
9
|
+
# This class provides the exception class used by the LogJam library.
|
10
|
+
class LogJamError < StandardError
|
11
|
+
# Attribute accessor/mutator declarations.
|
12
|
+
attr_accessor :verbose
|
13
|
+
|
14
|
+
# Constructor for the LogJamError class.
|
15
|
+
#
|
16
|
+
# ==== Parameters
|
17
|
+
# message:: The message to be associated with the error.
|
18
|
+
# cause:: Any underlying exception to be associated with the error.
|
19
|
+
# Defaults to nil.
|
20
|
+
def initialize(message, cause=nil, verbose=true)
|
21
|
+
super(message)
|
22
|
+
@cause = cause
|
23
|
+
@verbose = verbose
|
24
|
+
end
|
25
|
+
|
26
|
+
# This method fetches a stringified interpretation of an exception.
|
27
|
+
def to_s()
|
28
|
+
text = StringIO.new
|
29
|
+
text << super
|
30
|
+
if @verbose
|
31
|
+
text << "\n" + self.backtrace.join("\n")
|
32
|
+
if !@cause.nil?
|
33
|
+
text << "\n\nCause: #{@cause}"
|
34
|
+
text << "\n" + @cause.backtrace.join("\n")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
text.string
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,129 @@
|
|
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 'logger'
|
7
|
+
|
8
|
+
# This module defines the name space to be used by all code within the
|
9
|
+
# LogJam library.
|
10
|
+
module LogJam
|
11
|
+
# Module constants.
|
12
|
+
LOG_FILE = :log_file
|
13
|
+
LOG_ROLL = :log_roll_period
|
14
|
+
LOG_LEVEL = :log_level
|
15
|
+
|
16
|
+
# Module wide property declarations.
|
17
|
+
@@logjam_logger = nil
|
18
|
+
|
19
|
+
# This method fetches the module logger, initializing it and creating it if
|
20
|
+
# it doesn't yet exist.
|
21
|
+
#
|
22
|
+
# ==== Parameters
|
23
|
+
# configuration:: The configuration to use in setting up the logging.
|
24
|
+
# Defaults to nil to indicate the creation of a logger based
|
25
|
+
# on STDOUT.
|
26
|
+
def log(configuration=nil)
|
27
|
+
LogJam.configure(configuration) if !configuration.nil? || @@logjam_logger.nil?
|
28
|
+
@@logjam_logger
|
29
|
+
end
|
30
|
+
|
31
|
+
# This method updates the logger associated with the module.
|
32
|
+
#
|
33
|
+
# ==== Parameters
|
34
|
+
# logger:: The new logger for the module.
|
35
|
+
def log=(logger)
|
36
|
+
LogJam.log = logger
|
37
|
+
end
|
38
|
+
|
39
|
+
# This method updates the logger associated with the module.
|
40
|
+
#
|
41
|
+
# ==== Parameters
|
42
|
+
# logger:: The new logger for the module.
|
43
|
+
def self.log=(logger)
|
44
|
+
@@logjam_logger.logger = logger
|
45
|
+
end
|
46
|
+
|
47
|
+
# This method is used to install the LogJam capabilities into a target class.
|
48
|
+
#
|
49
|
+
# ==== Parameters
|
50
|
+
# target:: The class that is to be 'logified'.
|
51
|
+
def self.logify(target)
|
52
|
+
target.extend(self)
|
53
|
+
end
|
54
|
+
|
55
|
+
# This method sets up the module logging from configuration.
|
56
|
+
#
|
57
|
+
# ==== Parameters
|
58
|
+
# configuration:: The configuration to use when setting up logging.
|
59
|
+
def self.configure(configuration)
|
60
|
+
if !configuration.nil?
|
61
|
+
if @@logjam_logger.nil?
|
62
|
+
# Create the logger.
|
63
|
+
if LogJam.is_configured?(configuration, LOG_FILE)
|
64
|
+
file_name = LogJam.get_value(configuration, LOG_FILE)
|
65
|
+
period = LogJam.get_value(configuration, LOG_ROLL)
|
66
|
+
@@logjam_logger = LogJamLogger.new(file_name, period)
|
67
|
+
else
|
68
|
+
@@logjam_logger = LogJamLogger.new(STDOUT)
|
69
|
+
end
|
70
|
+
else
|
71
|
+
# Change the internally held logger.
|
72
|
+
if LogJam.is_configured?(configuration, LOG_FILE)
|
73
|
+
file_name = LogJam.get_value(configuration, LOG_FILE)
|
74
|
+
period = LogJam.get_value(configuration, LOG_ROLL)
|
75
|
+
@@logjam_logger.logger = Logger.new(file_name, period)
|
76
|
+
else
|
77
|
+
@@logjam_logger.logger = Logger.new(STDOUT)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
else
|
81
|
+
if @@logjam_logger.nil?
|
82
|
+
@@logjam_logger = LogJamLogger.new(STDOUT)
|
83
|
+
else
|
84
|
+
@@logjam_logger.logger = Logger.new(STDOUT)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Set the logger level.
|
89
|
+
level = LogJam.get_value(configuration, LOG_LEVEL, "DEBUG")
|
90
|
+
case level.downcase
|
91
|
+
when "info"
|
92
|
+
level = Logger::INFO
|
93
|
+
when "warn"
|
94
|
+
level = Logger::WARN
|
95
|
+
when "error"
|
96
|
+
level = Logger::ERROR
|
97
|
+
when "fatal"
|
98
|
+
level = Logger::FATAL
|
99
|
+
when "unknown"
|
100
|
+
level = Logger::UNKNOWN
|
101
|
+
else
|
102
|
+
level = Logger::DEBUG
|
103
|
+
end
|
104
|
+
@@logjam_logger.level = level
|
105
|
+
@@logjam_logger
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
# This method encapsulates the functionality for extracting named value from
|
111
|
+
# a Hash given a key.
|
112
|
+
def self.get_value(configuration, name, default=nil)
|
113
|
+
value = default
|
114
|
+
if !configuration.nil?
|
115
|
+
if configuration.include?(name)
|
116
|
+
value = configuration[name]
|
117
|
+
elsif configuration.include?(name.to_s)
|
118
|
+
value = configuration[name.to_s]
|
119
|
+
end
|
120
|
+
end
|
121
|
+
value
|
122
|
+
end
|
123
|
+
|
124
|
+
# This method is used internally by the module to determine whether a
|
125
|
+
# configuration setting has been provided.
|
126
|
+
def self.is_configured?(configuration, name)
|
127
|
+
configuration.include?(name) || configuration.include?(name.to_s)
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,382 @@
|
|
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
|
+
end
|
73
|
+
|
74
|
+
# This method attempts to fetch the logger for a specified name. If this
|
75
|
+
# logger does not exist then a default logger will be returned instead.
|
76
|
+
#
|
77
|
+
# ==== Parameters
|
78
|
+
# name:: The name of the logger to retrieve.
|
79
|
+
def self.get_logger(name=nil)
|
80
|
+
LogJam.process_configuration(nil) if @@logjam_loggers.empty?
|
81
|
+
@@logjam_loggers.fetch(name, @@logjam_loggers[nil])
|
82
|
+
end
|
83
|
+
|
84
|
+
# This method fetches a list of the names currently defined within the LogJam
|
85
|
+
# internal settings.
|
86
|
+
def self.names
|
87
|
+
@@logjam_loggers.keys.compact
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
# This method fetches the module associated with a name. If the module does
|
93
|
+
# not exist the default module is returned instead.
|
94
|
+
#
|
95
|
+
# ==== Parameters
|
96
|
+
# name:: The name associated with the module to return.
|
97
|
+
def self.get_module(name)
|
98
|
+
LogJam.create_module(name)
|
99
|
+
end
|
100
|
+
|
101
|
+
# This method attempts to load a LogJam configuration from an IO object.
|
102
|
+
#
|
103
|
+
# ==== Parameters
|
104
|
+
# source:: The IO object to read the configuration details from.
|
105
|
+
# type:: An indicator of the format being used for the configuration. This
|
106
|
+
# should be :yaml, :json or nil. Nil indicates that the library
|
107
|
+
# will try to load the file in various formats.
|
108
|
+
def self.load_configuration(source, type)
|
109
|
+
configuration = nil
|
110
|
+
if ![:yaml, :json].include?(type)
|
111
|
+
begin
|
112
|
+
# Read in the full details of the configuration.
|
113
|
+
details = source.read
|
114
|
+
|
115
|
+
# Try YAML format first.
|
116
|
+
begin
|
117
|
+
configuration = LogJam.load_yaml_configuration(StringIO.new(details))
|
118
|
+
rescue LogJamError
|
119
|
+
# Assume wrong format and ignore.
|
120
|
+
configuration = nil
|
121
|
+
end
|
122
|
+
|
123
|
+
if configuration.nil?
|
124
|
+
# Try JSON format second.
|
125
|
+
begin
|
126
|
+
configuration = LogJam.load_json_configuration(StringIO.new(details))
|
127
|
+
rescue LogJamError
|
128
|
+
# Assume wrong format and ignore.
|
129
|
+
configuration = nil
|
130
|
+
end
|
131
|
+
end
|
132
|
+
rescue => error
|
133
|
+
raise LogJamError.new("Exception raised loading the LogJam "\
|
134
|
+
"configuration.\nCause: #{error}", error)
|
135
|
+
end
|
136
|
+
|
137
|
+
# Check if the load was successful.
|
138
|
+
if configuration.nil?
|
139
|
+
raise LogJamError.new("Error loading the LogJam configuration. The "\
|
140
|
+
"configuration is not in a recognised format "\
|
141
|
+
"or contains errors. The configuration must "\
|
142
|
+
"be in either YAML or JSON format.")
|
143
|
+
end
|
144
|
+
elsif type == :json
|
145
|
+
configuration = LogJam.load_json_configuration(source)
|
146
|
+
elsif type == :yaml
|
147
|
+
configuration = LogJam.load_yaml_configuration(source)
|
148
|
+
end
|
149
|
+
configuration
|
150
|
+
end
|
151
|
+
|
152
|
+
# This method attempts to load a configuration for the LogJam library from
|
153
|
+
# a file. The configuration is expected to be in YAML format.
|
154
|
+
#
|
155
|
+
# ==== Parameters
|
156
|
+
# source:: An IO object from which the configuration will be read.
|
157
|
+
def self.load_yaml_configuration(source)
|
158
|
+
begin
|
159
|
+
YAML.load(source)
|
160
|
+
rescue => error
|
161
|
+
raise LogJamError.new("Error loading LogJam configuration from YAML "\
|
162
|
+
"source.\nCause: #{error}", error)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
# This method attempts to load a configuration for the LogJam library from
|
167
|
+
# a file. The configuration is expected to be in JSON format.
|
168
|
+
#
|
169
|
+
# ==== Parameters
|
170
|
+
# source:: An IO object from which the configuration will be read.
|
171
|
+
def self.load_json_configuration(source)
|
172
|
+
begin
|
173
|
+
JSON.parse(source.read)
|
174
|
+
rescue => error
|
175
|
+
raise LogJamError.new("Error loading LogJam configuration from JSON "\
|
176
|
+
"source.\nCause: #{error}", error)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
# This method processes a logger configuration and generates the appropriate
|
181
|
+
# set of loggers and internal objects from it.
|
182
|
+
#
|
183
|
+
# ==== Parameters
|
184
|
+
# configuration:: The configuration to be processed. If this is nil or empty
|
185
|
+
# then a single default logger is generated that writes to the standard
|
186
|
+
# output stream.
|
187
|
+
def self.process_configuration(configuration)
|
188
|
+
if !configuration.nil? && !configuration.empty?
|
189
|
+
key = (configuration.include?(:loggers) ? :loggers : "loggers")
|
190
|
+
if configuration.include?(key)
|
191
|
+
loggers = configuration[key]
|
192
|
+
if loggers.kind_of?(Array)
|
193
|
+
configuration[key].each do |definition|
|
194
|
+
LogJam.create_logger(definition)
|
195
|
+
end
|
196
|
+
elsif loggers.kind_of?(Hash)
|
197
|
+
LogJam.create_logger(loggers)
|
198
|
+
else
|
199
|
+
raise LogJamError.new("The loggers configuration entry is in "\
|
200
|
+
"an unrecognised format. Must be either "\
|
201
|
+
"a Hash or an Array.")
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
# Set up any aliases that have been specified.
|
207
|
+
if !@@logjam_loggers.empty? && !configuration.nil? && !configuration.empty?
|
208
|
+
key = (configuration.include?(:loggers) ? :aliases : "aliases")
|
209
|
+
if configuration.include?(key)
|
210
|
+
configuration[key].each do |name, equivalent|
|
211
|
+
@@logjam_loggers[name] = LogJam.get_logger(equivalent)
|
212
|
+
@@logjam_modules[name] = LogJam.get_module(equivalent)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
# Create a default logger if one hasn't been specified.
|
218
|
+
if @@logjam_loggers[nil].nil?
|
219
|
+
LogJam.create_logger({LOGGER_FILE => "STDOUT"})
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
# This method is used to create an anonymous module under a given name (if it
|
224
|
+
# doesn't already exist) and return it to the caller.
|
225
|
+
#
|
226
|
+
# ==== Parameters
|
227
|
+
# name:: The name to create the module under.
|
228
|
+
def self.create_module(name)
|
229
|
+
if !@@logjam_modules.include?(name)
|
230
|
+
# Create the anonymous module and add methods to it.
|
231
|
+
@@logjam_modules[name] = Module.new
|
232
|
+
@@logjam_modules[name].send(:define_method, :log) do
|
233
|
+
LogJam.get_logger(name)
|
234
|
+
end
|
235
|
+
@@logjam_modules[name].send(:define_method, :log=) do |logger|
|
236
|
+
LogJam.get_logger(name).logger = logger
|
237
|
+
end
|
238
|
+
end
|
239
|
+
@@logjam_modules[name]
|
240
|
+
end
|
241
|
+
|
242
|
+
# This method extends a specified class with a named module.
|
243
|
+
#
|
244
|
+
# ==== Parameters
|
245
|
+
# target:: The class that is to be extended.
|
246
|
+
# name:: The name of the module to extend the class with.
|
247
|
+
def self.extend_class(target, name)
|
248
|
+
target.extend(LogJam.get_module(name))
|
249
|
+
end
|
250
|
+
|
251
|
+
# This method attempts to guess the format that configuration details will be
|
252
|
+
# in given a file name. Guessing is done by looking at the file's extension.
|
253
|
+
# Files ending in '.yaml' or '.yml' are considered YAML. Files ending '.json'
|
254
|
+
# are considered JSON. The method returns nil if the path passed in has
|
255
|
+
# neither of these extensions.
|
256
|
+
#
|
257
|
+
# ==== Parameters
|
258
|
+
# path:: The path and name of the file to make the guess from.
|
259
|
+
def self.guess_format(path)
|
260
|
+
type = nil
|
261
|
+
if path.nil? && path.include?(".")
|
262
|
+
offset = path.length - path.reverse.index(".")
|
263
|
+
extension = path[offset, path.length - offset].downcase
|
264
|
+
case extension
|
265
|
+
when 'yaml', 'yml'
|
266
|
+
type = :yaml
|
267
|
+
|
268
|
+
when 'json'
|
269
|
+
type = :json
|
270
|
+
end
|
271
|
+
end
|
272
|
+
type
|
273
|
+
end
|
274
|
+
|
275
|
+
# This method creates a logger from a given definition. A definition should
|
276
|
+
# be a Hash containing the values that are used to configure the Logger with.
|
277
|
+
#
|
278
|
+
# ==== Parameters
|
279
|
+
# definition:: A Hash containing the configuration details for the logger.
|
280
|
+
def self.create_logger(definition)
|
281
|
+
# Fetch the configuration values.
|
282
|
+
name = LogJam.get_value(definition, LOGGER_NAME)
|
283
|
+
path = LogJam.get_value(definition, LOGGER_FILE)
|
284
|
+
rotation = LogJam.get_value(definition, LOGGER_ROTATION)
|
285
|
+
max_size = LogJam.get_value(definition, LOGGER_MAX_SIZE)
|
286
|
+
level = LogJam.get_value(definition, LOGGER_LEVEL)
|
287
|
+
default = LogJam.get_value(definition, LOGGER_DEFAULT)
|
288
|
+
|
289
|
+
device = nil
|
290
|
+
if ["STDOUT", "STDERR"].include?(path)
|
291
|
+
device = (path == "STDOUT" ? STDOUT : STDERR)
|
292
|
+
else
|
293
|
+
device = path
|
294
|
+
end
|
295
|
+
|
296
|
+
if rotation.kind_of?(String) && /^\s*\d+\s*$/ =~ rotation
|
297
|
+
rotation = rotation.to_i
|
298
|
+
rotation = 0 if rotation < 0
|
299
|
+
end
|
300
|
+
|
301
|
+
if !max_size.nil? && max_size.kind_of?(String)
|
302
|
+
max_size = max_size.to_i
|
303
|
+
end
|
304
|
+
max_size = 1048576 if !max_size.nil? && max_size < 1024
|
305
|
+
|
306
|
+
if !level.nil?
|
307
|
+
case level.downcase
|
308
|
+
when 'info'
|
309
|
+
level = Logger::INFO
|
310
|
+
|
311
|
+
when 'warn'
|
312
|
+
level = Logger::WARN
|
313
|
+
|
314
|
+
when 'error'
|
315
|
+
level = Logger::ERROR
|
316
|
+
|
317
|
+
when 'fatal'
|
318
|
+
level = Logger::FATAL
|
319
|
+
|
320
|
+
when 'unknown'
|
321
|
+
level = Logger::UNKNOWN
|
322
|
+
|
323
|
+
else
|
324
|
+
level = Logger::DEBUG
|
325
|
+
end
|
326
|
+
else
|
327
|
+
level = Logger::DEBUG
|
328
|
+
end
|
329
|
+
|
330
|
+
if default != true
|
331
|
+
if default.kind_of?(String)
|
332
|
+
default = ["true", "yes", "on", "1"].include?(default.downcase)
|
333
|
+
else
|
334
|
+
default = false
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
# Create the actual logger and associated module.
|
339
|
+
logger = LogJamLogger.new(device, rotation, max_size)
|
340
|
+
logger.level = level
|
341
|
+
logger.name = name
|
342
|
+
@@logjam_loggers[name] = logger
|
343
|
+
logger_module = LogJam.create_module(name)
|
344
|
+
if default
|
345
|
+
@@logjam_loggers[nil] = logger
|
346
|
+
@@logjam_modules[nil] = logger_module
|
347
|
+
end
|
348
|
+
logger
|
349
|
+
end
|
350
|
+
|
351
|
+
# This method attempts to fetch a value from a Hash. The key passed to the
|
352
|
+
# method should be a symbol and this will be checked for first. If this is
|
353
|
+
# not found then a check is made for the string equivalent. The first of
|
354
|
+
# these that is present in the Hash generates the value returned. If neither
|
355
|
+
# is present in the Hash then nil is returned.
|
356
|
+
#
|
357
|
+
# ==== Parameters
|
358
|
+
# source:: The Hash that will be checked for the value.
|
359
|
+
# key:: A symbol that will be checked as the key for the value.
|
360
|
+
def self.get_value(source, key)
|
361
|
+
if source.include?(key)
|
362
|
+
source[key]
|
363
|
+
elsif source.include?(key.to_s)
|
364
|
+
source[key.to_s]
|
365
|
+
else
|
366
|
+
nil
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
# This module level method is used to check for the existence of a
|
371
|
+
# configuration file under one or a standard set of names. This method is
|
372
|
+
# only used whenever the configure method is called and either passed nil
|
373
|
+
# or no parameter.
|
374
|
+
def self.find_default_file
|
375
|
+
file_name = nil
|
376
|
+
DEFAULT_FILE_NAMES.each do |name|
|
377
|
+
file_name = name if File.exists?(name) && File.readable?(name)
|
378
|
+
break if !file_name.nil?
|
379
|
+
end
|
380
|
+
file_name
|
381
|
+
end
|
382
|
+
end
|
@@ -0,0 +1,202 @@
|
|
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
|
data/lib/logjam.rb
ADDED
data/license.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2011 Peter Wood
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: logjam
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Black North
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2012-02-10 00:00:00 +00:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: json
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
type: :runtime
|
32
|
+
version_requirements: *id001
|
33
|
+
description: LogJam is a library to simplify the use of logging across libraries and applications.
|
34
|
+
email: ruby@blacknorth.com
|
35
|
+
executables: []
|
36
|
+
|
37
|
+
extensions: []
|
38
|
+
|
39
|
+
extra_rdoc_files: []
|
40
|
+
|
41
|
+
files:
|
42
|
+
- lib/logjam/logjam-original.rb
|
43
|
+
- lib/logjam/exceptions.rb
|
44
|
+
- lib/logjam/logjam.rb
|
45
|
+
- lib/logjam/logjam_logger.rb
|
46
|
+
- lib/logjam.rb
|
47
|
+
- license.txt
|
48
|
+
- README
|
49
|
+
has_rdoc: true
|
50
|
+
homepage:
|
51
|
+
licenses: []
|
52
|
+
|
53
|
+
post_install_message:
|
54
|
+
rdoc_options: []
|
55
|
+
|
56
|
+
require_paths:
|
57
|
+
- lib
|
58
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
segments:
|
64
|
+
- 0
|
65
|
+
version: "0"
|
66
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
segments:
|
72
|
+
- 0
|
73
|
+
version: "0"
|
74
|
+
requirements: []
|
75
|
+
|
76
|
+
rubyforge_project:
|
77
|
+
rubygems_version: 1.3.7
|
78
|
+
signing_key:
|
79
|
+
specification_version: 3
|
80
|
+
summary: A library to aggregate logging.
|
81
|
+
test_files: []
|
82
|
+
|