configurability 1.0.10 → 1.1.0
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.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
|