semantic_logger 2.0.0 → 2.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.
- checksums.yaml +7 -0
- data/Gemfile +1 -1
- data/README.md +162 -159
- data/Rakefile +6 -5
- data/lib/semantic_logger.rb +1 -3
- data/lib/semantic_logger/appender/file.rb +9 -9
- data/lib/semantic_logger/appender/wrapper.rb +6 -6
- data/lib/semantic_logger/base.rb +13 -16
- data/lib/semantic_logger/loggable.rb +55 -3
- data/lib/semantic_logger/logger.rb +17 -47
- data/lib/semantic_logger/semantic_logger.rb +135 -0
- data/lib/semantic_logger/version.rb +1 -1
- data/test/loggable_test.rb +5 -5
- data/test/logger_test.rb +14 -13
- metadata +22 -52
- data/Gemfile.lock +0 -33
- data/nbproject/private/config.properties +0 -0
- data/nbproject/private/private.properties +0 -1
- data/nbproject/private/private.xml +0 -4
- data/nbproject/private/rake-d.txt +0 -4
- data/nbproject/project.properties +0 -7
- data/nbproject/project.xml +0 -16
data/Rakefile
CHANGED
@@ -2,6 +2,7 @@ lib = File.expand_path('../lib/', __FILE__)
|
|
2
2
|
$:.unshift lib unless $:.include?(lib)
|
3
3
|
|
4
4
|
require 'rubygems'
|
5
|
+
require 'rubygems/package'
|
5
6
|
require 'rake/clean'
|
6
7
|
require 'rake/testtask'
|
7
8
|
require 'date'
|
@@ -19,13 +20,13 @@ task :gem do |t|
|
|
19
20
|
spec.date = Date.today.to_s
|
20
21
|
spec.summary = "Improved logging for Ruby"
|
21
22
|
spec.description = "Semantic Logger takes logging in Ruby to a new level by adding several new capabilities to the commonly used Logging API"
|
22
|
-
spec.files = FileList["./**/*"].exclude(
|
23
|
+
spec.files = FileList["./**/*"].exclude(/\.gem$/, /\.log$/,/nbproject/).map{|f| f.sub(/^\.\//, '')}
|
24
|
+
spec.license = "Apache License V2.0"
|
23
25
|
spec.has_rdoc = true
|
24
|
-
spec.add_dependency 'sync_attr'
|
25
|
-
spec.add_dependency 'thread_safe'
|
26
|
-
spec.add_development_dependency 'shoulda'
|
26
|
+
spec.add_dependency 'sync_attr', '>= 1.0'
|
27
|
+
spec.add_dependency 'thread_safe', '>= 0.1.0'
|
27
28
|
end
|
28
|
-
Gem::
|
29
|
+
Gem::Package.build gemspec
|
29
30
|
end
|
30
31
|
|
31
32
|
desc "Run Test Suite"
|
data/lib/semantic_logger.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# Place requires here to prevent issues on JRuby with global.require.lock=true
|
2
2
|
require 'thread'
|
3
3
|
require 'semantic_logger/version'
|
4
|
+
require 'semantic_logger/semantic_logger'
|
4
5
|
|
5
6
|
module SemanticLogger
|
6
7
|
autoload :Base, 'semantic_logger/base'
|
@@ -13,7 +14,4 @@ module SemanticLogger
|
|
13
14
|
autoload :Wrapper, 'semantic_logger/appender/wrapper'
|
14
15
|
autoload :MongoDB, 'semantic_logger/appender/mongodb'
|
15
16
|
end
|
16
|
-
|
17
|
-
# Logging levels in order with most detailed logging first
|
18
|
-
LEVELS = [:trace, :debug, :info, :warn, :error, :fatal]
|
19
17
|
end
|
@@ -12,15 +12,15 @@ module SemanticLogger
|
|
12
12
|
# require 'semantic_logger'
|
13
13
|
#
|
14
14
|
# # Enable trace level logging
|
15
|
-
# SemanticLogger
|
15
|
+
# SemanticLogger.default_level = :info
|
16
16
|
#
|
17
17
|
# # Log to screen
|
18
|
-
# SemanticLogger
|
18
|
+
# SemanticLogger.add_appender(STDOUT)
|
19
19
|
#
|
20
20
|
# # And log to a file at the same time
|
21
|
-
# SemanticLogger::Logger.
|
21
|
+
# SemanticLogger::Logger.add_appender('application.log')
|
22
22
|
#
|
23
|
-
# logger =
|
23
|
+
# logger = SemanticLogger['test']
|
24
24
|
# logger.info 'Hello World'
|
25
25
|
#
|
26
26
|
# Example 2. To log all levels to file and only :info and above to screen:
|
@@ -28,19 +28,19 @@ module SemanticLogger
|
|
28
28
|
# require 'semantic_logger'
|
29
29
|
#
|
30
30
|
# # Enable trace level logging
|
31
|
-
# SemanticLogger
|
31
|
+
# SemanticLogger.default_level = :trace
|
32
32
|
#
|
33
33
|
# # Log to screen but only display :info and above
|
34
|
-
# SemanticLogger
|
34
|
+
# SemanticLogger.add_appender(STDOUT, :info)
|
35
35
|
#
|
36
36
|
# # And log to a file at the same time, including all :trace level data
|
37
|
-
# SemanticLogger
|
37
|
+
# SemanticLogger.add_appender('application.log')
|
38
38
|
#
|
39
|
-
# logger = SemanticLogger
|
39
|
+
# logger = SemanticLogger['test']
|
40
40
|
# logger.info 'Hello World'
|
41
41
|
#
|
42
42
|
def initialize(filename, level=nil, &block)
|
43
|
-
raise "
|
43
|
+
raise "filename cannot be null when initializing the SemanticLogging::Appender::File" unless filename
|
44
44
|
@filename = filename
|
45
45
|
@log = if filename.respond_to?(:write) and filename.respond_to?(:close)
|
46
46
|
filename
|
@@ -13,22 +13,22 @@ module SemanticLogger
|
|
13
13
|
# require 'logger'
|
14
14
|
# require 'semantic_logger'
|
15
15
|
# ruby_logger = Logger.new(STDOUT)
|
16
|
-
# SemanticLogger
|
17
|
-
# logger = SemanticLogger
|
16
|
+
# SemanticLogger.add_appender(ruby_logger)
|
17
|
+
# logger = SemanticLogger['test']
|
18
18
|
# logger.info('Hello World', :some => :payload)
|
19
19
|
#
|
20
20
|
# Enhance the Rails Logger
|
21
21
|
# # Add the Rails logger to the list of appenders
|
22
|
-
# SemanticLogger
|
23
|
-
# Rails.logger = SemanticLogger
|
22
|
+
# SemanticLogger.add_appender(Rails.logger)
|
23
|
+
# Rails.logger = SemanticLogger['Rails']
|
24
24
|
#
|
25
25
|
# # Make ActiveRecord logging include its class name in every log entry
|
26
|
-
# ActiveRecord::Base.logger = SemanticLogger
|
26
|
+
# ActiveRecord::Base.logger = SemanticLogger['ActiveRecord']
|
27
27
|
#
|
28
28
|
# Note: Since the log level is controlled by setting the Ruby or Rails logger directly
|
29
29
|
# the level is ignored for this appender
|
30
30
|
def initialize(logger, &block)
|
31
|
-
raise "logger cannot be null when initiailizing the SemanticLogging::Appender::
|
31
|
+
raise "logger cannot be null when initiailizing the SemanticLogging::Appender::Wrapper" unless logger
|
32
32
|
@logger = logger
|
33
33
|
|
34
34
|
# Set the formatter to the supplied block
|
data/lib/semantic_logger/base.rb
CHANGED
@@ -17,9 +17,9 @@ module SemanticLogger
|
|
17
17
|
#
|
18
18
|
# Note: This level is only for this particular appender. It does not override
|
19
19
|
# the log level in any logging instance or the default log level
|
20
|
-
# SemanticLogger
|
20
|
+
# SemanticLogger.default_level
|
21
21
|
#
|
22
|
-
# Must be one of the values in SemanticLogger::
|
22
|
+
# Must be one of the values in SemanticLogger::LEVELS
|
23
23
|
def level=(level)
|
24
24
|
@level_index = self.class.map_level_to_index(level)
|
25
25
|
@level = level
|
@@ -51,15 +51,15 @@ module SemanticLogger
|
|
51
51
|
# require 'semantic_logger'
|
52
52
|
#
|
53
53
|
# # Enable trace level logging
|
54
|
-
# SemanticLogger
|
54
|
+
# SemanticLogger.default_level = :info
|
55
55
|
#
|
56
56
|
# # Log to screen
|
57
|
-
# SemanticLogger
|
57
|
+
# SemanticLogger.add_appender(STDOUT)
|
58
58
|
#
|
59
59
|
# # And log to a file at the same time
|
60
|
-
# SemanticLogger
|
60
|
+
# SemanticLogger.add_appender('application.log')
|
61
61
|
#
|
62
|
-
# logger = SemanticLogger
|
62
|
+
# logger = SemanticLogger['MyApplication']
|
63
63
|
# logger.debug("Only display this if log level is set to Debug or lower")
|
64
64
|
#
|
65
65
|
# # Log semantic information along with a text message
|
@@ -204,19 +204,16 @@ module SemanticLogger
|
|
204
204
|
|
205
205
|
# #TODO implement a thread safe #silence method
|
206
206
|
|
207
|
-
#
|
208
|
-
@@default_level = :info
|
209
|
-
|
210
|
-
# Allow for setting the global default log level
|
211
|
-
# This change only applies to _new_ loggers, existing logger levels
|
212
|
-
# will not be changed in any way
|
207
|
+
# DEPRECATED See SemanticLogger.default_level=
|
213
208
|
def self.default_level=(level)
|
214
|
-
|
209
|
+
warn "[DEPRECATION] `SemanticLogger::Logger.default_level=` is deprecated. Please use `SemanticLogger.default_level=` instead."
|
210
|
+
SemanticLogger.default_level = level
|
215
211
|
end
|
216
212
|
|
217
|
-
#
|
213
|
+
# DEPRECATED See SemanticLogger.default_level
|
218
214
|
def self.default_level
|
219
|
-
|
215
|
+
warn "[DEPRECATION] `SemanticLogger::Logger.default_level` is deprecated. Please use `SemanticLogger.default_level` instead."
|
216
|
+
SemanticLogger.default_level
|
220
217
|
end
|
221
218
|
|
222
219
|
############################################################################
|
@@ -224,7 +221,7 @@ module SemanticLogger
|
|
224
221
|
|
225
222
|
def initialize(klass, level=nil)
|
226
223
|
@name = klass.is_a?(String) ? klass : klass.name
|
227
|
-
self.level = level ||
|
224
|
+
self.level = level || SemanticLogger.default_level
|
228
225
|
end
|
229
226
|
|
230
227
|
# Write log data to underlying data storage
|
@@ -10,9 +10,11 @@ require 'sync_attr'
|
|
10
10
|
# Example
|
11
11
|
#
|
12
12
|
# require 'semantic_logger'
|
13
|
+
# SemanticLogger.default_level = :debug
|
14
|
+
# SemanticLogger.add_appender(STDOUT)
|
13
15
|
#
|
14
16
|
# class ExternalSupplier
|
15
|
-
# #
|
17
|
+
# # Create class and instance logger methods
|
16
18
|
# include SemanticLogger::Loggable
|
17
19
|
#
|
18
20
|
# def call_supplier(amount, name)
|
@@ -33,14 +35,64 @@ module SemanticLogger
|
|
33
35
|
include SyncAttr
|
34
36
|
|
35
37
|
sync_cattr_reader :logger do
|
36
|
-
SemanticLogger
|
38
|
+
SemanticLogger[self]
|
37
39
|
end
|
38
40
|
end
|
39
41
|
end
|
40
42
|
|
41
43
|
# Also make the logger available as an instance method MixIn
|
44
|
+
# The class logger can be replaced using an instance specific #logger= below
|
42
45
|
def logger
|
43
|
-
self.class.logger
|
46
|
+
@semantic_logger ||= self.class.logger
|
47
|
+
end
|
48
|
+
|
49
|
+
# Set instance specific logger
|
50
|
+
#
|
51
|
+
# By default instances of the class will use the class logger. Sometimes it
|
52
|
+
# is useful to be able to add instance specific logging data to the class name.
|
53
|
+
#
|
54
|
+
# For example, server or host_name that the class instance is using.
|
55
|
+
#
|
56
|
+
# Example:
|
57
|
+
# require 'semantic_logger'
|
58
|
+
# SemanticLogger.default_level = :debug
|
59
|
+
# SemanticLogger.add_appender(STDOUT)
|
60
|
+
#
|
61
|
+
# class MyClass
|
62
|
+
# include SemanticLogger::Loggable
|
63
|
+
#
|
64
|
+
# def self.my_name=(my_name)
|
65
|
+
# # Use class level logger that only logs class name
|
66
|
+
# logger.info "My name is changed to #{my_name}"
|
67
|
+
#
|
68
|
+
# @@my_name = my_name
|
69
|
+
# end
|
70
|
+
#
|
71
|
+
# def initialize(host_name)
|
72
|
+
# # Add host_name to every log entry in this logging instance
|
73
|
+
# self.logger = SemanticLogger["#{self.class.name} [#{host_name}]"]
|
74
|
+
#
|
75
|
+
# logger.info "Started server"
|
76
|
+
# end
|
77
|
+
#
|
78
|
+
# def check
|
79
|
+
# logger.debug "Checking..."
|
80
|
+
# end
|
81
|
+
# end
|
82
|
+
#
|
83
|
+
# MyClass.my_name = "Joe"
|
84
|
+
#
|
85
|
+
# mine = MyClass.new('server.com')
|
86
|
+
# mine.check
|
87
|
+
#
|
88
|
+
# # Generates the following log output:
|
89
|
+
#
|
90
|
+
# 2013-04-02 15:08:42.368574 I [37279:70198560687720] MyClass -- My name is changed to Joe
|
91
|
+
# 2013-04-02 15:08:42.369934 I [37279:70198560687720] MyClass [server.com] -- Started server
|
92
|
+
# 2013-04-02 15:08:42.371171 D [37279:70198560687720] MyClass [server.com] -- Checking...
|
93
|
+
#
|
94
|
+
def logger=(logger)
|
95
|
+
@semantic_logger = logger
|
44
96
|
end
|
45
97
|
|
46
98
|
end
|
@@ -1,43 +1,9 @@
|
|
1
1
|
require 'thread_safe'
|
2
2
|
|
3
|
-
# Logger
|
4
|
-
#
|
5
|
-
# Logger maintains the logging name to be used for all log entries generated
|
6
|
-
# by the invoking classes or modules
|
7
|
-
#
|
8
|
-
# It is recommended to create an instance of the class for every class or
|
9
|
-
# module so that it can be uniquely identified and searched on
|
10
|
-
#
|
11
|
-
# Example, log to Logger:
|
12
|
-
# require 'logger'
|
13
|
-
# require 'semantic_logger'
|
14
|
-
# log = Logger.new(STDOUT)
|
15
|
-
# log.level = Logger::DEBUG
|
16
|
-
#
|
17
|
-
# SemanticLogger::Logger.appenders << SemanticLogger::Appender::Logger.new(log)
|
18
|
-
#
|
19
|
-
# logger = SemanticLogger::Logger.new("my.app.class")
|
20
|
-
# logger.debug("Login time", :user => 'Joe', :duration => 100, :ip_address=>'127.0.0.1')
|
21
|
-
#
|
22
|
-
# # Now log to the Logger above as well as MongoDB at the same time
|
23
|
-
#
|
24
|
-
# db = Mongodb::Connection.new['production_logging']
|
25
|
-
#
|
26
|
-
# SemanticLogger::Logger.appenders << SemanticLogger::Appender::MongoDB.new(
|
27
|
-
# :db => db,
|
28
|
-
# :collection_size => 25.gigabytes
|
29
|
-
# )
|
30
|
-
# ...
|
31
|
-
# # This will be logged to both the Ruby Logger and MongoDB
|
32
|
-
# logger.debug("Login time", :user => 'Mary', :duration => 230, :ip_address=>'192.168.0.1')
|
33
|
-
#
|
3
|
+
# Logger stores the class name to be used for all log messages so that every
|
4
|
+
# log message written by this instance will include the class name
|
34
5
|
module SemanticLogger
|
35
6
|
class Logger < Base
|
36
|
-
# Add or remove logging appenders to the thread-safe appenders Array
|
37
|
-
# Appenders will be written to in the order that they appear in this list
|
38
|
-
def self.appenders
|
39
|
-
@@appenders
|
40
|
-
end
|
41
7
|
|
42
8
|
# Returns a Logger instance
|
43
9
|
#
|
@@ -53,11 +19,11 @@ module SemanticLogger
|
|
53
19
|
#
|
54
20
|
# level
|
55
21
|
# The initial log level to start with for this logger instance
|
56
|
-
# Default: SemanticLogger
|
22
|
+
# Default: SemanticLogger.default_level
|
57
23
|
#
|
58
24
|
def initialize(klass, level=nil)
|
59
25
|
@name = klass.is_a?(String) ? klass : klass.name
|
60
|
-
self.level = level ||
|
26
|
+
self.level = level || SemanticLogger.default_level
|
61
27
|
end
|
62
28
|
|
63
29
|
# Returns [Integer] the number of log entries that have not been written
|
@@ -71,12 +37,6 @@ module SemanticLogger
|
|
71
37
|
queue.size
|
72
38
|
end
|
73
39
|
|
74
|
-
# DEPRECATED: Please use queue_size instead.
|
75
|
-
def self.cache_count
|
76
|
-
warn "[DEPRECATION] 'SemanticLogger::Logger.cache_count' is deprecated. Please use 'SemanticLogger::Logger.queue_size' instead."
|
77
|
-
queue_size
|
78
|
-
end
|
79
|
-
|
80
40
|
# Flush all queued log entries disk, database, etc.
|
81
41
|
# All queued log messages are written and then each appender is flushed in turn
|
82
42
|
def self.flush
|
@@ -121,11 +81,21 @@ module SemanticLogger
|
|
121
81
|
@@logger = logger
|
122
82
|
end
|
123
83
|
|
84
|
+
# DEPRECATED See SemanticLogger.add_appender
|
85
|
+
def self.appenders
|
86
|
+
warn "[DEPRECATION] `SemanticLogger::Logger.appenders` is deprecated. Please use `SemanticLogger.add_appender` instead."
|
87
|
+
SemanticLogger.appenders
|
88
|
+
end
|
89
|
+
|
90
|
+
# DEPRECATED: Please use queue_size instead.
|
91
|
+
def self.cache_count
|
92
|
+
warn "[DEPRECATION] 'SemanticLogger::Logger.cache_count' is deprecated. Please use 'SemanticLogger::Logger.queue_size' instead."
|
93
|
+
queue_size
|
94
|
+
end
|
124
95
|
|
125
96
|
############################################################################
|
126
97
|
protected
|
127
98
|
|
128
|
-
@@appenders = ThreadSafe::Array.new
|
129
99
|
@@appender_thread = nil
|
130
100
|
@@queue = Queue.new
|
131
101
|
|
@@ -177,7 +147,7 @@ module SemanticLogger
|
|
177
147
|
count = 0
|
178
148
|
while message = queue.pop
|
179
149
|
if message.is_a? Log
|
180
|
-
appenders.each do |appender|
|
150
|
+
SemanticLogger.appenders.each do |appender|
|
181
151
|
begin
|
182
152
|
appender.log(message)
|
183
153
|
rescue Exception => exc
|
@@ -195,7 +165,7 @@ module SemanticLogger
|
|
195
165
|
else
|
196
166
|
case message[:command]
|
197
167
|
when :flush
|
198
|
-
appenders.each do |appender|
|
168
|
+
SemanticLogger.appenders.each do |appender|
|
199
169
|
begin
|
200
170
|
logger.info "Appender thread: Flushing appender: #{appender.name}"
|
201
171
|
appender.flush
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'thread_safe'
|
2
|
+
module SemanticLogger
|
3
|
+
# Logging levels in order of most detailed to most severe
|
4
|
+
LEVELS = [:trace, :debug, :info, :warn, :error, :fatal]
|
5
|
+
|
6
|
+
# Return a logger for the supplied class or class_name
|
7
|
+
def self.[](klass)
|
8
|
+
SemanticLogger::Logger.new(klass)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Allow for setting the global default log level
|
12
|
+
# This change only applies to _new_ loggers, existing logger levels
|
13
|
+
# will not be changed in any way
|
14
|
+
def self.default_level=(level)
|
15
|
+
@@default_level = level
|
16
|
+
end
|
17
|
+
|
18
|
+
# Returns the global default log level for new Logger instances
|
19
|
+
def self.default_level
|
20
|
+
@@default_level
|
21
|
+
end
|
22
|
+
|
23
|
+
# Add a new logging appender as a new destination for all log messages
|
24
|
+
# emitted from Semantic Logger
|
25
|
+
#
|
26
|
+
# Appenders will be written to in the order that they are added
|
27
|
+
#
|
28
|
+
# If a block is supplied then it will be used to customize the format
|
29
|
+
# of the messages sent to that appender. See SemanticLogger::Logger.new for
|
30
|
+
# more information on custom formatters
|
31
|
+
#
|
32
|
+
# Parameters
|
33
|
+
# appender [String|IO|SemanticLogger::Appender::Base|::Logger]
|
34
|
+
# Filename to write log messages to
|
35
|
+
# Or,
|
36
|
+
# STDOUT, STDERR, or any IO stream to write log messages to
|
37
|
+
# Or,
|
38
|
+
# Any SemanticLogger::Appender instance such as
|
39
|
+
# SemanticLogger::Appender::File
|
40
|
+
# SemanticLogger::Appender::Wrapper
|
41
|
+
# SemanticLogger::Appender::Mongodb
|
42
|
+
# Or,
|
43
|
+
# A custom appender derived from SemanticLogger::Appender::Base
|
44
|
+
# Or,
|
45
|
+
# Ruby built-in Logger, or any logger that implements the following methods:
|
46
|
+
# :debug, :info, :warn, :error, :fatal
|
47
|
+
#
|
48
|
+
# log_level [Symbol]
|
49
|
+
# Optional
|
50
|
+
# By setting the log_level higher than the SemanticLogger::default_level
|
51
|
+
# this appender can exclude lower level log messages
|
52
|
+
# Any one of SemanticLogger::LEVELS. For example: :trace, :debug, :info, :warn, :error, :fatal
|
53
|
+
#
|
54
|
+
# Examples:
|
55
|
+
#
|
56
|
+
# # Send all logging output to Standard Out (Screen)
|
57
|
+
# SemanticLogger.add_appender(STDOUT)
|
58
|
+
#
|
59
|
+
# # Send all logging output to a file
|
60
|
+
# SemanticLogger.add_appender('logfile.log')
|
61
|
+
#
|
62
|
+
# # Send all logging output to a file and only :info and above to standard output
|
63
|
+
# SemanticLogger.add_appender('logfile.log')
|
64
|
+
# SemanticLogger.add_appender(STDOUT, :info)
|
65
|
+
#
|
66
|
+
# Log to an existing logger:
|
67
|
+
#
|
68
|
+
# # Send Semantic logging output to an existing logger
|
69
|
+
# require 'logger'
|
70
|
+
# require 'semantic_logger'
|
71
|
+
#
|
72
|
+
# # Built-in Ruby logger
|
73
|
+
# log = Logger.new(STDOUT)
|
74
|
+
# log.level = Logger::DEBUG
|
75
|
+
#
|
76
|
+
# SemanticLogger.default_level = :debug
|
77
|
+
# SemanticLogger.add_appender(log)
|
78
|
+
#
|
79
|
+
# logger = SemanticLogger['Example']
|
80
|
+
# logger.info "Hello World"
|
81
|
+
# logger.debug("Login time", :user => 'Joe', :duration => 100, :ip_address=>'127.0.0.1')
|
82
|
+
#
|
83
|
+
def self.add_appender(appender, log_level=nil, &block)
|
84
|
+
appender_instance = if appender.is_a?(String) || appender.is_a?(IO)
|
85
|
+
# $stderr, STDOUT, other IO, or a filename
|
86
|
+
SemanticLogger::Appender::File.new(appender, log_level, &block)
|
87
|
+
elsif appender.is_a? Appender::Base
|
88
|
+
# Already an instance of an appender
|
89
|
+
appender.log_level = log_level if log_level
|
90
|
+
appender.formatter = block if block
|
91
|
+
appender
|
92
|
+
else
|
93
|
+
# Check if the custom appender responds to all the log levels. For example Ruby ::Logger
|
94
|
+
if does_not_implement = LEVELS[1..-1].find{|i| !appender.respond_to?(i)}
|
95
|
+
raise "Supplied appender does not implement:#{does_not_implement}. It must implement all of #{LEVELS[1..-1].inspect}"
|
96
|
+
end
|
97
|
+
|
98
|
+
raise "Change the log level to #{log_level}, update the log level directly against the supplied appender" if log_level
|
99
|
+
SemanticLogger::Appender::Wrapper.new(appender, &block)
|
100
|
+
end
|
101
|
+
@@appenders << appender_instance
|
102
|
+
end
|
103
|
+
|
104
|
+
# Remove an existing appender
|
105
|
+
# Currently only supports appender instances
|
106
|
+
# TODO allow removing by filename, STDOUT etc..
|
107
|
+
def self.remove_appender(appender)
|
108
|
+
@@appenders.delete(appender)
|
109
|
+
end
|
110
|
+
|
111
|
+
# Returns [SemanticLogger::Appender::Base] a copy of the list of active
|
112
|
+
# appenders for debugging etc.
|
113
|
+
# Use SemanticLogger.add_appender and SemanticLogger.remove_appender
|
114
|
+
# to manipulate the active appenders list
|
115
|
+
def self.appenders
|
116
|
+
@@appenders.dup
|
117
|
+
end
|
118
|
+
|
119
|
+
# Wait until all queued log messages have been written and flush all active
|
120
|
+
# appenders
|
121
|
+
def self.flush
|
122
|
+
SemanticLogger::Logger.flush
|
123
|
+
end
|
124
|
+
|
125
|
+
############################################################################
|
126
|
+
protected
|
127
|
+
|
128
|
+
@@appenders = ThreadSafe::Array.new
|
129
|
+
|
130
|
+
############################################################################
|
131
|
+
private
|
132
|
+
|
133
|
+
# Initial default Level for all new instances of SemanticLogger::Logger
|
134
|
+
@@default_level = :info
|
135
|
+
end
|