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,92 @@
|
|
1
|
+
|
2
|
+
module Logsly::Logging182::Appenders
|
3
|
+
|
4
|
+
# Accessor / Factory for the StringIo appender.
|
5
|
+
#
|
6
|
+
def self.string_io( *args )
|
7
|
+
return ::Logsly::Logging182::Appenders::StringIo if args.empty?
|
8
|
+
::Logsly::Logging182::Appenders::StringIo.new(*args)
|
9
|
+
end
|
10
|
+
|
11
|
+
# This class provides an Appender that can write to a StringIO instance.
|
12
|
+
# This is very useful for testing log message output.
|
13
|
+
#
|
14
|
+
class StringIo < ::Logsly::Logging182::Appenders::IO
|
15
|
+
|
16
|
+
# The StringIO instance the appender is writing to.
|
17
|
+
attr_reader :sio
|
18
|
+
|
19
|
+
# call-seq:
|
20
|
+
# StringIo.new( name, opts = {} )
|
21
|
+
#
|
22
|
+
# Creates a new StringIo appender that will append log messages to a
|
23
|
+
# StringIO instance.
|
24
|
+
#
|
25
|
+
def initialize( name, opts = {} )
|
26
|
+
@sio = StringIO.new
|
27
|
+
@sio.extend IoToS
|
28
|
+
@pos = 0
|
29
|
+
super(name, @sio, opts)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Reopen the underlying StringIO instance. If the instance is currently
|
33
|
+
# closed then it will be opened. If the instance is currently open then it
|
34
|
+
# will be closed and immediately opened.
|
35
|
+
#
|
36
|
+
def reopen
|
37
|
+
@mutex.synchronize {
|
38
|
+
if defined? @io and @io
|
39
|
+
flush
|
40
|
+
@io.close rescue nil
|
41
|
+
end
|
42
|
+
@io = @sio = StringIO.new
|
43
|
+
@sio.extend IoToS
|
44
|
+
@pos = 0
|
45
|
+
}
|
46
|
+
super
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
# Clears the internal StringIO instance. All log messages are removed
|
51
|
+
# from the buffer.
|
52
|
+
#
|
53
|
+
def clear
|
54
|
+
@mutex.synchronize {
|
55
|
+
@pos = 0
|
56
|
+
@sio.seek 0
|
57
|
+
@sio.truncate 0
|
58
|
+
}
|
59
|
+
end
|
60
|
+
alias :reset :clear
|
61
|
+
|
62
|
+
%w[read readline readlines].each do|m|
|
63
|
+
class_eval <<-CODE, __FILE__, __LINE__+1
|
64
|
+
def #{m}( *args )
|
65
|
+
sync {
|
66
|
+
begin
|
67
|
+
@sio.seek @pos
|
68
|
+
rv = @sio.#{m}(*args)
|
69
|
+
@pos = @sio.tell
|
70
|
+
rv
|
71
|
+
rescue EOFError
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
}
|
75
|
+
end
|
76
|
+
CODE
|
77
|
+
end
|
78
|
+
|
79
|
+
# :stopdoc:
|
80
|
+
module IoToS
|
81
|
+
def to_s
|
82
|
+
seek 0
|
83
|
+
str = read
|
84
|
+
seek 0
|
85
|
+
return str
|
86
|
+
end
|
87
|
+
end
|
88
|
+
# :startdoc:
|
89
|
+
|
90
|
+
end # StringIo
|
91
|
+
end # Logsly::Logging182::Appenders
|
92
|
+
|
@@ -0,0 +1,215 @@
|
|
1
|
+
|
2
|
+
# only load this class if we have the syslog library
|
3
|
+
# Windows does not have syslog
|
4
|
+
#
|
5
|
+
if HAVE_SYSLOG
|
6
|
+
|
7
|
+
module Logsly::Logging182::Appenders
|
8
|
+
|
9
|
+
# Accessor / Factory for the Syslog appender.
|
10
|
+
#
|
11
|
+
def self.syslog( *args )
|
12
|
+
return ::Logsly::Logging182::Appenders::Syslog if args.empty?
|
13
|
+
::Logsly::Logging182::Appenders::Syslog.new(*args)
|
14
|
+
end
|
15
|
+
|
16
|
+
# This class provides an Appender that can write to the UNIX syslog
|
17
|
+
# daemon.
|
18
|
+
#
|
19
|
+
class Syslog < ::Logsly::Logging182::Appender
|
20
|
+
include ::Syslog::Constants
|
21
|
+
|
22
|
+
# call-seq:
|
23
|
+
# Syslog.new( name, opts = {} )
|
24
|
+
#
|
25
|
+
# Create an appender that will log messages to the system message
|
26
|
+
# logger. The message is then written to the system console, log files,
|
27
|
+
# logged-in users, or forwarded to other machines as appropriate. The
|
28
|
+
# options that can be used to configure the appender are as follows:
|
29
|
+
#
|
30
|
+
# :ident => identifier string (name is used by default)
|
31
|
+
# :logopt => options used when opening the connection
|
32
|
+
# :facility => the syslog facility to use
|
33
|
+
#
|
34
|
+
# The parameter :ident is a string that will be prepended to every
|
35
|
+
# message. The :logopt argument is a bit field specifying logging
|
36
|
+
# options, which is formed by OR'ing one or more of the following
|
37
|
+
# values:
|
38
|
+
#
|
39
|
+
# LOG_CONS If syslog() cannot pass the message to syslogd(8) it
|
40
|
+
# wil attempt to write the message to the console
|
41
|
+
# ('/dev/console').
|
42
|
+
#
|
43
|
+
# LOG_NDELAY Open the connection to syslogd(8) immediately. Normally
|
44
|
+
# the open is delayed until the first message is logged.
|
45
|
+
# Useful for programs that need to manage the order in
|
46
|
+
# which file descriptors are allocated.
|
47
|
+
#
|
48
|
+
# LOG_PERROR Write the message to standard error output as well to
|
49
|
+
# the system log. Not available on Solaris.
|
50
|
+
#
|
51
|
+
# LOG_PID Log the process id with each message: useful for
|
52
|
+
# identifying instantiations of daemons.
|
53
|
+
#
|
54
|
+
# The :facility parameter encodes a default facility to be assigned to
|
55
|
+
# all messages that do not have an explicit facility encoded:
|
56
|
+
#
|
57
|
+
# LOG_AUTH The authorization system: login(1), su(1), getty(8),
|
58
|
+
# etc.
|
59
|
+
#
|
60
|
+
# LOG_AUTHPRIV The same as LOG_AUTH, but logged to a file readable
|
61
|
+
# only by selected individuals.
|
62
|
+
#
|
63
|
+
# LOG_CONSOLE Messages written to /dev/console by the kernel console
|
64
|
+
# output driver.
|
65
|
+
#
|
66
|
+
# LOG_CRON The cron daemon: cron(8).
|
67
|
+
#
|
68
|
+
# LOG_DAEMON System daemons, such as routed(8), that are not
|
69
|
+
# provided for explicitly by other facilities.
|
70
|
+
#
|
71
|
+
# LOG_FTP The file transfer protocol daemons: ftpd(8), tftpd(8).
|
72
|
+
#
|
73
|
+
# LOG_KERN Messages generated by the kernel. These cannot be
|
74
|
+
# generated by any user processes.
|
75
|
+
#
|
76
|
+
# LOG_LPR The line printer spooling system: lpr(1), lpc(8),
|
77
|
+
# lpd(8), etc.
|
78
|
+
#
|
79
|
+
# LOG_MAIL The mail system.
|
80
|
+
#
|
81
|
+
# LOG_NEWS The network news system.
|
82
|
+
#
|
83
|
+
# LOG_SECURITY Security subsystems, such as ipfw(4).
|
84
|
+
#
|
85
|
+
# LOG_SYSLOG Messages generated internally by syslogd(8).
|
86
|
+
#
|
87
|
+
# LOG_USER Messages generated by random user processes. This is
|
88
|
+
# the default facility identifier if none is specified.
|
89
|
+
#
|
90
|
+
# LOG_UUCP The uucp system.
|
91
|
+
#
|
92
|
+
# LOG_LOCAL0 Reserved for local use. Similarly for LOG_LOCAL1
|
93
|
+
# through LOG_LOCAL7.
|
94
|
+
#
|
95
|
+
def initialize( name, opts = {} )
|
96
|
+
@ident = opts.getopt(:ident, name)
|
97
|
+
@logopt = opts.getopt(:logopt, (LOG_PID | LOG_CONS), :as => Integer)
|
98
|
+
@facility = opts.getopt(:facility, LOG_USER, :as => Integer)
|
99
|
+
@syslog = ::Syslog.open(@ident, @logopt, @facility)
|
100
|
+
|
101
|
+
# provides a mapping from the default Logsly::Logging182 levels
|
102
|
+
# to the syslog levels
|
103
|
+
@map = [LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERR, LOG_CRIT]
|
104
|
+
|
105
|
+
map = opts.getopt(:map)
|
106
|
+
self.map = map unless map.nil?
|
107
|
+
|
108
|
+
super
|
109
|
+
end
|
110
|
+
|
111
|
+
# call-seq:
|
112
|
+
# map = { logging_levels => syslog_levels }
|
113
|
+
#
|
114
|
+
# Configure the mapping from the Logsly::Logging182 levels to the syslog levels.
|
115
|
+
# This is needed in order to log events at the proper syslog level.
|
116
|
+
#
|
117
|
+
# Without any configuration, the following mapping will be used:
|
118
|
+
#
|
119
|
+
# :debug => LOG_DEBUG
|
120
|
+
# :info => LOG_INFO
|
121
|
+
# :warn => LOG_WARNING
|
122
|
+
# :error => LOG_ERR
|
123
|
+
# :fatal => LOG_CRIT
|
124
|
+
#
|
125
|
+
def map=( levels )
|
126
|
+
map = []
|
127
|
+
levels.keys.each do |lvl|
|
128
|
+
num = ::Logsly::Logging182.level_num(lvl)
|
129
|
+
map[num] = syslog_level_num(levels[lvl])
|
130
|
+
end
|
131
|
+
@map = map
|
132
|
+
end
|
133
|
+
|
134
|
+
# call-seq:
|
135
|
+
# close
|
136
|
+
#
|
137
|
+
# Closes the connection to the syslog facility.
|
138
|
+
#
|
139
|
+
def close( footer = true )
|
140
|
+
super
|
141
|
+
@syslog.close if @syslog.opened?
|
142
|
+
self
|
143
|
+
end
|
144
|
+
|
145
|
+
# call-seq:
|
146
|
+
# closed? => true or false
|
147
|
+
#
|
148
|
+
# Queries the connection to the syslog facility and returns +true+ if
|
149
|
+
# the connection is closed.
|
150
|
+
#
|
151
|
+
def closed?
|
152
|
+
!@syslog.opened?
|
153
|
+
end
|
154
|
+
|
155
|
+
# Reopen the connection to the underlying logging destination. If the
|
156
|
+
# connection is currently closed then it will be opened. If the connection
|
157
|
+
# is currently open then it will be closed and immediately opened.
|
158
|
+
#
|
159
|
+
def reopen
|
160
|
+
@mutex.synchronize {
|
161
|
+
if @syslog.opened?
|
162
|
+
flush
|
163
|
+
@syslog.close
|
164
|
+
end
|
165
|
+
@syslog = ::Syslog.open(@ident, @logopt, @facility)
|
166
|
+
}
|
167
|
+
super
|
168
|
+
self
|
169
|
+
end
|
170
|
+
|
171
|
+
|
172
|
+
private
|
173
|
+
|
174
|
+
# call-seq:
|
175
|
+
# write( event )
|
176
|
+
#
|
177
|
+
# Write the given _event_ to the syslog facility. The log event will be
|
178
|
+
# processed through the Layout associated with this appender. The message
|
179
|
+
# will be logged at the level specified by the event.
|
180
|
+
#
|
181
|
+
def write( event )
|
182
|
+
pri = LOG_DEBUG
|
183
|
+
message = if event.instance_of?(::Logsly::Logging182::LogEvent)
|
184
|
+
pri = @map[event.level]
|
185
|
+
@layout.format(event)
|
186
|
+
else
|
187
|
+
event.to_s
|
188
|
+
end
|
189
|
+
return if message.empty?
|
190
|
+
|
191
|
+
@syslog.log(pri, '%s', message)
|
192
|
+
self
|
193
|
+
end
|
194
|
+
|
195
|
+
# call-seq:
|
196
|
+
# syslog_level_num( level ) => integer
|
197
|
+
#
|
198
|
+
# Takes the given _level_ as a string, symbol, or integer and returns
|
199
|
+
# the corresponding syslog level number.
|
200
|
+
#
|
201
|
+
def syslog_level_num( level )
|
202
|
+
case level
|
203
|
+
when Integer; level
|
204
|
+
when String, Symbol
|
205
|
+
level = level.to_s.upcase
|
206
|
+
self.class.const_get level
|
207
|
+
else
|
208
|
+
raise ArgumentError, "unkonwn level '#{level}'"
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
end # Syslog
|
213
|
+
end # Logsly::Logging182::Appenders
|
214
|
+
end # HAVE_SYSLOG
|
215
|
+
|
@@ -0,0 +1,64 @@
|
|
1
|
+
|
2
|
+
module Logsly::Logging182
|
3
|
+
module Appenders
|
4
|
+
|
5
|
+
# call-seq:
|
6
|
+
# Appenders[name]
|
7
|
+
#
|
8
|
+
# Returns the appender instance stored in the appender hash under the
|
9
|
+
# key _name_, or +nil+ if no appender has been created using that name.
|
10
|
+
#
|
11
|
+
def []( name ) @appenders[name] end
|
12
|
+
|
13
|
+
# call-seq:
|
14
|
+
# Appenders[name] = appender
|
15
|
+
#
|
16
|
+
# Stores the given _appender_ instance in the appender hash under the
|
17
|
+
# key _name_.
|
18
|
+
#
|
19
|
+
def []=( name, value ) @appenders[name] = value end
|
20
|
+
|
21
|
+
# call-seq:
|
22
|
+
# Appenders.remove( name )
|
23
|
+
#
|
24
|
+
# Removes the appender instance stored in the appender hash under the
|
25
|
+
# key _name_.
|
26
|
+
#
|
27
|
+
def remove( name ) @appenders.delete(name) end
|
28
|
+
|
29
|
+
# call-seq:
|
30
|
+
# each {|appender| block}
|
31
|
+
#
|
32
|
+
# Yield each appender to the _block_.
|
33
|
+
#
|
34
|
+
def each( &block )
|
35
|
+
@appenders.values.each(&block)
|
36
|
+
return nil
|
37
|
+
end
|
38
|
+
|
39
|
+
# :stopdoc:
|
40
|
+
def reset
|
41
|
+
@appenders.values.each {|appender|
|
42
|
+
next if appender.nil?
|
43
|
+
appender.close
|
44
|
+
}
|
45
|
+
@appenders.clear
|
46
|
+
return nil
|
47
|
+
end
|
48
|
+
# :startdoc:
|
49
|
+
|
50
|
+
extend self
|
51
|
+
@appenders = Hash.new
|
52
|
+
end # Appenders
|
53
|
+
|
54
|
+
require 'logsly/logging182/appenders/buffering'
|
55
|
+
require 'logsly/logging182/appenders/io'
|
56
|
+
require 'logsly/logging182/appenders/console'
|
57
|
+
require 'logsly/logging182/appenders/email'
|
58
|
+
require 'logsly/logging182/appenders/file'
|
59
|
+
require 'logsly/logging182/appenders/growl'
|
60
|
+
require 'logsly/logging182/appenders/rolling_file'
|
61
|
+
require 'logsly/logging182/appenders/string_io'
|
62
|
+
require 'logsly/logging182/appenders/syslog'
|
63
|
+
end # Logsly::Logging182
|
64
|
+
|
@@ -0,0 +1,248 @@
|
|
1
|
+
|
2
|
+
# color_scheme.rb
|
3
|
+
#
|
4
|
+
# Created by Jeremy Hinegardner on 2007-01-24
|
5
|
+
# Copyright 2007. All rights reserved
|
6
|
+
#
|
7
|
+
# This is Free Software. See LICENSE and COPYING for details
|
8
|
+
|
9
|
+
module Logsly::Logging182
|
10
|
+
|
11
|
+
# ColorScheme objects encapsulate a named set of colors to be used in the
|
12
|
+
# colors() method call. For example, by applying a ColorScheme that
|
13
|
+
# has a <tt>:warning</tt> color then the following could be used:
|
14
|
+
#
|
15
|
+
# scheme.color("This is a warning", :warning)
|
16
|
+
#
|
17
|
+
# ColorScheme objects are used by the Pattern layout code to colorize log
|
18
|
+
# messages. Each color scheme is given a unique name which is used by the
|
19
|
+
# Pattern layout to lookup the appropriate color scheme to use. Please
|
20
|
+
# refer to the Pattern layout documentation for more details - specifically
|
21
|
+
# the initializer documentation.
|
22
|
+
#
|
23
|
+
# The color scheme can be applied to the Pattern layout in several ways.
|
24
|
+
# Each token in the log pattern can be colorized with the log level (debug,
|
25
|
+
# info, warn, etc) receiving unique colors based on the level itself.
|
26
|
+
# Another option is to colorize the entire log message based on the log
|
27
|
+
# level; in this mode tokens do not get their own colors. Please see the
|
28
|
+
# ColorScheme initializer for the list of colorization options.
|
29
|
+
#
|
30
|
+
class ColorScheme
|
31
|
+
|
32
|
+
class << self
|
33
|
+
# Retrieve a color scheme by name.
|
34
|
+
#
|
35
|
+
def []( name )
|
36
|
+
@color_schemes[name.to_s]
|
37
|
+
end
|
38
|
+
|
39
|
+
# Store a color scheme by name.
|
40
|
+
#
|
41
|
+
def []=( name, value )
|
42
|
+
raise ArgumentError, "Silly! That's not a ColorSchmeme!" unless ColorScheme === value
|
43
|
+
@color_schemes[name.to_s] = value
|
44
|
+
end
|
45
|
+
|
46
|
+
# Clear all color schemes and setup a default color scheme.
|
47
|
+
#
|
48
|
+
def reset
|
49
|
+
@color_schemes ||= {}
|
50
|
+
@color_schemes.clear
|
51
|
+
|
52
|
+
new(:default, :levels => {
|
53
|
+
:info => :green,
|
54
|
+
:warn => :yellow,
|
55
|
+
:error => :red,
|
56
|
+
:fatal => [:white, :on_red]
|
57
|
+
})
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Create a ColorScheme instance that can be accessed using the given
|
62
|
+
# _name_. If a color scheme already exists with the given _name_ it will
|
63
|
+
# be replaced by the new color scheme.
|
64
|
+
#
|
65
|
+
# The color names are passed as options to the method with each name
|
66
|
+
# mapping to one or more color codes. For example:
|
67
|
+
#
|
68
|
+
# ColorScheme.new('example', :logger => [:white, :on_green], :message => :magenta)
|
69
|
+
#
|
70
|
+
# The color codes are the lowercase names of the constants defined at the
|
71
|
+
# end of this file. Multiple color codes can be aliased by grouping them
|
72
|
+
# in an array as shown in the example above.
|
73
|
+
#
|
74
|
+
# Since color schemes are primary intended to be used with the Pattern
|
75
|
+
# layout, there are a few special options of note. First the log levels
|
76
|
+
# are enumerated in their own hash:
|
77
|
+
#
|
78
|
+
# :levels => {
|
79
|
+
# :debug => :blue,
|
80
|
+
# :info => :cyan,
|
81
|
+
# :warn => :yellow,
|
82
|
+
# :error => :red,
|
83
|
+
# :fatal => [:white, :on_red]
|
84
|
+
# }
|
85
|
+
#
|
86
|
+
# The log level token will be colorized differently based on the value of
|
87
|
+
# the log level itself. Similarly the entire log message can be colorized
|
88
|
+
# based on the value of the log level. A different option should be given
|
89
|
+
# for this behavior:
|
90
|
+
#
|
91
|
+
# :lines => {
|
92
|
+
# :debug => :blue,
|
93
|
+
# :info => :cyan,
|
94
|
+
# :warn => :yellow,
|
95
|
+
# :error => :red,
|
96
|
+
# :fatal => [:white, :on_red]
|
97
|
+
# }
|
98
|
+
#
|
99
|
+
# The :levels and :lines options cannot be used together; only one or the
|
100
|
+
# other should be given.
|
101
|
+
#
|
102
|
+
# The remaining tokens defined in the Pattern layout can be colorized
|
103
|
+
# using the following aliases. Their meaning in the Pattern layout are
|
104
|
+
# repeated here for sake of clarity.
|
105
|
+
#
|
106
|
+
# :logger [%c] name of the logger that generate the log event
|
107
|
+
# :date [%d] datestamp
|
108
|
+
# :message [%m] the user supplied log message
|
109
|
+
# :pid [%p] PID of the current process
|
110
|
+
# :time [%r] the time in milliseconds since the program started
|
111
|
+
# :thread [%T] the name of the thread Thread.current[:name]
|
112
|
+
# :thread_id [%t] object_id of the thread
|
113
|
+
# :file [%F] filename where the logging request was issued
|
114
|
+
# :line [%L] line number where the logging request was issued
|
115
|
+
# :method [%M] method name where the logging request was issued
|
116
|
+
#
|
117
|
+
# Please refer to the "examples/colorization.rb" file for a working
|
118
|
+
# example of log colorization.
|
119
|
+
#
|
120
|
+
def initialize( name, opts = {} )
|
121
|
+
@scheme = Hash.new
|
122
|
+
|
123
|
+
@lines = opts.key? :lines
|
124
|
+
@levels = opts.key? :levels
|
125
|
+
raise ArgumentError, "Found both :lines and :levels - only one can be used." if lines? and levels?
|
126
|
+
|
127
|
+
lines = opts.delete :lines
|
128
|
+
levels = opts.delete :levels
|
129
|
+
|
130
|
+
load_from_hash(opts)
|
131
|
+
load_from_hash(lines) if lines?
|
132
|
+
load_from_hash(levels) if levels?
|
133
|
+
|
134
|
+
::Logsly::Logging182::ColorScheme[name] = self
|
135
|
+
end
|
136
|
+
|
137
|
+
# Load multiple colors from key/value pairs.
|
138
|
+
#
|
139
|
+
def load_from_hash( h )
|
140
|
+
h.each_pair do |color_tag, constants|
|
141
|
+
self[color_tag] = constants
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
# Returns +true+ if the :lines option was passed to the constructor.
|
146
|
+
#
|
147
|
+
def lines?
|
148
|
+
@lines
|
149
|
+
end
|
150
|
+
|
151
|
+
# Returns +true+ if the :levels option was passed to the constructor.
|
152
|
+
#
|
153
|
+
def levels?
|
154
|
+
@levels
|
155
|
+
end
|
156
|
+
|
157
|
+
# Does this color scheme include the given tag name?
|
158
|
+
#
|
159
|
+
def include?( color_tag )
|
160
|
+
@scheme.key?(to_key(color_tag))
|
161
|
+
end
|
162
|
+
|
163
|
+
# Allow the scheme to be accessed like a Hash.
|
164
|
+
#
|
165
|
+
def []( color_tag )
|
166
|
+
@scheme[to_key(color_tag)]
|
167
|
+
end
|
168
|
+
|
169
|
+
# Allow the scheme to be set like a Hash.
|
170
|
+
#
|
171
|
+
def []=( color_tag, constants )
|
172
|
+
@scheme[to_key(color_tag)] = constants.respond_to?(:map) ?
|
173
|
+
constants.map { |c| to_constant(c) }.join : to_constant(constants)
|
174
|
+
end
|
175
|
+
|
176
|
+
# This method provides easy access to ANSI color sequences, without the user
|
177
|
+
# needing to remember to CLEAR at the end of each sequence. Just pass the
|
178
|
+
# _string_ to color, followed by a list of _colors_ you would like it to be
|
179
|
+
# affected by. The _colors_ can be ColorScheme class constants, or symbols
|
180
|
+
# (:blue for BLUE, for example). A CLEAR will automatically be embedded to
|
181
|
+
# the end of the returned String.
|
182
|
+
#
|
183
|
+
def color( string, *colors )
|
184
|
+
colors.map! { |color|
|
185
|
+
color_tag = to_key(color)
|
186
|
+
@scheme.key?(color_tag) ? @scheme[color_tag] : to_constant(color)
|
187
|
+
}
|
188
|
+
|
189
|
+
colors.compact!
|
190
|
+
return string if colors.empty?
|
191
|
+
|
192
|
+
"#{colors.join}#{string}#{CLEAR}"
|
193
|
+
end
|
194
|
+
|
195
|
+
private
|
196
|
+
|
197
|
+
# Return a normalized representation of a color name.
|
198
|
+
#
|
199
|
+
def to_key( t )
|
200
|
+
t.to_s.downcase
|
201
|
+
end
|
202
|
+
|
203
|
+
# Return a normalized representation of a color setting.
|
204
|
+
#
|
205
|
+
def to_constant( v )
|
206
|
+
v = v.to_s.upcase
|
207
|
+
ColorScheme.const_get(v) if (ColorScheme.const_defined?(v, false) rescue ColorScheme.const_defined?(v))
|
208
|
+
end
|
209
|
+
|
210
|
+
# Embed in a String to clear all previous ANSI sequences. This *MUST* be
|
211
|
+
# done before the program exits!
|
212
|
+
CLEAR = "\e[0m".freeze
|
213
|
+
RESET = CLEAR # An alias for CLEAR.
|
214
|
+
ERASE_LINE = "\e[K".freeze # Erase the current line of terminal output.
|
215
|
+
ERASE_CHAR = "\e[P".freeze # Erase the character under the cursor.
|
216
|
+
BOLD = "\e[1m".freeze # The start of an ANSI bold sequence.
|
217
|
+
DARK = "\e[2m".freeze # The start of an ANSI dark sequence. (Terminal support uncommon.)
|
218
|
+
UNDERLINE = "\e[4m".freeze # The start of an ANSI underline sequence.
|
219
|
+
UNDERSCORE = UNDERLINE # An alias for UNDERLINE.
|
220
|
+
BLINK = "\e[5m".freeze # The start of an ANSI blink sequence. (Terminal support uncommon.)
|
221
|
+
REVERSE = "\e[7m".freeze # The start of an ANSI reverse sequence.
|
222
|
+
CONCEALED = "\e[8m".freeze # The start of an ANSI concealed sequence. (Terminal support uncommon.)
|
223
|
+
|
224
|
+
BLACK = "\e[30m".freeze # Set the terminal's foreground ANSI color to black.
|
225
|
+
RED = "\e[31m".freeze # Set the terminal's foreground ANSI color to red.
|
226
|
+
GREEN = "\e[32m".freeze # Set the terminal's foreground ANSI color to green.
|
227
|
+
YELLOW = "\e[33m".freeze # Set the terminal's foreground ANSI color to yellow.
|
228
|
+
BLUE = "\e[34m".freeze # Set the terminal's foreground ANSI color to blue.
|
229
|
+
MAGENTA = "\e[35m".freeze # Set the terminal's foreground ANSI color to magenta.
|
230
|
+
CYAN = "\e[36m".freeze # Set the terminal's foreground ANSI color to cyan.
|
231
|
+
WHITE = "\e[37m".freeze # Set the terminal's foreground ANSI color to white.
|
232
|
+
|
233
|
+
ON_BLACK = "\e[40m".freeze # Set the terminal's background ANSI color to black.
|
234
|
+
ON_RED = "\e[41m".freeze # Set the terminal's background ANSI color to red.
|
235
|
+
ON_GREEN = "\e[42m".freeze # Set the terminal's background ANSI color to green.
|
236
|
+
ON_YELLOW = "\e[43m".freeze # Set the terminal's background ANSI color to yellow.
|
237
|
+
ON_BLUE = "\e[44m".freeze # Set the terminal's background ANSI color to blue.
|
238
|
+
ON_MAGENTA = "\e[45m".freeze # Set the terminal's background ANSI color to magenta.
|
239
|
+
ON_CYAN = "\e[46m".freeze # Set the terminal's background ANSI color to cyan.
|
240
|
+
ON_WHITE = "\e[47m".freeze # Set the terminal's background ANSI color to white.
|
241
|
+
|
242
|
+
end # ColorScheme
|
243
|
+
|
244
|
+
# setup the default color scheme
|
245
|
+
ColorScheme.reset
|
246
|
+
|
247
|
+
end # Logsly::Logging182
|
248
|
+
|