configurability 1.0.10 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/History.rdoc +8 -0
- data/Manifest.txt +1 -1
- data/README.rdoc +28 -12
- data/Rakefile +2 -0
- data/lib/configurability.rb +74 -32
- data/lib/configurability/config.rb +15 -1
- data/lib/configurability/logging.rb +300 -0
- data/spec/configurability/config_spec.rb +41 -29
- data/spec/configurability/deferredconfig_spec.rb +1 -1
- data/spec/configurability_spec.rb +73 -0
- data/spec/lib/helpers.rb +4 -0
- metadata +68 -34
- metadata.gz.sig +0 -0
- data/lib/configurability/logformatter.rb +0 -60
data.tar.gz.sig
CHANGED
Binary file
|
data/History.rdoc
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
== v1.1.0 [2012-04-25] Michael Granger <ged@FaerieMUD.org>
|
2
|
+
|
3
|
+
Add a 'defaults' API that allows defaults to be gathered from any
|
4
|
+
object with configurability and merged into a hash keyed by the
|
5
|
+
object's config_key. This hash can be used to generate an initial
|
6
|
+
unified config file for all configurable parts of a given system.
|
7
|
+
|
8
|
+
|
1
9
|
== v1.0.10 [2012-03-13] Michael Granger <ged@FaerieMUD.org>
|
2
10
|
|
3
11
|
- Fix log level message.
|
data/Manifest.txt
CHANGED
@@ -10,7 +10,7 @@ lib/configurability.rb
|
|
10
10
|
lib/configurability/behavior.rb
|
11
11
|
lib/configurability/config.rb
|
12
12
|
lib/configurability/deferredconfig.rb
|
13
|
-
lib/configurability/
|
13
|
+
lib/configurability/logging.rb
|
14
14
|
spec/configurability/config_spec.rb
|
15
15
|
spec/configurability/deferredconfig_spec.rb
|
16
16
|
spec/configurability_spec.rb
|
data/README.rdoc
CHANGED
@@ -1,14 +1,19 @@
|
|
1
1
|
= Configurability
|
2
2
|
|
3
|
-
|
3
|
+
home :: https://bitbucket.org/ged/configurability
|
4
|
+
code :: https://bitbucket.org/ged/configurability
|
5
|
+
docs :: http://deveiate.org/code/configurability
|
6
|
+
github :: https://github.com/ged/configurability
|
4
7
|
|
5
8
|
|
6
9
|
== Description
|
7
10
|
|
8
|
-
Configurability is a
|
9
|
-
|
10
|
-
|
11
|
-
configuration
|
11
|
+
Configurability is a unified, unintrusive, assume-nothing configuration system
|
12
|
+
for Ruby. It lets you keep the configuration for multiple objects in a single
|
13
|
+
config file, load the file when it's convenient for you, and distribute the
|
14
|
+
configuration when you're ready, sending it everywhere it needs to go with a
|
15
|
+
single action.
|
16
|
+
|
12
17
|
|
13
18
|
|
14
19
|
== Installation
|
@@ -93,6 +98,9 @@ as a Symbol:
|
|
93
98
|
|
94
99
|
=== Changing How an Object Is Configured
|
95
100
|
|
101
|
+
[:FIXME:] Explain the 'at least once' configuration call, and how to handle
|
102
|
+
being called with 'nil'.
|
103
|
+
|
96
104
|
You can also change what happens when an object is configured by implementing
|
97
105
|
a `#configure` method that takes the config section as an argument:
|
98
106
|
|
@@ -216,19 +224,27 @@ then dump it to a YAML string:
|
|
216
224
|
|
217
225
|
config.dump
|
218
226
|
# => "--- \ndatabase: \n development: \n adapter: sqlite3\n
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
227
|
+
database: db/dev.db\n pool: 5\n timeout: 5000\n testing: \n
|
228
|
+
adapter: mysql\n database: t_fixedassets\n pool: 2\n timeout:
|
229
|
+
5000\n production: \n adapter: postgres\n database:
|
230
|
+
fixedassets\n pool: 25\n timeout: 50\nldap: \n uri:
|
231
|
+
ldap://ldap.acme.com/dc=acme,dc=com\n bind_dn:
|
232
|
+
cn=web,dc=acme,dc=com\n bind_pass: Mut@ge.Mix@ge\nbranding: \n
|
233
|
+
header: \"#333\"\n title: \"#dedede\"\n anchor: \"#9fc8d4\"\n"
|
226
234
|
|
227
235
|
or write it back to the file it was loaded from:
|
228
236
|
|
229
237
|
config.write
|
230
238
|
|
231
239
|
|
240
|
+
== Configuration Defaults
|
241
|
+
|
242
|
+
Configurability also supports an API for generating a new config file with
|
243
|
+
defaults for all objects with Configurability.
|
244
|
+
|
245
|
+
[:FIXME:] Finish up the documentation
|
246
|
+
|
247
|
+
|
232
248
|
== Development
|
233
249
|
|
234
250
|
You can submit bug reports, suggestions, clone it with Mercurial, and
|
data/Rakefile
CHANGED
@@ -10,6 +10,7 @@ end
|
|
10
10
|
Hoe.plugin :mercurial
|
11
11
|
Hoe.plugin :yard
|
12
12
|
Hoe.plugin :signing
|
13
|
+
Hoe.plugin :deveiate
|
13
14
|
|
14
15
|
Hoe.plugins.delete :rubyforge
|
15
16
|
|
@@ -25,6 +26,7 @@ hoespec = Hoe.spec 'configurability' do
|
|
25
26
|
self.dependency 'simplecov', '~> 0.3', :developer
|
26
27
|
|
27
28
|
self.spec_extras[:licenses] = ["BSD"]
|
29
|
+
self.spec_extras[:rdoc_options] = ['-f', 'fivefish', '-t', 'Configurability Toolkit']
|
28
30
|
self.require_ruby_version( '>= 1.8.7' )
|
29
31
|
|
30
32
|
self.hg_sign_tags = true if self.respond_to?( :hg_sign_tags= )
|
data/lib/configurability.rb
CHANGED
@@ -11,14 +11,19 @@ require 'yaml'
|
|
11
11
|
module Configurability
|
12
12
|
|
13
13
|
# Library version constant
|
14
|
-
VERSION = '1.0
|
14
|
+
VERSION = '1.1.0'
|
15
15
|
|
16
16
|
# Version-control revision constant
|
17
|
-
REVISION = %q$Revision:
|
17
|
+
REVISION = %q$Revision: e56100a012e3 $
|
18
|
+
|
19
|
+
|
20
|
+
require 'configurability/logging'
|
21
|
+
extend Configurability::Logging
|
18
22
|
|
19
|
-
require 'configurability/logformatter'
|
20
23
|
require 'configurability/deferredconfig'
|
21
24
|
|
25
|
+
autoload :Config, 'configurability/config'
|
26
|
+
|
22
27
|
|
23
28
|
### The objects that have had Configurability added to them
|
24
29
|
@configurable_objects = []
|
@@ -31,16 +36,6 @@ module Configurability
|
|
31
36
|
### are the config section it was called with
|
32
37
|
@configured = Hash.new( false )
|
33
38
|
|
34
|
-
### Logging
|
35
|
-
@default_logger = Logger.new( $stderr )
|
36
|
-
@default_logger.level = $DEBUG ? Logger::DEBUG : Logger::WARN
|
37
|
-
|
38
|
-
@default_log_formatter = Configurability::LogFormatter.new( @default_logger )
|
39
|
-
@default_logger.formatter = @default_log_formatter
|
40
|
-
|
41
|
-
@logger = @default_logger
|
42
|
-
|
43
|
-
|
44
39
|
class << self
|
45
40
|
|
46
41
|
# the Array of objects that have had Configurability added to them
|
@@ -52,17 +47,15 @@ module Configurability
|
|
52
47
|
# the hash of configure methods => config sections which have already been installed
|
53
48
|
attr_reader :configured
|
54
49
|
|
55
|
-
|
56
|
-
# reset
|
57
|
-
attr_accessor :default_log_formatter
|
50
|
+
end
|
58
51
|
|
59
|
-
# the logger that will be used when the logging subsystem is reset
|
60
|
-
attr_accessor :default_logger
|
61
52
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
53
|
+
### Get the library version. If +include_buildnum+ is true, the version string will
|
54
|
+
### include the VCS rev ID.
|
55
|
+
def self::version_string( include_buildnum=false )
|
56
|
+
vstring = "%s %s" % [ self.name, VERSION ]
|
57
|
+
vstring << " (build %s)" % [ REVISION[/: ([[:xdigit:]]+)/, 1] || '0' ] if include_buildnum
|
58
|
+
return vstring
|
66
59
|
end
|
67
60
|
|
68
61
|
|
@@ -128,14 +121,6 @@ module Configurability
|
|
128
121
|
end
|
129
122
|
|
130
123
|
|
131
|
-
### Reset the global logger object to the default
|
132
|
-
def self::reset_logger
|
133
|
-
self.logger = self.default_logger
|
134
|
-
self.logger.level = Logger::WARN
|
135
|
-
self.logger.formatter = self.default_log_formatter
|
136
|
-
end
|
137
|
-
|
138
|
-
|
139
124
|
### Install the appropriate section of the +config+ into the given +object+.
|
140
125
|
def self::install_config( config, object )
|
141
126
|
section = object.config_key.to_sym
|
@@ -155,8 +140,7 @@ module Configurability
|
|
155
140
|
section = nil
|
156
141
|
end
|
157
142
|
else
|
158
|
-
self.log.info "
|
159
|
-
[ section, config ]
|
143
|
+
self.log.info " no %p section in %p; configuring with nil" % [ section, config ]
|
160
144
|
section = nil
|
161
145
|
end
|
162
146
|
|
@@ -174,10 +158,42 @@ module Configurability
|
|
174
158
|
end
|
175
159
|
|
176
160
|
|
161
|
+
### Gather defaults from objects with Configurability in the given +collection+
|
162
|
+
### object. Objects that wish to add a section to the defaults should implement
|
163
|
+
### a #defaults method in the same scope as #configure that returns the Hash of
|
164
|
+
### default, or set one of the constants in the default implementation of
|
165
|
+
### #defaults. The hash for each object will be merged into the +collection+
|
166
|
+
### via #merge!.
|
167
|
+
def self::gather_defaults( collection={} )
|
168
|
+
self.configurable_objects.each do |obj|
|
169
|
+
next unless obj.respond_to?( :defaults )
|
170
|
+
unless subhash = obj.defaults
|
171
|
+
Configurability.log.warn "No defaults for %p; skipping" % [ obj ]
|
172
|
+
next
|
173
|
+
end
|
174
|
+
section = obj.config_key.to_sym
|
175
|
+
|
176
|
+
collection.merge!( section => subhash )
|
177
|
+
end
|
178
|
+
|
179
|
+
return collection
|
180
|
+
end
|
181
|
+
|
182
|
+
|
183
|
+
### Gather the default configuration in a Configurability::Config object and return it.
|
184
|
+
def self::default_config
|
185
|
+
return self.gather_defaults( Configurability::Config.new )
|
186
|
+
end
|
187
|
+
|
188
|
+
|
177
189
|
#############################################################
|
178
190
|
### A P P E N D E D M E T H O D S
|
179
191
|
#############################################################
|
180
192
|
|
193
|
+
#
|
194
|
+
# :section: Configuration API
|
195
|
+
#
|
196
|
+
|
181
197
|
### Get (and optionally set) the +config_key+ (a Symbol).
|
182
198
|
def config_key( sym=nil )
|
183
199
|
@config_key = sym unless sym.nil?
|
@@ -198,5 +214,31 @@ module Configurability
|
|
198
214
|
end
|
199
215
|
|
200
216
|
|
217
|
+
#
|
218
|
+
# :section: Configuration Defaults API
|
219
|
+
#
|
220
|
+
|
221
|
+
### The default implementation of the method called by ::gather_defaults when
|
222
|
+
### gathering configuration defaults. This method expects either a
|
223
|
+
### +DEFAULT_CONFIG+ or a +CONFIG_DEFAULTS+ constant to contain the configuration
|
224
|
+
### defaults, and will just return +nil+ if neither exists.
|
225
|
+
def defaults
|
226
|
+
|
227
|
+
return nil unless respond_to?( :const_defined? )
|
228
|
+
|
229
|
+
Configurability.log.debug "Looking for defaults in %p's constants." % [ self ]
|
230
|
+
if self.const_defined?( :DEFAULT_CONFIG )
|
231
|
+
Configurability.log.debug " found DEFAULT_CONFIG"
|
232
|
+
return self.const_get( :DEFAULT_CONFIG ).dup
|
233
|
+
elsif self.const_defined?( :CONFIG_DEFAULTS )
|
234
|
+
Configurability.log.debug " found CONFIG_DEFAULTS"
|
235
|
+
return self.const_get( :CONFIG_DEFAULTS ).dup
|
236
|
+
else
|
237
|
+
Configurability.log.debug " no default constants."
|
238
|
+
return nil
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
|
201
243
|
end # module Configurability
|
202
244
|
|
@@ -140,9 +140,17 @@ class Configurability::Config
|
|
140
140
|
### Write the configuration object using the specified name and any
|
141
141
|
### additional +args+.
|
142
142
|
def write( path=@path, *args )
|
143
|
+
unless path.is_a?( String ) || path.is_a?( Pathname )
|
144
|
+
args.unshift( path )
|
145
|
+
path = @path
|
146
|
+
end
|
147
|
+
|
143
148
|
raise ArgumentError,
|
144
149
|
"No name associated with this config." unless path
|
145
|
-
|
150
|
+
|
151
|
+
self.log.info "Writing config to %s with args: %p" % [ path, args ]
|
152
|
+
path = Pathname( path )
|
153
|
+
path.open( File::WRONLY|File::CREAT|File::TRUNC, *args ) do |ofh|
|
146
154
|
ofh.print( self.dump )
|
147
155
|
end
|
148
156
|
end
|
@@ -254,6 +262,12 @@ class Configurability::Config
|
|
254
262
|
end
|
255
263
|
|
256
264
|
|
265
|
+
### Delegate logging to the module's Logger.
|
266
|
+
def log
|
267
|
+
Configurability.logger
|
268
|
+
end
|
269
|
+
|
270
|
+
|
257
271
|
#######
|
258
272
|
private
|
259
273
|
#######
|
@@ -0,0 +1,300 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
# vim: set nosta noet ts=4 sw=4:
|
3
|
+
# encoding: utf-8
|
4
|
+
|
5
|
+
require 'logger'
|
6
|
+
require 'date'
|
7
|
+
|
8
|
+
require 'configurability' unless defined?( Configurability )
|
9
|
+
|
10
|
+
|
11
|
+
# A mixin that provides a top-level logging subsystem based on Logger.
|
12
|
+
module Configurability::Logging
|
13
|
+
|
14
|
+
### Logging
|
15
|
+
# Log levels
|
16
|
+
LOG_LEVELS = {
|
17
|
+
'debug' => Logger::DEBUG,
|
18
|
+
'info' => Logger::INFO,
|
19
|
+
'warn' => Logger::WARN,
|
20
|
+
'error' => Logger::ERROR,
|
21
|
+
'fatal' => Logger::FATAL,
|
22
|
+
}.freeze
|
23
|
+
LOG_LEVEL_NAMES = LOG_LEVELS.invert.freeze
|
24
|
+
|
25
|
+
|
26
|
+
### Inclusion hook
|
27
|
+
def self::extended( mod )
|
28
|
+
super
|
29
|
+
|
30
|
+
class << mod
|
31
|
+
# the log formatter that will be used when the logging subsystem is reset
|
32
|
+
attr_accessor :default_log_formatter
|
33
|
+
|
34
|
+
# the logger that will be used when the logging subsystem is reset
|
35
|
+
attr_accessor :default_logger
|
36
|
+
|
37
|
+
# the logger that's currently in effect
|
38
|
+
attr_accessor :logger
|
39
|
+
alias_method :log, :logger
|
40
|
+
alias_method :log=, :logger=
|
41
|
+
end
|
42
|
+
|
43
|
+
mod.default_logger = mod.logger = Logger.new( $stderr )
|
44
|
+
mod.default_logger.level = case
|
45
|
+
when $DEBUG then Logger::DEBUG
|
46
|
+
when $VERBOSE then Logger::INFO
|
47
|
+
else Logger::WARN end
|
48
|
+
mod.default_log_formatter = Configurability::Logging::Formatter.new( mod.default_logger )
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
### Reset the global logger object to the default
|
53
|
+
def reset_logger
|
54
|
+
self.logger = self.default_logger
|
55
|
+
self.logger.level = $DEBUG ? Logger::DEBUG : Logger::WARN
|
56
|
+
self.logger.formatter = self.default_log_formatter
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
### Returns +true+ if the global logger has not been set to something other than
|
61
|
+
### the default one.
|
62
|
+
def using_default_logger?
|
63
|
+
return self.logger == self.default_logger
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
# A alternate formatter for Logger instances.
|
68
|
+
class Formatter < Logger::Formatter
|
69
|
+
|
70
|
+
# The format to output unless debugging is turned on
|
71
|
+
DEFAULT_FORMAT = "[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"
|
72
|
+
|
73
|
+
# The format to output if debugging is turned on
|
74
|
+
DEFAULT_DEBUG_FORMAT = "[%1$s.%2$06d %3$d/%4$s] %5$5s {%6$s} -- %7$s\n"
|
75
|
+
|
76
|
+
|
77
|
+
### Initialize the formatter with a reference to the logger so it can check for log level.
|
78
|
+
def initialize( logger, format=DEFAULT_FORMAT, debug=DEFAULT_DEBUG_FORMAT ) # :notnew:
|
79
|
+
@logger = logger
|
80
|
+
@format = format
|
81
|
+
@debug_format = debug
|
82
|
+
|
83
|
+
super()
|
84
|
+
end
|
85
|
+
|
86
|
+
######
|
87
|
+
public
|
88
|
+
######
|
89
|
+
|
90
|
+
# The Logger object associated with the formatter
|
91
|
+
attr_accessor :logger
|
92
|
+
|
93
|
+
# The logging format string
|
94
|
+
attr_accessor :format
|
95
|
+
|
96
|
+
# The logging format string that's used when outputting in debug mode
|
97
|
+
attr_accessor :debug_format
|
98
|
+
|
99
|
+
|
100
|
+
### Log using either the DEBUG_FORMAT if the associated logger is at ::DEBUG level or
|
101
|
+
### using FORMAT if it's anything less verbose.
|
102
|
+
def call( severity, time, progname, msg )
|
103
|
+
args = [
|
104
|
+
time.strftime( '%Y-%m-%d %H:%M:%S' ), # %1$s
|
105
|
+
time.usec, # %2$d
|
106
|
+
Process.pid, # %3$d
|
107
|
+
Thread.current == Thread.main ? 'main' : Thread.object_id, # %4$s
|
108
|
+
severity, # %5$s
|
109
|
+
progname, # %6$s
|
110
|
+
msg # %7$s
|
111
|
+
]
|
112
|
+
|
113
|
+
if @logger.level == Logger::DEBUG
|
114
|
+
return self.debug_format % args
|
115
|
+
else
|
116
|
+
return self.format % args
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end # class Formatter
|
120
|
+
|
121
|
+
|
122
|
+
# A ANSI-colorized formatter for Logger instances.
|
123
|
+
class ColorFormatter < Logger::Formatter
|
124
|
+
|
125
|
+
# Set some ANSI escape code constants (Shamelessly stolen from Perl's
|
126
|
+
# Term::ANSIColor by Russ Allbery <rra@stanford.edu> and Zenin <zenin@best.com>
|
127
|
+
ANSI_ATTRIBUTES = {
|
128
|
+
'clear' => 0,
|
129
|
+
'reset' => 0,
|
130
|
+
'bold' => 1,
|
131
|
+
'dark' => 2,
|
132
|
+
'underline' => 4,
|
133
|
+
'underscore' => 4,
|
134
|
+
'blink' => 5,
|
135
|
+
'reverse' => 7,
|
136
|
+
'concealed' => 8,
|
137
|
+
|
138
|
+
'black' => 30, 'on_black' => 40,
|
139
|
+
'red' => 31, 'on_red' => 41,
|
140
|
+
'green' => 32, 'on_green' => 42,
|
141
|
+
'yellow' => 33, 'on_yellow' => 43,
|
142
|
+
'blue' => 34, 'on_blue' => 44,
|
143
|
+
'magenta' => 35, 'on_magenta' => 45,
|
144
|
+
'cyan' => 36, 'on_cyan' => 46,
|
145
|
+
'white' => 37, 'on_white' => 47
|
146
|
+
}
|
147
|
+
|
148
|
+
|
149
|
+
### Create a string that contains the ANSI codes specified and return it
|
150
|
+
def self::ansi_code( *attributes )
|
151
|
+
attributes.flatten!
|
152
|
+
attributes.collect! {|at| at.to_s }
|
153
|
+
return '' unless /(?:vt10[03]|xterm(?:-color)?|linux|screen)/i =~ ENV['TERM']
|
154
|
+
attributes = ANSI_ATTRIBUTES.values_at( *attributes ).compact.join(';')
|
155
|
+
|
156
|
+
if attributes.empty?
|
157
|
+
return ''
|
158
|
+
else
|
159
|
+
return "\e[%sm" % attributes
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
|
164
|
+
### Colorize the given +string+ with the specified +attributes+ and
|
165
|
+
### return it, handling line-endings, color reset, etc.
|
166
|
+
def self::colorize( *args )
|
167
|
+
string = ''
|
168
|
+
|
169
|
+
if block_given?
|
170
|
+
string = yield
|
171
|
+
else
|
172
|
+
string = args.shift
|
173
|
+
end
|
174
|
+
|
175
|
+
ending = string[/(\s)$/] || ''
|
176
|
+
string = string.rstrip
|
177
|
+
|
178
|
+
return self.ansi_code( args.flatten ) + string + self.ansi_code( 'reset' ) + ending
|
179
|
+
end
|
180
|
+
|
181
|
+
|
182
|
+
# Color settings
|
183
|
+
LEVEL_FORMATS = {
|
184
|
+
:debug => colorize( :bold, :black ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s {%6$s} -- %7$s\n"},
|
185
|
+
:info => colorize( :normal ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"},
|
186
|
+
:warn => colorize( :bold, :yellow ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"},
|
187
|
+
:error => colorize( :red ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"},
|
188
|
+
:fatal => colorize( :bold, :red, :on_white ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"},
|
189
|
+
}
|
190
|
+
|
191
|
+
|
192
|
+
### Initialize the formatter with a reference to the logger so it can check for log level.
|
193
|
+
def initialize( logger, settings={} ) # :notnew:
|
194
|
+
settings = LEVEL_FORMATS.merge( settings )
|
195
|
+
|
196
|
+
@logger = logger
|
197
|
+
@settings = settings
|
198
|
+
|
199
|
+
super()
|
200
|
+
end
|
201
|
+
|
202
|
+
######
|
203
|
+
public
|
204
|
+
######
|
205
|
+
|
206
|
+
# The Logger object associated with the formatter
|
207
|
+
attr_accessor :logger
|
208
|
+
|
209
|
+
# The formats, by level
|
210
|
+
attr_accessor :settings
|
211
|
+
|
212
|
+
|
213
|
+
### Log using the format associated with the severity
|
214
|
+
def call( severity, time, progname, msg )
|
215
|
+
args = [
|
216
|
+
time.strftime( '%Y-%m-%d %H:%M:%S' ), # %1$s
|
217
|
+
time.usec, # %2$d
|
218
|
+
Process.pid, # %3$d
|
219
|
+
Thread.current == Thread.main ? 'main' : Thread.object_id, # %4$s
|
220
|
+
severity, # %5$s
|
221
|
+
progname, # %6$s
|
222
|
+
msg # %7$s
|
223
|
+
]
|
224
|
+
|
225
|
+
return self.settings[ severity.downcase.to_sym ] % args
|
226
|
+
end
|
227
|
+
|
228
|
+
end # class Formatter
|
229
|
+
|
230
|
+
|
231
|
+
# An alternate formatter for Logger instances that outputs +div+ HTML
|
232
|
+
# fragments.
|
233
|
+
class HtmlFormatter < Logger::Formatter
|
234
|
+
|
235
|
+
# The default HTML fragment that'll be used as the template for each log message.
|
236
|
+
HTML_LOG_FORMAT = %q{
|
237
|
+
<div class="log-message %5$s">
|
238
|
+
<span class="log-time">%1$s.%2$06d</span>
|
239
|
+
[
|
240
|
+
<span class="log-pid">%3$d</span>
|
241
|
+
/
|
242
|
+
<span class="log-tid">%4$s</span>
|
243
|
+
]
|
244
|
+
<span class="log-level">%5$s</span>
|
245
|
+
:
|
246
|
+
<span class="log-name">%6$s</span>
|
247
|
+
<span class="log-message-text">%7$s</span>
|
248
|
+
</div>
|
249
|
+
}
|
250
|
+
|
251
|
+
### Override the logging formats with ones that generate HTML fragments
|
252
|
+
def initialize( logger, format=HTML_LOG_FORMAT ) # :notnew:
|
253
|
+
@logger = logger
|
254
|
+
@format = format
|
255
|
+
super()
|
256
|
+
end
|
257
|
+
|
258
|
+
|
259
|
+
######
|
260
|
+
public
|
261
|
+
######
|
262
|
+
|
263
|
+
# The HTML fragment that will be used as a format() string for the log
|
264
|
+
attr_accessor :format
|
265
|
+
|
266
|
+
|
267
|
+
### Return a log message composed out of the arguments formatted using the
|
268
|
+
### formatter's format string
|
269
|
+
def call( severity, time, progname, msg )
|
270
|
+
args = [
|
271
|
+
time.strftime( '%Y-%m-%d %H:%M:%S' ), # %1$s
|
272
|
+
time.usec, # %2$d
|
273
|
+
Process.pid, # %3$d
|
274
|
+
Thread.current == Thread.main ? 'main' : Thread.object_id, # %4$s
|
275
|
+
severity.downcase, # %5$s
|
276
|
+
progname, # %6$s
|
277
|
+
escape_html( msg ).gsub(/\n/, '<br />') # %7$s
|
278
|
+
]
|
279
|
+
|
280
|
+
return self.format % args
|
281
|
+
end
|
282
|
+
|
283
|
+
|
284
|
+
#######
|
285
|
+
private
|
286
|
+
#######
|
287
|
+
|
288
|
+
### Escape any HTML special characters in +string+.
|
289
|
+
def escape_html( string )
|
290
|
+
return string.
|
291
|
+
gsub( '&', '&' ).
|
292
|
+
gsub( '<', '<' ).
|
293
|
+
gsub( '>', '>' )
|
294
|
+
end
|
295
|
+
|
296
|
+
end # class HtmlFormatter
|
297
|
+
|
298
|
+
|
299
|
+
end # module Configurability
|
300
|
+
|
@@ -10,7 +10,6 @@ BEGIN {
|
|
10
10
|
$LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir )
|
11
11
|
}
|
12
12
|
|
13
|
-
require 'tempfile'
|
14
13
|
require 'logger'
|
15
14
|
require 'fileutils'
|
16
15
|
require 'rspec'
|
@@ -48,6 +47,11 @@ describe Configurability::Config do
|
|
48
47
|
setup_logging( :fatal )
|
49
48
|
end
|
50
49
|
|
50
|
+
after( :each ) do
|
51
|
+
Configurability.configurable_objects.clear
|
52
|
+
Configurability.reset
|
53
|
+
end
|
54
|
+
|
51
55
|
after( :all ) do
|
52
56
|
reset_logging()
|
53
57
|
end
|
@@ -135,7 +139,7 @@ describe Configurability::Config do
|
|
135
139
|
|
136
140
|
context "created with in-memory YAML source" do
|
137
141
|
|
138
|
-
before(:each) do
|
142
|
+
before( :each ) do
|
139
143
|
@config = Configurability::Config.new( TEST_CONFIG )
|
140
144
|
end
|
141
145
|
|
@@ -206,7 +210,7 @@ describe Configurability::Config do
|
|
206
210
|
|
207
211
|
# saving if changed since loaded
|
208
212
|
context " whose internal values have been changed since loaded" do
|
209
|
-
before(:each) do
|
213
|
+
before( :each ) do
|
210
214
|
@config = Configurability::Config.new( TEST_CONFIG )
|
211
215
|
@config.section.subsection.anothersection = 11451
|
212
216
|
end
|
@@ -226,42 +230,50 @@ describe Configurability::Config do
|
|
226
230
|
|
227
231
|
# loading from a file
|
228
232
|
context " loaded from a file" do
|
229
|
-
before(:all) do
|
230
|
-
|
231
|
-
@tmpfile
|
232
|
-
@tmpfile.
|
233
|
+
before( :all ) do
|
234
|
+
filename = Dir::Tmpname.make_tmpname( './test', '.conf' )
|
235
|
+
@tmpfile = Pathname( filename )
|
236
|
+
@tmpfile.open( 'w', 0644 ) {|io| io.print(TEST_CONFIG) }
|
233
237
|
end
|
234
238
|
|
235
|
-
after(:all) do
|
236
|
-
@tmpfile.
|
239
|
+
after( :all ) do
|
240
|
+
@tmpfile.unlink
|
237
241
|
end
|
238
242
|
|
239
|
-
|
240
|
-
|
241
|
-
@config = Configurability::Config.load( @tmpfile.path )
|
243
|
+
before( :each ) do
|
244
|
+
@config = Configurability::Config.load( @tmpfile.to_s )
|
242
245
|
end
|
243
246
|
|
244
247
|
|
245
248
|
### Specifications
|
246
249
|
it "remembers which file it was loaded from" do
|
247
|
-
@config.path.should ==
|
250
|
+
@config.path.should == @tmpfile.expand_path
|
248
251
|
end
|
249
252
|
|
250
253
|
it "writes itself back to the same file by default" do
|
251
254
|
@config.port = 114411
|
252
255
|
@config.write
|
253
|
-
otherconfig = Configurability::Config.load( @tmpfile.
|
256
|
+
otherconfig = Configurability::Config.load( @tmpfile.to_s )
|
254
257
|
|
255
258
|
otherconfig.port.should == 114411
|
256
259
|
end
|
257
260
|
|
261
|
+
it "can be written to a different file" do
|
262
|
+
path = Dir::Tmpname.make_tmpname( './another-', '.config' )
|
263
|
+
|
264
|
+
@config.write( path )
|
265
|
+
File.read( path ).should =~ /section:\n subsection/
|
266
|
+
|
267
|
+
File.unlink( path )
|
268
|
+
end
|
269
|
+
|
258
270
|
it "includes the name of the file in its inspect output" do
|
259
|
-
@config.inspect.should include( File.basename(@tmpfile.
|
271
|
+
@config.inspect.should include( File.basename(@tmpfile.to_s) )
|
260
272
|
end
|
261
273
|
|
262
274
|
it "yields itself if a block is given at load-time" do
|
263
275
|
yielded_self = nil
|
264
|
-
config = Configurability::Config.load( @tmpfile.
|
276
|
+
config = Configurability::Config.load( @tmpfile.to_s ) do
|
265
277
|
yielded_self = self
|
266
278
|
end
|
267
279
|
yielded_self.should equal( config )
|
@@ -270,7 +282,7 @@ describe Configurability::Config do
|
|
270
282
|
it "passes itself as the block argument if a block of arity 1 is given at load-time" do
|
271
283
|
arg_self = nil
|
272
284
|
yielded_self = nil
|
273
|
-
config = Configurability::Config.load( @tmpfile.
|
285
|
+
config = Configurability::Config.load( @tmpfile.to_s ) do |arg|
|
274
286
|
yielded_self = self
|
275
287
|
arg_self = arg
|
276
288
|
end
|
@@ -288,23 +300,23 @@ describe Configurability::Config do
|
|
288
300
|
|
289
301
|
# reload if file changes
|
290
302
|
context " whose file changes after loading" do
|
291
|
-
before(:all) do
|
292
|
-
|
293
|
-
@tmpfile
|
294
|
-
@tmpfile.
|
303
|
+
before( :all ) do
|
304
|
+
filename = Dir::Tmpname.make_tmpname( './test', '.conf' )
|
305
|
+
@tmpfile = Pathname( filename )
|
306
|
+
@tmpfile.open( 'w', 0644 ) {|io| io.print(TEST_CONFIG) }
|
295
307
|
end
|
296
308
|
|
297
|
-
after(:all) do
|
298
|
-
@tmpfile.
|
309
|
+
after( :all ) do
|
310
|
+
@tmpfile.unlink
|
299
311
|
end
|
300
312
|
|
301
313
|
|
302
|
-
before(:each) do
|
314
|
+
before( :each ) do
|
303
315
|
old_date = Time.now - 3600
|
304
|
-
File.utime( old_date, old_date, @tmpfile.
|
305
|
-
@config = Configurability::Config.load( @tmpfile.
|
316
|
+
File.utime( old_date, old_date, @tmpfile.to_s )
|
317
|
+
@config = Configurability::Config.load( @tmpfile.to_s )
|
306
318
|
now = Time.now + 10
|
307
|
-
File.utime( now, now, @tmpfile.
|
319
|
+
File.utime( now, now, @tmpfile.to_s )
|
308
320
|
end
|
309
321
|
|
310
322
|
|
@@ -324,7 +336,7 @@ describe Configurability::Config do
|
|
324
336
|
end
|
325
337
|
|
326
338
|
it "reapplies its defaults when reloading" do
|
327
|
-
config = Configurability::Config.load( @tmpfile.
|
339
|
+
config = Configurability::Config.load( @tmpfile.to_s, :defaultskey => 8 )
|
328
340
|
config.reload
|
329
341
|
config.defaultskey.should == 8
|
330
342
|
end
|
@@ -333,7 +345,7 @@ describe Configurability::Config do
|
|
333
345
|
|
334
346
|
# merging
|
335
347
|
context " created by merging two other configs" do
|
336
|
-
before(:each) do
|
348
|
+
before( :each ) do
|
337
349
|
@config1 = Configurability::Config.new
|
338
350
|
@config2 = Configurability::Config.new( TEST_CONFIG )
|
339
351
|
@merged = @config1.merge( @config2 )
|
@@ -36,7 +36,7 @@ describe Configurability::DeferredConfig do
|
|
36
36
|
end
|
37
37
|
|
38
38
|
it "calls Configurability.install_config with itself when a 'configure' method is defined" do
|
39
|
-
config =
|
39
|
+
config = { :testing => :testing_config }
|
40
40
|
Configurability.configure_objects( config )
|
41
41
|
|
42
42
|
a_class = Class.new do
|
@@ -287,6 +287,79 @@ describe Configurability do
|
|
287
287
|
|
288
288
|
end
|
289
289
|
|
290
|
+
|
291
|
+
describe "defaults hash" do
|
292
|
+
|
293
|
+
it "can generate a Hash of defaults for all objects with Configurability" do
|
294
|
+
Configurability.gather_defaults.should be_a( Hash )
|
295
|
+
end
|
296
|
+
|
297
|
+
it "fetches defaults from a CONFIG_DEFAULTS constant if the object defines one" do
|
298
|
+
klass = Class.new do
|
299
|
+
extend Configurability
|
300
|
+
config_key :testconfig
|
301
|
+
self::CONFIG_DEFAULTS = { :one => 1, :types => {:one => true} }
|
302
|
+
Configurability.log.debug "Defaults: %p" % [ self.defaults ]
|
303
|
+
end
|
304
|
+
|
305
|
+
Configurability.gather_defaults.should include( :testconfig )
|
306
|
+
Configurability.gather_defaults[:testconfig].should == klass.const_get( :CONFIG_DEFAULTS )
|
307
|
+
Configurability.gather_defaults[:testconfig].should_not be( klass.const_get(:CONFIG_DEFAULTS) )
|
308
|
+
end
|
309
|
+
|
310
|
+
it "fetches defaults from a DEFAULT_CONFIG constant if the object defines one" do
|
311
|
+
klass = Class.new do
|
312
|
+
extend Configurability
|
313
|
+
config_key :testconfig
|
314
|
+
self::DEFAULT_CONFIG = { :two => 2, :types => {:two => true} }
|
315
|
+
end
|
316
|
+
|
317
|
+
Configurability.gather_defaults.should include( :testconfig )
|
318
|
+
Configurability.gather_defaults[:testconfig].should == klass.const_get( :DEFAULT_CONFIG )
|
319
|
+
Configurability.gather_defaults[:testconfig].should_not be( klass.const_get(:DEFAULT_CONFIG) )
|
320
|
+
end
|
321
|
+
|
322
|
+
it "fetches defaults from a #defaults method if the object implements one" do
|
323
|
+
klass = Class.new do
|
324
|
+
extend Configurability
|
325
|
+
config_key :otherconfig
|
326
|
+
def self::defaults; { :other => true }; end
|
327
|
+
end
|
328
|
+
|
329
|
+
Configurability.gather_defaults.should include( :otherconfig )
|
330
|
+
Configurability.gather_defaults[:otherconfig].should == klass.defaults
|
331
|
+
Configurability.gather_defaults[:otherconfig].should_not be( klass.defaults )
|
332
|
+
end
|
333
|
+
|
334
|
+
it "can return a Configurability::Config object with defaults, too" do
|
335
|
+
klass1 = Class.new do
|
336
|
+
extend Configurability
|
337
|
+
config_key :testconfig
|
338
|
+
self::CONFIG_DEFAULTS = { :one => 1, :types => {:one => true} }
|
339
|
+
end
|
340
|
+
klass2 = Class.new do
|
341
|
+
extend Configurability
|
342
|
+
config_key :testconfig
|
343
|
+
self::DEFAULT_CONFIG = { :two => 2, :types => {:two => true} }
|
344
|
+
end
|
345
|
+
klass3 = Class.new do
|
346
|
+
extend Configurability
|
347
|
+
config_key :otherconfig
|
348
|
+
def self::defaults; { :other => true }; end
|
349
|
+
end
|
350
|
+
|
351
|
+
config = Configurability.default_config
|
352
|
+
|
353
|
+
config.should be_a( Configurability::Config )
|
354
|
+
config.testconfig.one.should == 1
|
355
|
+
config.testconfig.two.should == 2
|
356
|
+
config.testconfig.types.one.should be_true()
|
357
|
+
config.testconfig.types.two.should be_true()
|
358
|
+
config.otherconfig.other.should be_true()
|
359
|
+
end
|
360
|
+
|
361
|
+
end
|
362
|
+
|
290
363
|
end
|
291
364
|
|
292
365
|
# vim: set nosta noet ts=4 sw=4:
|
data/spec/lib/helpers.rb
CHANGED
@@ -142,6 +142,10 @@ end
|
|
142
142
|
RSpec.configure do |config|
|
143
143
|
config.mock_with( :rspec )
|
144
144
|
config.include( Configurability::SpecHelpers )
|
145
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
146
|
+
|
147
|
+
config.filter_run_excluding :only_ruby_19 if RUBY_VERSION < '1.9.2'
|
148
|
+
|
145
149
|
end
|
146
150
|
|
147
151
|
# vim: set nosta noet ts=4 sw=4:
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: configurability
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -36,22 +36,27 @@ cert_chain:
|
|
36
36
|
YUhDS0xaZFNLai9SSHVUT3QrZ2JsUmV4OEZBaDhOZUEKY21saFhlNDZwWk5K
|
37
37
|
Z1dLYnhaYWg4NWpJang5NWhSOHZPSStOQU01aUg5a09xSzEzRHJ4YWNUS1Bo
|
38
38
|
cWo1UGp3RgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
|
39
|
-
date: 2012-
|
39
|
+
date: 2012-04-26 00:00:00.000000000 Z
|
40
40
|
dependencies:
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: hoe-mercurial
|
43
|
-
requirement:
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
44
|
none: false
|
45
45
|
requirements:
|
46
46
|
- - ~>
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version: 1.
|
48
|
+
version: 1.4.0
|
49
49
|
type: :development
|
50
50
|
prerelease: false
|
51
|
-
version_requirements:
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ~>
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 1.4.0
|
52
57
|
- !ruby/object:Gem::Dependency
|
53
58
|
name: hoe-highline
|
54
|
-
requirement:
|
59
|
+
requirement: !ruby/object:Gem::Requirement
|
55
60
|
none: false
|
56
61
|
requirements:
|
57
62
|
- - ~>
|
@@ -59,10 +64,31 @@ dependencies:
|
|
59
64
|
version: 0.0.1
|
60
65
|
type: :development
|
61
66
|
prerelease: false
|
62
|
-
version_requirements:
|
67
|
+
version_requirements: !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
69
|
+
requirements:
|
70
|
+
- - ~>
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 0.0.1
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: rdoc
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
77
|
+
requirements:
|
78
|
+
- - ~>
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '3.10'
|
81
|
+
type: :development
|
82
|
+
prerelease: false
|
83
|
+
version_requirements: !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ~>
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '3.10'
|
63
89
|
- !ruby/object:Gem::Dependency
|
64
90
|
name: rspec
|
65
|
-
requirement:
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
66
92
|
none: false
|
67
93
|
requirements:
|
68
94
|
- - ~>
|
@@ -70,10 +96,15 @@ dependencies:
|
|
70
96
|
version: '2.4'
|
71
97
|
type: :development
|
72
98
|
prerelease: false
|
73
|
-
version_requirements:
|
99
|
+
version_requirements: !ruby/object:Gem::Requirement
|
100
|
+
none: false
|
101
|
+
requirements:
|
102
|
+
- - ~>
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '2.4'
|
74
105
|
- !ruby/object:Gem::Dependency
|
75
106
|
name: simplecov
|
76
|
-
requirement:
|
107
|
+
requirement: !ruby/object:Gem::Requirement
|
77
108
|
none: false
|
78
109
|
requirements:
|
79
110
|
- - ~>
|
@@ -81,44 +112,45 @@ dependencies:
|
|
81
112
|
version: '0.3'
|
82
113
|
type: :development
|
83
114
|
prerelease: false
|
84
|
-
version_requirements:
|
85
|
-
- !ruby/object:Gem::Dependency
|
86
|
-
name: rdoc
|
87
|
-
requirement: &70327439149040 !ruby/object:Gem::Requirement
|
115
|
+
version_requirements: !ruby/object:Gem::Requirement
|
88
116
|
none: false
|
89
117
|
requirements:
|
90
118
|
- - ~>
|
91
119
|
- !ruby/object:Gem::Version
|
92
|
-
version: '3
|
93
|
-
type: :development
|
94
|
-
prerelease: false
|
95
|
-
version_requirements: *70327439149040
|
120
|
+
version: '0.3'
|
96
121
|
- !ruby/object:Gem::Dependency
|
97
122
|
name: hoe
|
98
|
-
requirement:
|
123
|
+
requirement: !ruby/object:Gem::Requirement
|
99
124
|
none: false
|
100
125
|
requirements:
|
101
126
|
- - ~>
|
102
127
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
128
|
+
version: '3.0'
|
104
129
|
type: :development
|
105
130
|
prerelease: false
|
106
|
-
version_requirements:
|
107
|
-
|
108
|
-
|
131
|
+
version_requirements: !ruby/object:Gem::Requirement
|
132
|
+
none: false
|
133
|
+
requirements:
|
134
|
+
- - ~>
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '3.0'
|
137
|
+
description: ! 'Configurability is a unified, unintrusive, assume-nothing configuration
|
138
|
+
system
|
139
|
+
|
140
|
+
for Ruby. It lets you keep the configuration for multiple objects in a single
|
109
141
|
|
110
|
-
|
142
|
+
config file, load the file when it''s convenient for you, and distribute the
|
111
143
|
|
112
|
-
configuration
|
144
|
+
configuration when you''re ready, sending it everywhere it needs to go with a
|
113
145
|
|
114
|
-
|
146
|
+
single action.'
|
115
147
|
email:
|
116
148
|
- ged@FaerieMUD.org
|
117
149
|
executables: []
|
118
150
|
extensions: []
|
119
151
|
extra_rdoc_files:
|
120
|
-
- Manifest.txt
|
121
152
|
- History.rdoc
|
153
|
+
- Manifest.txt
|
122
154
|
- README.rdoc
|
123
155
|
files:
|
124
156
|
- ChangeLog
|
@@ -133,19 +165,21 @@ files:
|
|
133
165
|
- lib/configurability/behavior.rb
|
134
166
|
- lib/configurability/config.rb
|
135
167
|
- lib/configurability/deferredconfig.rb
|
136
|
-
- lib/configurability/
|
168
|
+
- lib/configurability/logging.rb
|
137
169
|
- spec/configurability/config_spec.rb
|
138
170
|
- spec/configurability/deferredconfig_spec.rb
|
139
171
|
- spec/configurability_spec.rb
|
140
172
|
- spec/lib/helpers.rb
|
141
173
|
- .gemtest
|
142
|
-
homepage:
|
174
|
+
homepage: https://bitbucket.org/ged/configurability
|
143
175
|
licenses:
|
144
176
|
- BSD
|
145
177
|
post_install_message:
|
146
178
|
rdoc_options:
|
147
|
-
-
|
148
|
-
-
|
179
|
+
- -f
|
180
|
+
- fivefish
|
181
|
+
- -t
|
182
|
+
- Configurability Toolkit
|
149
183
|
require_paths:
|
150
184
|
- lib
|
151
185
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -162,9 +196,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
162
196
|
version: '0'
|
163
197
|
requirements: []
|
164
198
|
rubyforge_project: configurability
|
165
|
-
rubygems_version: 1.8.
|
199
|
+
rubygems_version: 1.8.21
|
166
200
|
signing_key:
|
167
201
|
specification_version: 3
|
168
|
-
summary: Configurability is a
|
169
|
-
|
202
|
+
summary: Configurability is a unified, unintrusive, assume-nothing configuration system
|
203
|
+
for Ruby
|
170
204
|
test_files: []
|
metadata.gz.sig
CHANGED
Binary file
|
@@ -1,60 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'logger'
|
4
|
-
|
5
|
-
require 'configurability'
|
6
|
-
|
7
|
-
# A custom log-formatter class for
|
8
|
-
class Configurability::LogFormatter < Logger::Formatter
|
9
|
-
|
10
|
-
# The format to output unless debugging is turned on
|
11
|
-
DEFAULT_FORMAT = "[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"
|
12
|
-
|
13
|
-
# The format to output if debugging is turned on
|
14
|
-
DEFAULT_DEBUG_FORMAT = "[%1$s.%2$06d %3$d/%4$s] %5$5s {%6$s} -- %7$s\n"
|
15
|
-
|
16
|
-
|
17
|
-
### Initialize the formatter with a reference to the logger so it can check for log level.
|
18
|
-
def initialize( logger, format=DEFAULT_FORMAT, debug=DEFAULT_DEBUG_FORMAT ) # :notnew:
|
19
|
-
@logger = logger
|
20
|
-
@format = format
|
21
|
-
@debug_format = debug
|
22
|
-
|
23
|
-
super()
|
24
|
-
end
|
25
|
-
|
26
|
-
######
|
27
|
-
public
|
28
|
-
######
|
29
|
-
|
30
|
-
# The Logger object associated with the formatter
|
31
|
-
attr_accessor :logger
|
32
|
-
|
33
|
-
# The logging format string
|
34
|
-
attr_accessor :format
|
35
|
-
|
36
|
-
# The logging format string that's used when outputting in debug mode
|
37
|
-
attr_accessor :debug_format
|
38
|
-
|
39
|
-
|
40
|
-
### Log using either the DEBUG_FORMAT if the associated logger is at ::DEBUG level or
|
41
|
-
### using FORMAT if it's anything less verbose.
|
42
|
-
def call( severity, time, progname, msg )
|
43
|
-
args = [
|
44
|
-
time.strftime( '%Y-%m-%d %H:%M:%S' ), # %1$s
|
45
|
-
time.usec, # %2$d
|
46
|
-
Process.pid, # %3$d
|
47
|
-
Thread.current == Thread.main ? 'main' : Thread.object_id, # %4$s
|
48
|
-
severity, # %5$s
|
49
|
-
progname, # %6$s
|
50
|
-
msg # %7$s
|
51
|
-
]
|
52
|
-
|
53
|
-
if @logger.level == Logger::DEBUG
|
54
|
-
return self.debug_format % args
|
55
|
-
else
|
56
|
-
return self.format % args
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
end # class Configurability::LogFormatter
|