logsly 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +5 -3
- data/lib/logsly/colors.rb +2 -2
- data/lib/logsly/logging182/appender.rb +290 -0
- data/lib/logsly/logging182/appenders/buffering.rb +398 -0
- data/lib/logsly/logging182/appenders/console.rb +81 -0
- data/lib/logsly/logging182/appenders/email.rb +178 -0
- data/lib/logsly/logging182/appenders/file.rb +85 -0
- data/lib/logsly/logging182/appenders/growl.rb +200 -0
- data/lib/logsly/logging182/appenders/io.rb +84 -0
- data/lib/logsly/logging182/appenders/rolling_file.rb +338 -0
- data/lib/logsly/logging182/appenders/string_io.rb +92 -0
- data/lib/logsly/logging182/appenders/syslog.rb +215 -0
- data/lib/logsly/logging182/appenders.rb +64 -0
- data/lib/logsly/logging182/color_scheme.rb +248 -0
- data/lib/logsly/logging182/config/configurator.rb +187 -0
- data/lib/logsly/logging182/config/yaml_configurator.rb +190 -0
- data/lib/logsly/logging182/diagnostic_context.rb +332 -0
- data/lib/logsly/logging182/layout.rb +132 -0
- data/lib/logsly/logging182/layouts/basic.rb +38 -0
- data/lib/logsly/logging182/layouts/parseable.rb +256 -0
- data/lib/logsly/logging182/layouts/pattern.rb +568 -0
- data/lib/logsly/logging182/layouts.rb +9 -0
- data/lib/logsly/logging182/log_event.rb +44 -0
- data/lib/logsly/logging182/logger.rb +509 -0
- data/lib/logsly/logging182/proxy.rb +59 -0
- data/lib/logsly/logging182/rails_compat.rb +36 -0
- data/lib/logsly/logging182/repository.rb +231 -0
- data/lib/logsly/logging182/root_logger.rb +60 -0
- data/lib/logsly/logging182/stats.rb +277 -0
- data/lib/logsly/logging182/utils.rb +231 -0
- data/lib/logsly/logging182.rb +559 -0
- data/lib/logsly/outputs.rb +5 -5
- data/lib/logsly/version.rb +1 -1
- data/lib/logsly.rb +6 -6
- data/logsly.gemspec +4 -2
- data/test/unit/colors_tests.rb +3 -3
- data/test/unit/logsly_tests.rb +14 -14
- data/test/unit/outputs_tests.rb +34 -24
- metadata +45 -6
@@ -0,0 +1,559 @@
|
|
1
|
+
|
2
|
+
# Equivalent to a header guard in C/C++
|
3
|
+
# Used to prevent the class/module from being loaded more than once
|
4
|
+
unless defined? Logsly::Logging182
|
5
|
+
|
6
|
+
require File.expand_path('../logging182/utils', __FILE__)
|
7
|
+
|
8
|
+
require 'yaml'
|
9
|
+
require 'stringio'
|
10
|
+
require 'fileutils'
|
11
|
+
require 'little-plugger'
|
12
|
+
require 'multi_json'
|
13
|
+
|
14
|
+
HAVE_SYSLOG = require? 'syslog'
|
15
|
+
|
16
|
+
#
|
17
|
+
#
|
18
|
+
module Logsly::Logging182
|
19
|
+
extend LittlePlugger
|
20
|
+
|
21
|
+
# :stopdoc:
|
22
|
+
# LIBPATH = ::File.expand_path('..', __FILE__) + ::File::SEPARATOR
|
23
|
+
# PATH = ::File.expand_path('../..', __FILE__) + ::File::SEPARATOR
|
24
|
+
LEVELS = {}
|
25
|
+
LNAMES = []
|
26
|
+
module Plugins; end
|
27
|
+
# :startdoc:
|
28
|
+
|
29
|
+
class << self
|
30
|
+
|
31
|
+
# call-seq:
|
32
|
+
# Logsly::Logging182.configure( filename )
|
33
|
+
# Logsly::Logging182.configure { block }
|
34
|
+
#
|
35
|
+
# Configures the Logsly::Logging182 framework using the configuration information
|
36
|
+
# found in the given file. The file extension should be either '.yaml'
|
37
|
+
# or '.yml' (XML configuration is not yet supported).
|
38
|
+
#
|
39
|
+
def configure( *args, &block )
|
40
|
+
if block
|
41
|
+
return ::Logsly::Logging182::Config::Configurator.process(&block)
|
42
|
+
end
|
43
|
+
|
44
|
+
filename = args.shift
|
45
|
+
raise ArgumentError, 'a filename was not given' if filename.nil?
|
46
|
+
|
47
|
+
case File.extname(filename)
|
48
|
+
when '.yaml', '.yml'
|
49
|
+
::Logsly::Logging182::Config::YamlConfigurator.load(filename, *args)
|
50
|
+
else raise ArgumentError, 'unknown configuration file format' end
|
51
|
+
end
|
52
|
+
|
53
|
+
# call-seq:
|
54
|
+
# Logsly::Logging182.logger( device, age = 7, size = 1048576 )
|
55
|
+
# Logsly::Logging182.logger( device, age = 'weekly' )
|
56
|
+
#
|
57
|
+
# This convenience method returns a Logger instance configured to behave
|
58
|
+
# similarly to a core Ruby Logger instance.
|
59
|
+
#
|
60
|
+
# The _device_ is the logging destination. This can be a filename
|
61
|
+
# (String) or an IO object (STDERR, STDOUT, an open File, etc.). The
|
62
|
+
# _age_ is the number of old log files to keep or the frequency of
|
63
|
+
# rotation (+daily+, +weekly+, or +monthly+). The _size_ is the maximum
|
64
|
+
# logfile size and is only used when _age_ is a number.
|
65
|
+
#
|
66
|
+
# Using the same _device_ twice will result in the same Logger instance
|
67
|
+
# being returned. For example, if a Logger is created using STDOUT then
|
68
|
+
# the same Logger instance will be returned the next time STDOUT is
|
69
|
+
# used. A new Logger instance can be obtained by closing the previous
|
70
|
+
# logger instance.
|
71
|
+
#
|
72
|
+
# log1 = Logsly::Logging182.logger(STDOUT)
|
73
|
+
# log2 = Logsly::Logging182.logger(STDOUT)
|
74
|
+
# log1.object_id == log2.object_id #=> true
|
75
|
+
#
|
76
|
+
# log1.close
|
77
|
+
# log2 = Logsly::Logging182.logger(STDOUT)
|
78
|
+
# log1.object_id == log2.object_id #=> false
|
79
|
+
#
|
80
|
+
# The format of the log messages can be changed using a few optional
|
81
|
+
# parameters. The <tt>:pattern</tt> can be used to change the log
|
82
|
+
# message format. The <tt>:date_pattern</tt> can be used to change how
|
83
|
+
# timestamps are formatted.
|
84
|
+
#
|
85
|
+
# log = Logsly::Logging182.logger(STDOUT,
|
86
|
+
# :pattern => "[%d] %-5l : %m\n",
|
87
|
+
# :date_pattern => "%Y-%m-%d %H:%M:%S.%s")
|
88
|
+
#
|
89
|
+
# See the documentation for the Logsly::Logging182::Layouts::Pattern class for a
|
90
|
+
# full description of the :pattern and :date_pattern formatting strings.
|
91
|
+
#
|
92
|
+
def logger( *args )
|
93
|
+
return ::Logsly::Logging182::Logger if args.empty?
|
94
|
+
|
95
|
+
opts = args.pop if args.last.instance_of?(Hash)
|
96
|
+
opts ||= Hash.new
|
97
|
+
|
98
|
+
dev = args.shift
|
99
|
+
keep = age = args.shift
|
100
|
+
size = args.shift
|
101
|
+
|
102
|
+
name = case dev
|
103
|
+
when String; dev
|
104
|
+
when File; dev.path
|
105
|
+
else dev.object_id.to_s end
|
106
|
+
|
107
|
+
repo = ::Logsly::Logging182::Repository.instance
|
108
|
+
return repo[name] if repo.has_logger? name
|
109
|
+
|
110
|
+
l_opts = {
|
111
|
+
:pattern => "%.1l, [%d #%p] %#{::Logsly::Logging182::MAX_LEVEL_LENGTH}l : %m\n",
|
112
|
+
:date_pattern => '%Y-%m-%dT%H:%M:%S.%s'
|
113
|
+
}
|
114
|
+
[:pattern, :date_pattern, :date_method].each do |o|
|
115
|
+
l_opts[o] = opts.delete(o) if opts.has_key? o
|
116
|
+
end
|
117
|
+
layout = ::Logsly::Logging182::Layouts::Pattern.new(l_opts)
|
118
|
+
|
119
|
+
a_opts = Hash.new
|
120
|
+
a_opts[:size] = size if size.instance_of?(Fixnum)
|
121
|
+
a_opts[:age] = age if age.instance_of?(String)
|
122
|
+
a_opts[:keep] = keep if keep.instance_of?(Fixnum)
|
123
|
+
a_opts[:filename] = dev if dev.instance_of?(String)
|
124
|
+
a_opts[:layout] = layout
|
125
|
+
a_opts.merge! opts
|
126
|
+
|
127
|
+
appender =
|
128
|
+
case dev
|
129
|
+
when String
|
130
|
+
::Logsly::Logging182::Appenders::RollingFile.new(name, a_opts)
|
131
|
+
else
|
132
|
+
::Logsly::Logging182::Appenders::IO.new(name, dev, a_opts)
|
133
|
+
end
|
134
|
+
|
135
|
+
logger = ::Logsly::Logging182::Logger.new(name)
|
136
|
+
logger.add_appenders appender
|
137
|
+
logger.additive = false
|
138
|
+
|
139
|
+
class << logger
|
140
|
+
def close
|
141
|
+
@appenders.each {|a| a.close}
|
142
|
+
h = ::Logsly::Logging182::Repository.instance.instance_variable_get :@h
|
143
|
+
h.delete(@name)
|
144
|
+
class << self; undef :close; end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
logger
|
149
|
+
end
|
150
|
+
|
151
|
+
# Access to the layouts.
|
152
|
+
#
|
153
|
+
def layouts
|
154
|
+
::Logsly::Logging182::Layouts
|
155
|
+
end
|
156
|
+
|
157
|
+
# Access to the appenders.
|
158
|
+
#
|
159
|
+
def appenders
|
160
|
+
::Logsly::Logging182::Appenders
|
161
|
+
end
|
162
|
+
|
163
|
+
# Returns the color scheme identified by the given _name_. If there is no
|
164
|
+
# color scheme +nil+ is returned.
|
165
|
+
#
|
166
|
+
# If color scheme options are supplied then a new color scheme is created.
|
167
|
+
# Any existing color scheme with the given _name_ will be replaced by the
|
168
|
+
# new color scheme.
|
169
|
+
#
|
170
|
+
def color_scheme( name, opts = {} )
|
171
|
+
if opts.empty?
|
172
|
+
::Logsly::Logging182::ColorScheme[name]
|
173
|
+
else
|
174
|
+
::Logsly::Logging182::ColorScheme.new(name, opts)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
# Reopen all appenders. This method should be called immediately after a
|
179
|
+
# fork to ensure no conflict with file descriptors and calls to fcntl or
|
180
|
+
# flock.
|
181
|
+
#
|
182
|
+
def reopen
|
183
|
+
log_internal {'re-opening all appenders'}
|
184
|
+
::Logsly::Logging182::Appenders.each {|appender| appender.reopen}
|
185
|
+
self
|
186
|
+
end
|
187
|
+
|
188
|
+
# call-seq:
|
189
|
+
# Logsly::Logging182.consolidate( 'First::Name', 'Second::Name', ... )
|
190
|
+
#
|
191
|
+
# Consolidate all loggers under the given namespace. All child loggers
|
192
|
+
# in the namespace will use the "consolidated" namespace logger instead
|
193
|
+
# of creating a new logger for each class or module.
|
194
|
+
#
|
195
|
+
# If the "root" logger name is passed to this method then all loggers
|
196
|
+
# will consolidate to the root logger. In other words, only the root
|
197
|
+
# logger will be created, and it will be used by all classes and modules
|
198
|
+
# in the application.
|
199
|
+
#
|
200
|
+
# ==== Example
|
201
|
+
#
|
202
|
+
# Logsly::Logging182.consolidate( 'Foo' )
|
203
|
+
#
|
204
|
+
# foo = Logsly::Logging182.logger['Foo']
|
205
|
+
# bar = Logsly::Logging182.logger['Foo::Bar']
|
206
|
+
# baz = Logsly::Logging182.logger['Baz']
|
207
|
+
#
|
208
|
+
# foo.object_id == bar.object_id #=> true
|
209
|
+
# foo.object_id == baz.object_id #=> false
|
210
|
+
#
|
211
|
+
def consolidate( *args )
|
212
|
+
::Logsly::Logging182::Repository.instance.add_master(*args)
|
213
|
+
self
|
214
|
+
end
|
215
|
+
|
216
|
+
# call-seq:
|
217
|
+
# include Logsly::Logging182.globally
|
218
|
+
# include Logsly::Logging182.globally( :logger )
|
219
|
+
#
|
220
|
+
# Add a "logger" method to the including context. If included from
|
221
|
+
# Object or Kernel, the logger method will be available to all objects.
|
222
|
+
#
|
223
|
+
# Optionally, a method name can be given and that will be used to
|
224
|
+
# provided access to the logger:
|
225
|
+
#
|
226
|
+
# include Logsly::Logging182.globally( :log )
|
227
|
+
# log.info "Just using a shorter method name"
|
228
|
+
#
|
229
|
+
# If you prefer to use the shorter "log" to access the logger.
|
230
|
+
#
|
231
|
+
# ==== Example
|
232
|
+
#
|
233
|
+
# include Logsly::Logging182.globally
|
234
|
+
#
|
235
|
+
# class Foo
|
236
|
+
# logger.debug "Loading the Foo class"
|
237
|
+
# def initialize
|
238
|
+
# logger.info "Creating some new foo"
|
239
|
+
# end
|
240
|
+
# end
|
241
|
+
#
|
242
|
+
# logger.fatal "End of example"
|
243
|
+
#
|
244
|
+
def globally( name = :logger )
|
245
|
+
Module.new {
|
246
|
+
eval "def #{name}() @_logging_logger ||= ::Logsly::Logging182::Logger[self] end"
|
247
|
+
}
|
248
|
+
end
|
249
|
+
|
250
|
+
# call-seq:
|
251
|
+
# Logsly::Logging182.init( levels )
|
252
|
+
#
|
253
|
+
# Defines the levels available to the loggers. The _levels_ is an array
|
254
|
+
# of strings and symbols. Each element in the array is downcased and
|
255
|
+
# converted to a symbol; these symbols are used to create the logging
|
256
|
+
# methods in the loggers.
|
257
|
+
#
|
258
|
+
# The first element in the array is the lowest logging level. Setting the
|
259
|
+
# logging level to this value will enable all log messages. The last
|
260
|
+
# element in the array is the highest logging level. Setting the logging
|
261
|
+
# level to this value will disable all log messages except this highest
|
262
|
+
# level.
|
263
|
+
#
|
264
|
+
# This method should be invoked only once to configure the logging
|
265
|
+
# levels. It is automatically invoked with the default logging levels
|
266
|
+
# when the first logger is created.
|
267
|
+
#
|
268
|
+
# The levels "all" and "off" are reserved and will be ignored if passed
|
269
|
+
# to this method.
|
270
|
+
#
|
271
|
+
# Example:
|
272
|
+
#
|
273
|
+
# Logsly::Logging182.init :debug, :info, :warn, :error, :fatal
|
274
|
+
# log = Logsly::Logging182::Logger['my logger']
|
275
|
+
# log.level = :warn
|
276
|
+
# log.warn 'Danger! Danger! Will Robinson'
|
277
|
+
# log.info 'Just FYI' # => not logged
|
278
|
+
#
|
279
|
+
# or
|
280
|
+
#
|
281
|
+
# Logsly::Logging182.init %w(DEBUG INFO NOTICE WARNING ERR CRIT ALERT EMERG)
|
282
|
+
# log = Logsly::Logging182::Logger['syslog']
|
283
|
+
# log.level = :notice
|
284
|
+
# log.warning 'This is your first warning'
|
285
|
+
# log.info 'Just FYI' # => not logged
|
286
|
+
#
|
287
|
+
def init( *args )
|
288
|
+
args = %w(debug info warn error fatal) if args.empty?
|
289
|
+
|
290
|
+
args.flatten!
|
291
|
+
levels = LEVELS.clear
|
292
|
+
names = LNAMES.clear
|
293
|
+
|
294
|
+
id = 0
|
295
|
+
args.each do |lvl|
|
296
|
+
lvl = levelify lvl
|
297
|
+
unless levels.has_key?(lvl) or lvl == 'all' or lvl == 'off'
|
298
|
+
levels[lvl] = id
|
299
|
+
names[id] = lvl.upcase
|
300
|
+
id += 1
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
longest = names.inject {|x,y| (x.length > y.length) ? x : y}
|
305
|
+
longest = 'off' if longest.length < 3
|
306
|
+
module_eval "MAX_LEVEL_LENGTH = #{longest.length}", __FILE__, __LINE__
|
307
|
+
|
308
|
+
initialize_plugins
|
309
|
+
levels.keys
|
310
|
+
end
|
311
|
+
|
312
|
+
# call-seq:
|
313
|
+
# Logsly::Logging182.format_as( obj_format )
|
314
|
+
#
|
315
|
+
# Defines the default _obj_format_ method to use when converting objects
|
316
|
+
# into string representations for logging. _obj_format_ can be one of
|
317
|
+
# <tt>:string</tt>, <tt>:inspect</tt>, or <tt>:yaml</tt>. These
|
318
|
+
# formatting commands map to the following object methods
|
319
|
+
#
|
320
|
+
# * :string => to_s
|
321
|
+
# * :inspect => inspect
|
322
|
+
# * :yaml => to_yaml
|
323
|
+
# * :json => MultiJson.encode(obj)
|
324
|
+
#
|
325
|
+
# An +ArgumentError+ is raised if anything other than +:string+,
|
326
|
+
# +:inspect+, +:yaml+ is passed to this method.
|
327
|
+
#
|
328
|
+
def format_as( f )
|
329
|
+
f = f.intern if f.instance_of? String
|
330
|
+
|
331
|
+
unless [:string, :inspect, :yaml, :json].include? f
|
332
|
+
raise ArgumentError, "unknown object format '#{f}'"
|
333
|
+
end
|
334
|
+
|
335
|
+
module_eval "OBJ_FORMAT = :#{f}", __FILE__, __LINE__
|
336
|
+
self
|
337
|
+
end
|
338
|
+
|
339
|
+
# call-seq:
|
340
|
+
# Logsly::Logging182.backtrace #=> true or false
|
341
|
+
# Logsly::Logging182.backtrace( value ) #=> true or false
|
342
|
+
#
|
343
|
+
# Without any arguments, returns the global exception backtrace logging
|
344
|
+
# value. When set to +true+ backtraces will be written to the logs; when
|
345
|
+
# set to +false+ backtraces will be suppressed.
|
346
|
+
#
|
347
|
+
# When an argument is given the global exception backtrace setting will
|
348
|
+
# be changed. Value values are <tt>"on"</tt>, <tt>:on<tt> and +true+ to
|
349
|
+
# turn on backtraces and <tt>"off"</tt>, <tt>:off</tt> and +false+ to
|
350
|
+
# turn off backtraces.
|
351
|
+
#
|
352
|
+
def backtrace( b = nil )
|
353
|
+
@backtrace = true unless defined? @backtrace
|
354
|
+
return @backtrace if b.nil?
|
355
|
+
|
356
|
+
@backtrace = case b
|
357
|
+
when :on, 'on', true; true
|
358
|
+
when :off, 'off', false; false
|
359
|
+
else
|
360
|
+
raise ArgumentError, "backtrace must be true or false"
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
# Returns the version string for the library.
|
365
|
+
#
|
366
|
+
# def version
|
367
|
+
# @version ||= File.read(path('version.txt')).strip
|
368
|
+
# end
|
369
|
+
|
370
|
+
# Returns the library path for the module. If any arguments are given,
|
371
|
+
# they will be joined to the end of the library path using
|
372
|
+
# <tt>File.join</tt>.
|
373
|
+
#
|
374
|
+
# def libpath( *args, &block )
|
375
|
+
# rv = args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
|
376
|
+
# if block
|
377
|
+
# begin
|
378
|
+
# $LOAD_PATH.unshift LIBPATH
|
379
|
+
# rv = block.call
|
380
|
+
# ensure
|
381
|
+
# $LOAD_PATH.shift
|
382
|
+
# end
|
383
|
+
# end
|
384
|
+
# return rv
|
385
|
+
# end
|
386
|
+
|
387
|
+
# Returns the lpath for the module. If any arguments are given,
|
388
|
+
# they will be joined to the end of the path using
|
389
|
+
# <tt>File.join</tt>.
|
390
|
+
#
|
391
|
+
# def path( *args, &block )
|
392
|
+
# rv = args.empty? ? PATH : ::File.join(PATH, args.flatten)
|
393
|
+
# if block
|
394
|
+
# begin
|
395
|
+
# $LOAD_PATH.unshift PATH
|
396
|
+
# rv = block.call
|
397
|
+
# ensure
|
398
|
+
# $LOAD_PATH.shift
|
399
|
+
# end
|
400
|
+
# end
|
401
|
+
# return rv
|
402
|
+
# end
|
403
|
+
|
404
|
+
# call-seq:
|
405
|
+
# show_configuration( io = STDOUT, logger = 'root' )
|
406
|
+
#
|
407
|
+
# This method is used to show the configuration of the logging
|
408
|
+
# framework. The information is written to the given _io_ stream
|
409
|
+
# (defaulting to stdout). Normally the configuration is dumped starting
|
410
|
+
# with the root logger, but any logger name can be given.
|
411
|
+
#
|
412
|
+
# Each line contains information for a single logger and it's appenders.
|
413
|
+
# A child logger is indented two spaces from it's parent logger. Each
|
414
|
+
# line contains the logger name, level, additivity, and trace settings.
|
415
|
+
# Here is a brief example:
|
416
|
+
#
|
417
|
+
# root ........................... *info -T
|
418
|
+
# LoggerA ...................... info +A -T
|
419
|
+
# LoggerA::LoggerB ........... info +A -T
|
420
|
+
# LoggerA::LoggerC ........... *debug +A -T
|
421
|
+
# LoggerD ...................... *warn -A +T
|
422
|
+
#
|
423
|
+
# The lines can be deciphered as follows:
|
424
|
+
#
|
425
|
+
# 1) name - the name of the logger
|
426
|
+
#
|
427
|
+
# 2) level - the logger level; if it is preceded by an
|
428
|
+
# asterisk then the level was explicitly set for that
|
429
|
+
# logger (as opposed to being inherited from the parent
|
430
|
+
# logger)
|
431
|
+
#
|
432
|
+
# 3) additivity - a "+A" shows the logger is additive, and log events
|
433
|
+
# will be passed up to the parent logger; "-A" shows
|
434
|
+
# that the logger will *not* pass log events up to the
|
435
|
+
# parent logger
|
436
|
+
#
|
437
|
+
# 4) trace - a "+T" shows that the logger will include trace
|
438
|
+
# information in generated log events (this includes
|
439
|
+
# filename and line number of the log message; "-T"
|
440
|
+
# shows that the logger does not include trace
|
441
|
+
# information in the log events)
|
442
|
+
#
|
443
|
+
# If a logger has appenders then they are listed, one per line,
|
444
|
+
# immediately below the logger. Appender lines are pre-pended with a
|
445
|
+
# single dash:
|
446
|
+
#
|
447
|
+
# root ........................... *info -T
|
448
|
+
# - <Appenders::Stdout:0x8b02a4 name="stdout">
|
449
|
+
# LoggerA ...................... info +A -T
|
450
|
+
# LoggerA::LoggerB ........... info +A -T
|
451
|
+
# LoggerA::LoggerC ........... *debug +A -T
|
452
|
+
# LoggerD ...................... *warn -A +T
|
453
|
+
# - <Appenders::Stderr:0x8b04ca name="stderr">
|
454
|
+
#
|
455
|
+
# We can see in this configuration dump that all the loggers will append
|
456
|
+
# to stdout via the Stdout appender configured in the root logger. All
|
457
|
+
# the loggers are additive, and so their generated log events will be
|
458
|
+
# passed up to the root logger.
|
459
|
+
#
|
460
|
+
# The exception in this configuration is LoggerD. Its additivity is set
|
461
|
+
# to false. It uses its own appender to send messages to stderr.
|
462
|
+
#
|
463
|
+
def show_configuration( io = STDOUT, logger = 'root', indent = 0 )
|
464
|
+
logger = ::Logsly::Logging182::Logger[logger] unless ::Logsly::Logging182::Logger === logger
|
465
|
+
|
466
|
+
logger._dump_configuration(io, indent)
|
467
|
+
|
468
|
+
indent += 2
|
469
|
+
children = ::Logsly::Logging182::Repository.instance.children(logger.name)
|
470
|
+
children.sort {|a,b| a.name <=> b.name}.each do |child|
|
471
|
+
::Logsly::Logging182.show_configuration(io, child, indent)
|
472
|
+
end
|
473
|
+
|
474
|
+
self
|
475
|
+
end
|
476
|
+
|
477
|
+
# :stopdoc:
|
478
|
+
# Convert the given level into a canonical form - a lowercase string.
|
479
|
+
def levelify( level )
|
480
|
+
case level
|
481
|
+
when String; level.downcase
|
482
|
+
when Symbol; level.to_s.downcase
|
483
|
+
else raise ArgumentError, "levels must be a String or Symbol" end
|
484
|
+
end
|
485
|
+
|
486
|
+
# Convert the given level into a level number.
|
487
|
+
def level_num( level )
|
488
|
+
l = levelify(level) rescue level
|
489
|
+
case l
|
490
|
+
when 'all'; 0
|
491
|
+
when 'off'; LEVELS.length
|
492
|
+
else begin; Integer(l); rescue ArgumentError; LEVELS[l] end end
|
493
|
+
end
|
494
|
+
|
495
|
+
# Internal logging method for use by the framework.
|
496
|
+
def log_internal( level = 1, &block )
|
497
|
+
::Logsly::Logging182::Logger[::Logsly::Logging182].__send__(levelify(LNAMES[level]), &block)
|
498
|
+
end
|
499
|
+
|
500
|
+
# Close all appenders
|
501
|
+
def shutdown( *args )
|
502
|
+
return unless initialized?
|
503
|
+
log_internal {'shutdown called - closing all appenders'}
|
504
|
+
::Logsly::Logging182::Appenders.each {|appender| appender.close}
|
505
|
+
nil
|
506
|
+
end
|
507
|
+
|
508
|
+
# Reset the Logsly::Logging182 framework to it's uninitialized state
|
509
|
+
def reset
|
510
|
+
::Logsly::Logging182::Repository.reset
|
511
|
+
::Logsly::Logging182::Appenders.reset
|
512
|
+
::Logsly::Logging182::ColorScheme.reset
|
513
|
+
::Logsly::Logging182.clear_diagnostic_contexts(true)
|
514
|
+
LEVELS.clear
|
515
|
+
LNAMES.clear
|
516
|
+
remove_instance_variable :@backtrace if defined? @backtrace
|
517
|
+
remove_const :MAX_LEVEL_LENGTH if const_defined? :MAX_LEVEL_LENGTH
|
518
|
+
remove_const :OBJ_FORMAT if const_defined? :OBJ_FORMAT
|
519
|
+
self
|
520
|
+
end
|
521
|
+
|
522
|
+
# Return +true+ if the Logsly::Logging182 framework is initialized.
|
523
|
+
def initialized?
|
524
|
+
const_defined? :MAX_LEVEL_LENGTH
|
525
|
+
end
|
526
|
+
# :startdoc:
|
527
|
+
end
|
528
|
+
|
529
|
+
require 'logsly/logging182/appender'
|
530
|
+
require 'logsly/logging182/layout'
|
531
|
+
require 'logsly/logging182/log_event'
|
532
|
+
require 'logsly/logging182/logger'
|
533
|
+
require 'logsly/logging182/repository'
|
534
|
+
require 'logsly/logging182/root_logger'
|
535
|
+
require 'logsly/logging182/stats'
|
536
|
+
require 'logsly/logging182/color_scheme'
|
537
|
+
require 'logsly/logging182/appenders'
|
538
|
+
require 'logsly/logging182/layouts'
|
539
|
+
require 'logsly/logging182/proxy'
|
540
|
+
require 'logsly/logging182/diagnostic_context'
|
541
|
+
|
542
|
+
require 'logsly/logging182/config/configurator'
|
543
|
+
require 'logsly/logging182/config/yaml_configurator'
|
544
|
+
|
545
|
+
require 'logsly/logging182/rails_compat'
|
546
|
+
end # module Logsly::Logging182
|
547
|
+
|
548
|
+
|
549
|
+
# This finalizer will close all the appenders that exist in the system.
|
550
|
+
# This is needed for closing IO streams and connections to the syslog server
|
551
|
+
# or e-mail servers, etc.
|
552
|
+
#
|
553
|
+
# You can prevent the finalizer from running by calling `exit!` from your
|
554
|
+
# application. This is required when daemonizing.
|
555
|
+
#
|
556
|
+
ObjectSpace.define_finalizer self, Logsly::Logging182.method(:shutdown)
|
557
|
+
|
558
|
+
end # unless defined?
|
559
|
+
|
data/lib/logsly/outputs.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require 'logging'
|
2
1
|
require 'syslog'
|
2
|
+
require 'logsly/logging182'
|
3
3
|
|
4
4
|
module Logsly; end
|
5
5
|
module Logsly::Outputs
|
@@ -28,7 +28,7 @@ module Logsly::Outputs
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def to_layout(data)
|
31
|
-
|
31
|
+
Logsly::Logging182.layouts.pattern(data.to_pattern_opts)
|
32
32
|
end
|
33
33
|
|
34
34
|
def to_appender(*args)
|
@@ -81,7 +81,7 @@ module Logsly::Outputs
|
|
81
81
|
|
82
82
|
def to_appender(*args)
|
83
83
|
data = BaseData.new(*args, &self.build)
|
84
|
-
|
84
|
+
Logsly::Logging182.appenders.stdout(:layout => self.to_layout(data))
|
85
85
|
end
|
86
86
|
|
87
87
|
end
|
@@ -92,7 +92,7 @@ module Logsly::Outputs
|
|
92
92
|
|
93
93
|
def to_appender(*args)
|
94
94
|
data = FileData.new(*args, &self.build)
|
95
|
-
|
95
|
+
Logsly::Logging182.appenders.file(data.path, :layout => self.to_layout(data))
|
96
96
|
end
|
97
97
|
|
98
98
|
end
|
@@ -114,7 +114,7 @@ module Logsly::Outputs
|
|
114
114
|
::Syslog.close if ::Syslog.opened?
|
115
115
|
|
116
116
|
data = SyslogData.new(*args, &self.build)
|
117
|
-
|
117
|
+
Logsly::Logging182.appenders.syslog(data.identity, {
|
118
118
|
:logopt => data.log_opts,
|
119
119
|
:facility => data.facility,
|
120
120
|
:layout => self.to_layout(data)
|
data/lib/logsly/version.rb
CHANGED
data/lib/logsly.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'much-plugin'
|
2
|
-
require 'logging'
|
3
2
|
require 'logsly/version'
|
3
|
+
require 'logsly/logging182'
|
4
4
|
require 'logsly/colors'
|
5
5
|
require 'logsly/outputs'
|
6
6
|
|
@@ -14,7 +14,7 @@ module Logsly
|
|
14
14
|
|
15
15
|
def self.reset
|
16
16
|
@settings = nil
|
17
|
-
|
17
|
+
Logsly::Logging182.reset
|
18
18
|
end
|
19
19
|
|
20
20
|
def self.settings
|
@@ -51,10 +51,10 @@ module Logsly
|
|
51
51
|
|
52
52
|
@log_type = log_type.to_s
|
53
53
|
@level = (opts[:level] || opts['level'] || 'info').to_s
|
54
|
-
@outputs = opts[:outputs] || opts['outputs'] || []
|
54
|
+
@outputs = [*(opts[:outputs] || opts['outputs'] || [])]
|
55
55
|
|
56
56
|
unique_name = "#{self.class.name}-#{@log_type}-#{self.object_id}"
|
57
|
-
@logger =
|
57
|
+
@logger = Logsly::Logging182.logger[unique_name]
|
58
58
|
@logger.level = @level
|
59
59
|
|
60
60
|
@outputs.each do |output|
|
@@ -63,7 +63,7 @@ module Logsly
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def mdc(key, value)
|
66
|
-
|
66
|
+
Logsly::Logging182.mdc[key] = value
|
67
67
|
end
|
68
68
|
|
69
69
|
def file_path
|
@@ -108,7 +108,7 @@ module Logsly
|
|
108
108
|
end
|
109
109
|
|
110
110
|
def get_file_appender
|
111
|
-
@logger.appenders.detect{ |a| a.kind_of?(
|
111
|
+
@logger.appenders.detect{ |a| a.kind_of?(Logsly::Logging182::Appenders::File) }
|
112
112
|
end
|
113
113
|
|
114
114
|
end
|
data/logsly.gemspec
CHANGED
@@ -20,7 +20,9 @@ Gem::Specification.new do |gem|
|
|
20
20
|
|
21
21
|
gem.add_development_dependency("assert", ["~> 2.16.1"])
|
22
22
|
|
23
|
-
gem.add_dependency("much-plugin",
|
24
|
-
gem.add_dependency("logging",
|
23
|
+
gem.add_dependency("much-plugin", ["~> 0.2.0"])
|
24
|
+
# gem.add_dependency("logging", ["~> 1.8.2"]) # now manually copied in and tweaked, see README
|
25
|
+
gem.add_dependency("little-plugger", ["~> 1.1.4"]) # for logging182
|
26
|
+
gem.add_dependency("multi_json", ["~> 1.12.1"]) # for logging182
|
25
27
|
|
26
28
|
end
|
data/test/unit/colors_tests.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'assert'
|
2
2
|
require 'logsly/colors'
|
3
3
|
|
4
|
-
require '
|
4
|
+
require 'logsly/logging182'
|
5
5
|
|
6
6
|
class Logsly::Colors
|
7
7
|
|
@@ -39,12 +39,12 @@ class Logsly::Colors
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
should "build a unique
|
42
|
+
should "build a unique Logsly::Logging182 color scheme based on called args" do
|
43
43
|
arg = 'white'
|
44
44
|
scheme_name = subject.to_scheme(arg)
|
45
45
|
|
46
46
|
assert_equal "test-#{arg.object_id}", scheme_name
|
47
|
-
assert_kind_of
|
47
|
+
assert_kind_of Logsly::Logging182::ColorScheme, Logsly::Logging182.color_scheme(scheme_name)
|
48
48
|
end
|
49
49
|
|
50
50
|
end
|