d13n 0.5.2
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.
- checksums.yaml +7 -0
- data/.gitignore +35 -0
- data/.rspec +6 -0
- data/.rubocop.yml +5 -0
- data/.ruby-version +1 -0
- data/Gemfile +22 -0
- data/Gemfile.lock +151 -0
- data/Guardfile +63 -0
- data/README.md +200 -0
- data/bin/d13n +11 -0
- data/d13n.gemspec +34 -0
- data/lib/d13n/application/class_methods.rb +56 -0
- data/lib/d13n/application.rb +3 -0
- data/lib/d13n/cli/command.rb +76 -0
- data/lib/d13n/cli/commands/scaffold.rb +345 -0
- data/lib/d13n/configuration/default_source.rb +200 -0
- data/lib/d13n/configuration/dotted_hash.rb +39 -0
- data/lib/d13n/configuration/environment_source.rb +89 -0
- data/lib/d13n/configuration/manager.rb +239 -0
- data/lib/d13n/configuration/manual_source.rb +4 -0
- data/lib/d13n/configuration/mask_defaults.rb +6 -0
- data/lib/d13n/configuration/server_source.rb +83 -0
- data/lib/d13n/configuration/yaml_source.rb +66 -0
- data/lib/d13n/configuration.rb +6 -0
- data/lib/d13n/ext/string.rb +17 -0
- data/lib/d13n/logger/log_once.rb +24 -0
- data/lib/d13n/logger/memory_logger.rb +48 -0
- data/lib/d13n/logger/null_logger.rb +16 -0
- data/lib/d13n/logger.rb +213 -0
- data/lib/d13n/metric/conductor.rb +123 -0
- data/lib/d13n/metric/helper.rb +62 -0
- data/lib/d13n/metric/http_clients/http_helper.rb +15 -0
- data/lib/d13n/metric/http_clients/net_http_wrappers.rb +54 -0
- data/lib/d13n/metric/http_clients.rb +4 -0
- data/lib/d13n/metric/instrumentation/app_exception.rb +70 -0
- data/lib/d13n/metric/instrumentation/controller_instrumentation.rb +91 -0
- data/lib/d13n/metric/instrumentation/em-websocket.rb +71 -0
- data/lib/d13n/metric/instrumentation/exception.rb +65 -0
- data/lib/d13n/metric/instrumentation/middleware_tracing.rb +82 -0
- data/lib/d13n/metric/instrumentation/net.rb +36 -0
- data/lib/d13n/metric/instrumentation/sinatra/stream_namer.rb +35 -0
- data/lib/d13n/metric/instrumentation/sinatra.rb +165 -0
- data/lib/d13n/metric/instrumentation/websocket_instrumentation.rb +42 -0
- data/lib/d13n/metric/instrumentation.rb +41 -0
- data/lib/d13n/metric/manager.rb +106 -0
- data/lib/d13n/metric/metrics/app_database_metric.rb +4 -0
- data/lib/d13n/metric/metrics/app_http_metric.rb +229 -0
- data/lib/d13n/metric/metrics/app_state_metric.rb +103 -0
- data/lib/d13n/metric/metrics/base.rb +14 -0
- data/lib/d13n/metric/metrics/biz_state_metric.rb +4 -0
- data/lib/d13n/metric/metrics.rb +6 -0
- data/lib/d13n/metric/stream/span_tracer_helpers.rb +72 -0
- data/lib/d13n/metric/stream/stream_tracer_helpers.rb +141 -0
- data/lib/d13n/metric/stream/traced_span_stack.rb +73 -0
- data/lib/d13n/metric/stream.rb +322 -0
- data/lib/d13n/metric/stream_state.rb +68 -0
- data/lib/d13n/metric.rb +11 -0
- data/lib/d13n/rack/d13n_middleware.rb +21 -0
- data/lib/d13n/rack/metric_middleware.rb +18 -0
- data/lib/d13n/service/background_job/sinatra.rb +24 -0
- data/lib/d13n/service/background_job.rb +1 -0
- data/lib/d13n/service/start.rb +75 -0
- data/lib/d13n/service.rb +91 -0
- data/lib/d13n/support/request_id.rb +29 -0
- data/lib/d13n/version.rb +14 -0
- data/lib/d13n.rb +92 -0
- data/templates/.rspec.template +6 -0
- data/templates/.ruby-version.template +1 -0
- data/templates/Gemfile.template +16 -0
- data/templates/Guardfile.template +64 -0
- data/templates/Jenkinsfile.template +85 -0
- data/templates/Makefile.template +178 -0
- data/templates/README.md.template +1 -0
- data/templates/Rakefile.template +6 -0
- data/templates/application.yml.template +14 -0
- data/templates/config.ru.template +4 -0
- data/templates/docker/.dockerignore.template +5 -0
- data/templates/docker/Dockerfile.application.development +15 -0
- data/templates/docker/Dockerfile.cache.development +18 -0
- data/templates/docker/Dockerfile.development +27 -0
- data/templates/docker/Dockerfile.release +16 -0
- data/templates/docker/docker-compose.yml.development +53 -0
- data/templates/docker/docker-compose.yml.release +37 -0
- data/templates/lib/api/service.rb.template +10 -0
- data/templates/lib/api/support.rb.template +38 -0
- data/templates/lib/api/version.rb.template +3 -0
- data/templates/lib/api.rb.template +4 -0
- data/templates/lib/application.rb.template +49 -0
- data/templates/lib/service.rb.template +4 -0
- data/templates/lib/version.rb.template +3 -0
- data/templates/scripts/test.sh.template +7 -0
- data/templates/spec/spec_helper.rb.template +56 -0
- data/templates/tasks/migration.rake.template +11 -0
- data/templates/tasks/spec.rake.template +21 -0
- metadata +199 -0
@@ -0,0 +1,239 @@
|
|
1
|
+
|
2
|
+
module D13n::Configuration
|
3
|
+
class Manager
|
4
|
+
def [](key)
|
5
|
+
@cache[key]
|
6
|
+
end
|
7
|
+
|
8
|
+
def has_key?(key)
|
9
|
+
@cache.has_key?(key)
|
10
|
+
end
|
11
|
+
|
12
|
+
def keys
|
13
|
+
@cache.keys
|
14
|
+
end
|
15
|
+
|
16
|
+
def key(value)
|
17
|
+
@cache.key(value)
|
18
|
+
end
|
19
|
+
|
20
|
+
def alias_key_for(value)
|
21
|
+
alias_for(key(value))
|
22
|
+
end
|
23
|
+
|
24
|
+
def alias_for(key)
|
25
|
+
@alias_cache[key]
|
26
|
+
end
|
27
|
+
|
28
|
+
def initialize
|
29
|
+
reset_to_defaults
|
30
|
+
@callbacks = Hash.new { |hash, key| hash[key] = [] }
|
31
|
+
end
|
32
|
+
|
33
|
+
def remove_config_type(sym)
|
34
|
+
source = case sym
|
35
|
+
when :environment then @environment_source
|
36
|
+
when :server then @server_source
|
37
|
+
when :manual then @manual_source
|
38
|
+
when :yaml then @yaml_source
|
39
|
+
when :default then @default_source
|
40
|
+
end
|
41
|
+
|
42
|
+
remove_config(source)
|
43
|
+
end
|
44
|
+
|
45
|
+
def remove_config(source)
|
46
|
+
case source
|
47
|
+
when EnvironmentSource then @environment_source = nil
|
48
|
+
when ServerSource then @server_source = nil
|
49
|
+
when ManualSource then @manual_source = nil
|
50
|
+
when YamlSource then @yaml_source = nil
|
51
|
+
when DefaultSource then @default_source = nil
|
52
|
+
end
|
53
|
+
|
54
|
+
reset_cache
|
55
|
+
reset_alias
|
56
|
+
invoke_callbacks(:remove, source)
|
57
|
+
log_config(:remove, source)
|
58
|
+
end
|
59
|
+
|
60
|
+
def replace_or_add_config(source)
|
61
|
+
source.freeze
|
62
|
+
|
63
|
+
invoke_callbacks(:add, source)
|
64
|
+
case source
|
65
|
+
when EnvironmentSource then @environment_source = source
|
66
|
+
when ServerSource then @server_source = source
|
67
|
+
when ManualSource then @manual_source = source
|
68
|
+
when YamlSource then @yaml_source = source
|
69
|
+
when DefaultSource then @default_source = source
|
70
|
+
else
|
71
|
+
D13n.logger.warn("Invalid config format; config will be ignored: #{source}")
|
72
|
+
end
|
73
|
+
|
74
|
+
reset_cache
|
75
|
+
reset_alias
|
76
|
+
log_config(:add, source)
|
77
|
+
end
|
78
|
+
|
79
|
+
def source(key)
|
80
|
+
config_stack.each do |config|
|
81
|
+
if config.respond_to?(key.to_sym) || config.has_key?(key.to_sym)
|
82
|
+
return config
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def fetch(key)
|
88
|
+
config_stack.each do |config|
|
89
|
+
next unless config
|
90
|
+
accessor = key.to_sym
|
91
|
+
|
92
|
+
if config.has_key?(accessor)
|
93
|
+
evaluated = evaluate_procs(config[accessor])
|
94
|
+
begin
|
95
|
+
return apply_transformations(accessor, evaluated)
|
96
|
+
rescue
|
97
|
+
next
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
nil
|
102
|
+
end
|
103
|
+
|
104
|
+
def apply_transformations(key, value)
|
105
|
+
if transform = transform_from_default(key)
|
106
|
+
begin
|
107
|
+
transform.call(value)
|
108
|
+
rescue => e
|
109
|
+
D13n.logger.error("Error applying transformation for #{key}, pre-transform value was: #{value}.", e)
|
110
|
+
raise e
|
111
|
+
end
|
112
|
+
else
|
113
|
+
value
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def transform_from_default(key)
|
118
|
+
D13n::Configuration::DefaultSource.transform_for(key)
|
119
|
+
end
|
120
|
+
|
121
|
+
def evaluate_procs(value)
|
122
|
+
if value.respond_to?(:call)
|
123
|
+
instance_eval(&value)
|
124
|
+
else
|
125
|
+
value
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# Generally only useful during initial construction and tests
|
130
|
+
def reset_to_defaults
|
131
|
+
@environment_source = EnvironmentSource.new
|
132
|
+
@server_source = nil
|
133
|
+
@manual_source = nil
|
134
|
+
@yaml_source = nil
|
135
|
+
@default_source = DefaultSource.new
|
136
|
+
reset_cache
|
137
|
+
reset_alias
|
138
|
+
end
|
139
|
+
|
140
|
+
def reset_cache
|
141
|
+
@cache = Hash.new {|hash,key| hash[key] = self.fetch(key) }
|
142
|
+
end
|
143
|
+
|
144
|
+
def reset_alias
|
145
|
+
@alias_cache = @default_source.default_alias
|
146
|
+
end
|
147
|
+
|
148
|
+
def log_config(direction, source)
|
149
|
+
D13n.logger.debug do
|
150
|
+
"Updating config (#{direction}) from #{source.class}. Results: #{flattened.inspect}"
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def register_callback(key, &proc)
|
155
|
+
@callbacks[key] << proc
|
156
|
+
proc.call(@cache[key])
|
157
|
+
end
|
158
|
+
|
159
|
+
def invoke_callbacks(direction, source)
|
160
|
+
return unless source
|
161
|
+
source.keys.each do |key|
|
162
|
+
|
163
|
+
if @cache[key] != source[key]
|
164
|
+
@callbacks[key].each do |proc|
|
165
|
+
if direction == :add
|
166
|
+
proc.call(source[key])
|
167
|
+
else
|
168
|
+
proc.call(@cache[key])
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def flattened
|
176
|
+
config_stack.reverse.inject({}) do |flat,layer|
|
177
|
+
thawed_layer = layer.to_hash.dup
|
178
|
+
thawed_layer.each do |k,v|
|
179
|
+
begin
|
180
|
+
thawed_layer[k] = instance_eval(&v) if v.respond_to?(:call)
|
181
|
+
rescue => e
|
182
|
+
D13n.logger.debug("#{e.class.name} : #{e.message} - when accessing config key #{k}")
|
183
|
+
thawed_layer[k] = nil
|
184
|
+
end
|
185
|
+
thawed_layer.delete(:config)
|
186
|
+
end
|
187
|
+
flat.merge(thawed_layer.to_hash)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
def apply_mask(hash)
|
192
|
+
MASK_DEFAULTS. \
|
193
|
+
select {|_, proc| proc.call}. \
|
194
|
+
each {|key, _| hash.delete(key) }
|
195
|
+
hash
|
196
|
+
end
|
197
|
+
|
198
|
+
def to_hash
|
199
|
+
DottedHash.new(apply_mask(flattened)).to_hash
|
200
|
+
end
|
201
|
+
|
202
|
+
def to_collector_hash
|
203
|
+
DottedHash.new(apply_mask(flattened)).to_hash.delete_if do |k, v|
|
204
|
+
default = DEFAULTS[k]
|
205
|
+
if default
|
206
|
+
default[:exclude_from_reported_settings]
|
207
|
+
else
|
208
|
+
false
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
def app_name
|
214
|
+
D13n.config[:app_name]
|
215
|
+
end
|
216
|
+
|
217
|
+
private
|
218
|
+
|
219
|
+
def config_stack
|
220
|
+
stack = [@environment_source,
|
221
|
+
@server_source,
|
222
|
+
@manual_source,
|
223
|
+
@yaml_source,
|
224
|
+
@default_source]
|
225
|
+
|
226
|
+
stack.compact!
|
227
|
+
stack
|
228
|
+
end
|
229
|
+
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
require 'd13n/configuration/mask_defaults'
|
234
|
+
require 'd13n/configuration/dotted_hash'
|
235
|
+
require 'd13n/configuration/default_source'
|
236
|
+
require 'd13n/configuration/yaml_source'
|
237
|
+
require 'd13n/configuration/environment_source'
|
238
|
+
require 'd13n/configuration/server_source'
|
239
|
+
require 'd13n/configuration/manual_source'
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module D13n::Configuration
|
2
|
+
class ServerSource < DottedHash
|
3
|
+
SERVICE_PREFIXES = /^service/i
|
4
|
+
PROPERTY_PREFIXES = /^property/i
|
5
|
+
IDC_PREFIXES = /^idc/i
|
6
|
+
CLIENT_PREFIXES = /^client/i
|
7
|
+
JURISDICTION_PREFIXES = /^jurisdiction/i
|
8
|
+
|
9
|
+
attr_accessor :type_map
|
10
|
+
|
11
|
+
def initialize(connect_reply)
|
12
|
+
#filter_keys(connect_reply)
|
13
|
+
@type_map = {}
|
14
|
+
|
15
|
+
DEFAULTS.each do |config_setting, value|
|
16
|
+
self.type_map[config_setting] = value[:type]
|
17
|
+
end
|
18
|
+
|
19
|
+
super(connect_reply)
|
20
|
+
end
|
21
|
+
|
22
|
+
def set_keys_by_type()
|
23
|
+
self.keys.each do |key|
|
24
|
+
set_key_by_type(key)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def set_key_by_type(config_key)
|
29
|
+
value = self[config_key]
|
30
|
+
type = self.type_map[config_key]
|
31
|
+
|
32
|
+
if type == String
|
33
|
+
self[config_key] = value.to_s
|
34
|
+
elsif type == Integer
|
35
|
+
self[config_key] = value.to_i
|
36
|
+
elsif type == Float
|
37
|
+
self[config_key] = value.to_f
|
38
|
+
elsif type == Symbol
|
39
|
+
self[config_key] = value.to_sym
|
40
|
+
elsif type == Array
|
41
|
+
self[config_key] = value.split(/\s*,\s*/)
|
42
|
+
elsif type == D13n::Configuration::Boolean
|
43
|
+
if value =~ /false|off|no/i
|
44
|
+
self[config_key] = false
|
45
|
+
elsif value != nil
|
46
|
+
self[config_key] = true
|
47
|
+
end
|
48
|
+
else
|
49
|
+
D13n.logger.info("#{config_key} does not have a corresponding configuration setting (#{config_key} does not exist).")
|
50
|
+
self[config_key] = value
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.build(connect_reply)
|
55
|
+
instance = new(connect_reply)
|
56
|
+
self.filter_keys(instance)
|
57
|
+
instance
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.filter_keys(instance)
|
61
|
+
instance.delete_if do |key, _|
|
62
|
+
s_key = key.to_s
|
63
|
+
if s_key.match(SERVICE_PREFIXES) || s_key.match(PROPERTY_PREFIXES) || s_key.match(IDC_PREFIXES) || s_key.match(CLIENT_PREFIXES) || s_key.match(JURISDICTION_PREFIXES)
|
64
|
+
false
|
65
|
+
else
|
66
|
+
setting_spec = DEFAULTS[key.to_sym]
|
67
|
+
if setting_spec
|
68
|
+
if setting_spec[:allowed_from_server]
|
69
|
+
instance.set_key_by_type(key)
|
70
|
+
false # it's allowed, so don't delete it
|
71
|
+
else
|
72
|
+
D13n.logger.warn("Ignoring server-sent config for '#{key}' - this setting cannot be set from the server")
|
73
|
+
true # delete it
|
74
|
+
end
|
75
|
+
else
|
76
|
+
D13n.logger.debug("Ignoring unrecognized config key from server: '#{key}'")
|
77
|
+
true
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
module D13n::Configuration
|
3
|
+
class YamlSource < DottedHash
|
4
|
+
attr_accessor :file_path, :failures
|
5
|
+
|
6
|
+
def initialize(path,env)
|
7
|
+
config = {}
|
8
|
+
@failures = []
|
9
|
+
|
10
|
+
begin
|
11
|
+
@file_path = validate_config_file(path)
|
12
|
+
return unless @file_path
|
13
|
+
|
14
|
+
D13n.logger.info("Reading configuration from #{path} (#{Dir.pwd})")
|
15
|
+
raw_file = File.read(@file_path)
|
16
|
+
erb_file = process_erb(raw_file)
|
17
|
+
config = process_yaml(erb_file, env, config, @file_path)
|
18
|
+
rescue ScriptError, StandardError => e
|
19
|
+
log_failure("Failed to read or parse configuration file at #{path}", e)
|
20
|
+
end
|
21
|
+
|
22
|
+
super(config, true)
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
|
27
|
+
def validate_config_file(path)
|
28
|
+
expanded_path = File.expand_path(path)
|
29
|
+
|
30
|
+
if path.empty? || !File.exist?(expanded_path)
|
31
|
+
return
|
32
|
+
end
|
33
|
+
|
34
|
+
expanded_path
|
35
|
+
end
|
36
|
+
|
37
|
+
def process_erb(file)
|
38
|
+
begin
|
39
|
+
file.gsub!(/^\s*#.*$/, '#')
|
40
|
+
|
41
|
+
ERB.new(file).result(binding)
|
42
|
+
rescue Exception => e
|
43
|
+
log_failure("Failed ERB processing configuration file. This is typically caused by a Ruby error in <% %> templating blocks in your axle.yml file.", e)
|
44
|
+
ensure
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def process_yaml(file, env, config, path)
|
50
|
+
if file
|
51
|
+
confighash = YAML.load(file)
|
52
|
+
unless confighash.key?(env)
|
53
|
+
log_failure("Config file at #{path} doesn't include a '#{env}' section!")
|
54
|
+
end
|
55
|
+
config = confighash[env] || {}
|
56
|
+
end
|
57
|
+
|
58
|
+
config
|
59
|
+
end
|
60
|
+
|
61
|
+
def log_failure(*messages)
|
62
|
+
D13n.logger.error(*messages)
|
63
|
+
@failures << messages
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class String
|
2
|
+
# By default, +camelize+ converts strings to UpperCamelCase.
|
3
|
+
#
|
4
|
+
# 'active_record'.camelize # => "ActiveRecord"
|
5
|
+
def camelize
|
6
|
+
string = self
|
7
|
+
string.split('_').map{ |e| e.capitalize }.join
|
8
|
+
end
|
9
|
+
|
10
|
+
def underscore
|
11
|
+
self.gsub(/::/, '/').
|
12
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
13
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
14
|
+
tr("-", "_").
|
15
|
+
downcase
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module D13n
|
3
|
+
class Logger
|
4
|
+
module LogOnce
|
5
|
+
NUM_LOG_ONCE_KEYS = 1000
|
6
|
+
|
7
|
+
def log_once(level, key, *msgs)
|
8
|
+
return if @already_logged.include?(key)
|
9
|
+
|
10
|
+
if @already_logged.size >= NUM_LOG_ONCE_KEYS && key.kind_of?(String)
|
11
|
+
return
|
12
|
+
end
|
13
|
+
|
14
|
+
@already_logged[key] = true
|
15
|
+
|
16
|
+
self.send(level, *msgs)
|
17
|
+
end
|
18
|
+
|
19
|
+
def clear_already_logged
|
20
|
+
@already_logged = {}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module D13n
|
3
|
+
class Logger
|
4
|
+
class MemoryLogger
|
5
|
+
include LogOnce
|
6
|
+
def initialize
|
7
|
+
@messages = []
|
8
|
+
end
|
9
|
+
|
10
|
+
def is_startup_logger?
|
11
|
+
true
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_accessor :messages, :level, :log_formatter
|
15
|
+
|
16
|
+
def fatal(*msgs, &blk)
|
17
|
+
messages << [:fatal, msgs, blk]
|
18
|
+
end
|
19
|
+
|
20
|
+
def error(*msgs, &blk)
|
21
|
+
messages << [:error, msgs, blk]
|
22
|
+
end
|
23
|
+
|
24
|
+
def warn(*msgs, &blk)
|
25
|
+
messages << [:warn, msgs, blk]
|
26
|
+
end
|
27
|
+
|
28
|
+
def info(*msgs, &blk)
|
29
|
+
messages << [:info, msgs, blk]
|
30
|
+
end
|
31
|
+
|
32
|
+
def debug(*msgs, &blk)
|
33
|
+
messages << [:debug, msgs, blk]
|
34
|
+
end
|
35
|
+
|
36
|
+
def log_exception(level, e, backtrace_level=level)
|
37
|
+
messages << [:log_exception, [level, e, backtrace_level]]
|
38
|
+
end
|
39
|
+
|
40
|
+
def dump(logger)
|
41
|
+
messages.each do |(method, args, blk)|
|
42
|
+
logger.send(method, *args, &blk)
|
43
|
+
end
|
44
|
+
messages.clear
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module D13n
|
2
|
+
class Logger
|
3
|
+
class NullLogger
|
4
|
+
include Singleton
|
5
|
+
def fatal(*args); end
|
6
|
+
def error(*args); end
|
7
|
+
def warn(*args); end
|
8
|
+
def info(*args); end
|
9
|
+
def debug(*args); end
|
10
|
+
|
11
|
+
def method_missing(method, *args, &blk)
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|