semantic_logger 0.4.2 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +1 -1
- data/lib/semantic_logger/appender/file.rb +83 -0
- data/lib/semantic_logger/logger.rb +12 -9
- data/lib/semantic_logger/railtie.rb +37 -22
- data/lib/semantic_logger/version.rb +1 -1
- data/lib/semantic_logger.rb +1 -0
- data/test/logger_test.rb +2 -1
- metadata +5 -4
data/README.md
CHANGED
@@ -437,7 +437,7 @@ Reid Morrison :: reidmo@gmail.com :: @reidmorrison
|
|
437
437
|
License
|
438
438
|
-------
|
439
439
|
|
440
|
-
Copyright
|
440
|
+
Copyright 2012 Clarity Services, Inc.
|
441
441
|
|
442
442
|
Licensed under the Apache License, Version 2.0 (the "License");
|
443
443
|
you may not use this file except in compliance with the License.
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# File appender
|
2
|
+
#
|
3
|
+
# Writes log messages to a file or open iostream
|
4
|
+
#
|
5
|
+
module SemanticLogger
|
6
|
+
module Appender
|
7
|
+
class File
|
8
|
+
attr_accessor :formatter
|
9
|
+
|
10
|
+
# Create a File Logger appender instance
|
11
|
+
#
|
12
|
+
# Example
|
13
|
+
# require 'semantic_logger'
|
14
|
+
#
|
15
|
+
# # Log to screen
|
16
|
+
# SemanticLogger::Logger.appenders << SemanticLogger::Appender::File.new(STDOUT)
|
17
|
+
#
|
18
|
+
# # And log to a file at the same time
|
19
|
+
# SemanticLogger::Logger.appenders << SemanticLogger::Appender::File.new('application.log')
|
20
|
+
#
|
21
|
+
# logger = SemanticLogger::Logger.new('test')
|
22
|
+
# logger.info 'Hello World'
|
23
|
+
#
|
24
|
+
def initialize(filename, &block)
|
25
|
+
raise "logger cannot be null when initializing the SemanticLogging::Appender::Logger" unless filename
|
26
|
+
@filename = filename
|
27
|
+
@log = if filename.respond_to?(:write) and filename.respond_to?(:close)
|
28
|
+
filename
|
29
|
+
else
|
30
|
+
@log = open(filename, (::File::WRONLY | ::File::APPEND | ::File::CREAT))
|
31
|
+
# Force all log entries to write immediately without buffering
|
32
|
+
@log.sync = true
|
33
|
+
@log.set_encoding(Encoding::BINARY) if @log.respond_to?(:set_encoding)
|
34
|
+
@log
|
35
|
+
end
|
36
|
+
|
37
|
+
# Set the formatter to the supplied block
|
38
|
+
@formatter = block || self.default_formatter
|
39
|
+
end
|
40
|
+
|
41
|
+
# Default log formatter
|
42
|
+
# Replace this formatter by supplying a Block to the initializer
|
43
|
+
# Generates logs of the form:
|
44
|
+
# 2011-07-19 14:36:15.660 D [1149:ScriptThreadProcess] Rails -- Hello World\n
|
45
|
+
def default_formatter
|
46
|
+
Proc.new do |log|
|
47
|
+
message = log.message.to_s
|
48
|
+
tags = log.tags.collect { |tag| "[#{tag}]" }.join(" ") + " " if log.tags && (log.tags.size > 0)
|
49
|
+
|
50
|
+
if log.payload
|
51
|
+
if log.payload.is_a?(Exception)
|
52
|
+
exception = log.payload
|
53
|
+
message << " -- " << "#{exception.class}: #{exception.message}\n#{(exception.backtrace || []).join("\n")}"
|
54
|
+
else
|
55
|
+
message << " -- " << log.payload.inspect
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
str = "#{log.time.strftime("%Y-%m-%d %H:%M:%S")}.#{"%03d" % (log.time.usec/1000)} #{log.level.to_s[0..0].upcase} [#{$$}:#{log.thread_name}] #{tags}#{log.name} -- #{message}"
|
60
|
+
str << " (#{'%.1f' % log.duration}ms)" if log.duration
|
61
|
+
str << "\n"
|
62
|
+
str
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Pass log calls to the underlying Rails, log4j or Ruby logger
|
67
|
+
# trace entries are mapped to debug since :trace is not supported by the
|
68
|
+
# Ruby or Rails Loggers
|
69
|
+
def log(log)
|
70
|
+
# Since only one appender thread will be writing to the file at a time
|
71
|
+
# it is not necessary to protect access to the file with a semaphore
|
72
|
+
@log.write(@formatter.call(log))
|
73
|
+
end
|
74
|
+
|
75
|
+
# Flush all pending logs to disk.
|
76
|
+
# Waits for all sent documents to be writted to disk
|
77
|
+
def flush
|
78
|
+
@log.flush if @log.respond_to?(:flush)
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -29,6 +29,7 @@
|
|
29
29
|
# # This will be logged to both the Ruby Logger and MongoDB
|
30
30
|
# logger.debug("Login time", :user => 'Mary', :duration => 230, :ip_address=>'192.168.0.1')
|
31
31
|
#
|
32
|
+
require 'logger'
|
32
33
|
module SemanticLogger
|
33
34
|
class Logger
|
34
35
|
include SyncAttr
|
@@ -47,18 +48,21 @@ module SemanticLogger
|
|
47
48
|
[]
|
48
49
|
end
|
49
50
|
|
50
|
-
# Allow for setting the default log level
|
51
|
-
|
52
|
-
|
51
|
+
# Allow for setting the global default log level
|
52
|
+
# This change only applies to _new_ loggers, existing logger levels
|
53
|
+
# will not be changed in any way
|
54
|
+
def self.level=(level)
|
55
|
+
@@level = level
|
53
56
|
end
|
54
57
|
|
55
|
-
|
56
|
-
|
58
|
+
# Returns the global default log level for new Logger instances
|
59
|
+
def self.level
|
60
|
+
@@level
|
57
61
|
end
|
58
62
|
|
59
63
|
attr_reader :name, :level
|
60
64
|
|
61
|
-
@@
|
65
|
+
@@level = :info
|
62
66
|
|
63
67
|
# Returns a Logger instance
|
64
68
|
#
|
@@ -74,7 +78,7 @@ module SemanticLogger
|
|
74
78
|
# :level The initial log level to start with for this logger instance
|
75
79
|
def initialize(klass, options={})
|
76
80
|
@name = klass.is_a?(String) ? klass : klass.name
|
77
|
-
set_level(options[:level] || self.class.
|
81
|
+
set_level(options[:level] || self.class.level)
|
78
82
|
end
|
79
83
|
|
80
84
|
# Set the logging level
|
@@ -239,8 +243,7 @@ module SemanticLogger
|
|
239
243
|
# Warning: Do not use this logger directly it is intended for internal logging
|
240
244
|
# within Semantic Logger itself
|
241
245
|
sync_cattr_accessor :logger do
|
242
|
-
|
243
|
-
l = ::Logger.new(STDOUT)
|
246
|
+
l = ::Logger.new(STDERR)
|
244
247
|
l.level = ::Logger::INFO
|
245
248
|
l
|
246
249
|
end
|
@@ -26,17 +26,42 @@ module SemanticLogger #:nodoc:
|
|
26
26
|
initializer :initialize_semantic_logger, :before => :initialize_logger do
|
27
27
|
config = Rails.application.config
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
29
|
+
# Set the default log level based on the Rails config
|
30
|
+
SemanticLogger::Logger.level = config.log_level
|
31
|
+
|
32
|
+
# Also log to any pre-existing loggers with SymanticLogger
|
33
|
+
if existing_logger = (Rails.logger || config.logger)
|
34
|
+
# Add existing Logger to the list of appenders
|
35
|
+
SemanticLogger::Logger.appenders << SemanticLogger::Appender::Logger.new(existing_logger)
|
36
|
+
end
|
37
|
+
|
38
|
+
Rails.logger = config.logger = begin
|
39
|
+
# First check for Rails 3.2 path, then fallback to pre-3.2
|
40
|
+
path = ((config.paths.log.to_a rescue nil) || config.paths['log']).first
|
41
|
+
unless File.exist? File.dirname path
|
42
|
+
FileUtils.mkdir_p File.dirname path
|
43
|
+
end
|
44
|
+
|
45
|
+
# First set the internal logger in case something goes wrong
|
46
|
+
# with an appender
|
47
|
+
SemanticLogger::Logger.logger = begin
|
48
|
+
l = ::Logger.new(path)
|
49
|
+
l.level = ::Logger.const_get(config.log_level.to_s.upcase)
|
50
|
+
l
|
51
|
+
end
|
52
|
+
|
53
|
+
# Add the log file to the list of appenders
|
54
|
+
SemanticLogger::Logger.appenders << SemanticLogger::Appender::File.new(path)
|
55
|
+
|
56
|
+
#logger = ActiveSupport::TaggedLogging.new(logger) if defined?(ActiveSupport::TaggedLogging)
|
57
|
+
|
58
|
+
SemanticLogger::Logger.new(Rails)
|
59
|
+
rescue StandardError
|
60
|
+
SemanticLogger::Logger.appenders << SemanticLogger::Appender::File.new(STDERR)
|
61
|
+
|
62
|
+
logger = SemanticLogger::Logger.new(Rails)
|
63
|
+
logger.level = :warn
|
64
|
+
#logger = ActiveSupport::TaggedLogging.new(logger) if defined?(ActiveSupport::TaggedLogging)
|
40
65
|
logger.warn(
|
41
66
|
"Rails Error: Unable to access log file. Please ensure that #{path} exists and is chmod 0666. " +
|
42
67
|
"The log level has been raised to WARN and the output directed to STDERR until the problem is fixed."
|
@@ -44,18 +69,8 @@ module SemanticLogger #:nodoc:
|
|
44
69
|
logger
|
45
70
|
end
|
46
71
|
|
47
|
-
#
|
48
|
-
# with an appender
|
49
|
-
SemanticLogger::Logger.logger = logger
|
50
|
-
|
51
|
-
# Add the Rails Logger to the list of appenders
|
52
|
-
SemanticLogger::Logger.appenders << SemanticLogger::Appender::Logger.new(logger)
|
53
|
-
|
54
|
-
# Set the default log level based on the Rails config
|
55
|
-
SemanticLogger::Logger.default_level = config.log_level
|
56
|
-
|
72
|
+
# #TODO Should these be moved?
|
57
73
|
# Replace the default Rails loggers
|
58
|
-
Rails.logger = config.logger = SemanticLogger::Logger.new(Rails)
|
59
74
|
if defined?(ActiveRecord::Base)
|
60
75
|
ActiveRecord::Base.logger = SemanticLogger::Logger.new(ActiveRecord)
|
61
76
|
end
|
data/lib/semantic_logger.rb
CHANGED
@@ -5,6 +5,7 @@ module SemanticLogger
|
|
5
5
|
autoload :Logger, 'semantic_logger/logger'
|
6
6
|
|
7
7
|
module Appender
|
8
|
+
autoload :File, 'semantic_logger/appender/file'
|
8
9
|
autoload :Logger, 'semantic_logger/appender/logger'
|
9
10
|
# Only load the MongoDB appender if the Mongo Ruby Driver is loaded
|
10
11
|
autoload :MongoDB, 'semantic_logger/appender/mongodb'
|
data/test/logger_test.rb
CHANGED
@@ -59,9 +59,10 @@ class LoggerTest < Test::Unit::TestCase
|
|
59
59
|
|
60
60
|
should "add payload to log entries" do
|
61
61
|
@logger.with_payload(:tracking_number => '123456') do
|
62
|
-
@logger.with_payload(:
|
62
|
+
@logger.with_payload(:even => 2, :more => 'data') do
|
63
63
|
@logger.info('Hello world')
|
64
64
|
SemanticLogger::Logger.flush
|
65
|
+
# TODO make test ignore order of Hash elements
|
65
66
|
assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ \w \[\d+:.+\] LoggerTest -- Hello world -- \{:even=>2, :more=>\"data\", :tracking_number=>\"123456\"\}/, @mock_logger.message
|
66
67
|
end
|
67
68
|
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 5
|
8
|
+
- 0
|
9
|
+
version: 0.5.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Reid Morrison
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2012-09-
|
17
|
+
date: 2012-09-11 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -53,6 +53,7 @@ extra_rdoc_files: []
|
|
53
53
|
files:
|
54
54
|
- FUTURE.rb
|
55
55
|
- init.txt
|
56
|
+
- lib/semantic_logger/appender/file.rb
|
56
57
|
- lib/semantic_logger/appender/logger.rb
|
57
58
|
- lib/semantic_logger/appender/mongodb.rb
|
58
59
|
- lib/semantic_logger/logger.rb
|