logjam 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|