loggr 1.0.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.
- data/.gitignore +5 -0
- data/Gemfile +4 -0
- data/LICENSES.md +15 -0
- data/MIT-LICENSE +20 -0
- data/README.md +230 -0
- data/Rakefile +14 -0
- data/lib/logback-classic-0.9.29.jar +0 -0
- data/lib/logback-core-0.9.29.jar +0 -0
- data/lib/loggr.rb +38 -0
- data/lib/loggr/adapter.rb +114 -0
- data/lib/loggr/adapter/abstract.rb +25 -0
- data/lib/loggr/adapter/base.rb +54 -0
- data/lib/loggr/adapter/buffered.rb +25 -0
- data/lib/loggr/adapter/nop.rb +39 -0
- data/lib/loggr/adapter/rails.rb +36 -0
- data/lib/loggr/adapter/slf4j.rb +30 -0
- data/lib/loggr/factory.rb +9 -0
- data/lib/loggr/lint.rb +54 -0
- data/lib/loggr/severity.rb +16 -0
- data/lib/loggr/slf4j.rb +7 -0
- data/lib/loggr/slf4j/jars.rb +44 -0
- data/lib/loggr/slf4j/logger.rb +88 -0
- data/lib/loggr/slf4j/mdc.rb +35 -0
- data/lib/loggr/version.rb +3 -0
- data/lib/slf4j-api-1.6.1.jar +0 -0
- data/loggr.gemspec +26 -0
- data/test/logback_helper.rb +54 -0
- data/test/test_helper.rb +50 -0
- data/test/unit/adapter/abstract_test.rb +12 -0
- data/test/unit/adapter/base_test.rb +65 -0
- data/test/unit/adapter/buffered_test.rb +44 -0
- data/test/unit/adapter/nop_test.rb +24 -0
- data/test/unit/adapter/rails_test.rb +38 -0
- data/test/unit/adapter/slf4j_test.rb +25 -0
- data/test/unit/factory_test.rb +60 -0
- data/test/unit/slf4j/jars_test.rb +22 -0
- data/test/unit/slf4j/logger_test.rb +139 -0
- data/test/unit/slf4j/mdc_test.rb +77 -0
- metadata +151 -0
@@ -0,0 +1,35 @@
|
|
1
|
+
module Loggr
|
2
|
+
module SLF4J
|
3
|
+
|
4
|
+
# Wrapper around the SLF4J MDC.
|
5
|
+
#
|
6
|
+
class MDCWrapper
|
7
|
+
|
8
|
+
# Access the original SLF4J MDC
|
9
|
+
attr_accessor :java_mdc
|
10
|
+
|
11
|
+
# Create a new SLF4J MDC with the supplied implementation.
|
12
|
+
def initialize(impl = Java::OrgSlf4j::MDC)
|
13
|
+
@java_mdc = impl
|
14
|
+
end
|
15
|
+
|
16
|
+
# Read a key from the MDC.
|
17
|
+
def [](key); java_mdc.get(key.to_s) end
|
18
|
+
|
19
|
+
# Write a value to the MDC.
|
20
|
+
def []=(key, value); java_mdc.put(key.to_s, value.to_s) end
|
21
|
+
|
22
|
+
# Remove a key from the MDC.
|
23
|
+
def delete(key); java_mdc.remove(key.to_s) end
|
24
|
+
|
25
|
+
# Clear all keys from the MDC.
|
26
|
+
def clear; java_mdc.clear() end
|
27
|
+
|
28
|
+
# Convert MDC to a real hash.
|
29
|
+
def to_hash; java_mdc.getCopyOfContextMap().freeze end
|
30
|
+
end
|
31
|
+
|
32
|
+
# An instance is available as MDC :)
|
33
|
+
MDC = MDCWrapper.new
|
34
|
+
end
|
35
|
+
end
|
Binary file
|
data/loggr.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "loggr/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "loggr"
|
7
|
+
s.version = Loggr::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.summary = 'Logger factory framework (including an SLF4J wrapper)'
|
10
|
+
s.description = 'Adapters for different ruby logging backends. Create loggers using different adapters, like Logger (Stdlib), Rails or SLF4J (in JRuby only).'
|
11
|
+
|
12
|
+
s.required_ruby_version = ">= 1.8.7"
|
13
|
+
s.required_rubygems_version = ">= 1.3.6"
|
14
|
+
|
15
|
+
s.authors = ["Lukas Westermann"]
|
16
|
+
s.email = ["lukas@at-point.ch"]
|
17
|
+
s.homepage = "https://github.com/at-point/loggr/wiki"
|
18
|
+
|
19
|
+
s.files = `git ls-files`.split("\n")
|
20
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
21
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
22
|
+
s.require_path = 'lib'
|
23
|
+
|
24
|
+
s.add_development_dependency "minitest", ">= 2.3.0"
|
25
|
+
s.add_development_dependency "activesupport", ">= 3.0.0"
|
26
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
if RUBY_PLATFORM =~ /java/
|
2
|
+
require 'java'
|
3
|
+
require 'loggr/slf4j/jars'
|
4
|
+
Loggr::SLF4J::Jars.require_slf4j_jars!
|
5
|
+
|
6
|
+
class ArrayAppender
|
7
|
+
include Java::ChQosLogbackCore::Appender
|
8
|
+
|
9
|
+
attr_reader :events
|
10
|
+
attr_accessor :name
|
11
|
+
|
12
|
+
def initialize(name = 'ArrayAppender')
|
13
|
+
@mutex = Mutex.new
|
14
|
+
@name = name
|
15
|
+
@events = []
|
16
|
+
end
|
17
|
+
|
18
|
+
alias_method :setName, :name=
|
19
|
+
alias_method :getName, :name
|
20
|
+
|
21
|
+
def doAppend(event)
|
22
|
+
@mutex.synchronize { @events.push(event) }
|
23
|
+
end
|
24
|
+
|
25
|
+
def stop
|
26
|
+
end
|
27
|
+
|
28
|
+
def last
|
29
|
+
@events.last
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class MiniTest::Unit::TestCase
|
35
|
+
# Configures logback for testing et al.
|
36
|
+
def setup_logback!
|
37
|
+
if RUBY_PLATFORM =~ /java/
|
38
|
+
@appender = ArrayAppender.new
|
39
|
+
|
40
|
+
Java::OrgSlf4j::MDC.clear()
|
41
|
+
logger_context = Java::OrgSlf4j::LoggerFactory.getILoggerFactory()
|
42
|
+
root_logger = logger_context.getLogger(Java::OrgSlf4j::Logger::ROOT_LOGGER_NAME)
|
43
|
+
root_logger.detachAndStopAllAppenders()
|
44
|
+
root_logger.addAppender(@appender)
|
45
|
+
root_logger.setLevel(Java::ChQosLogbackClassic::Level::ALL)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Verifies log event based on level & message
|
50
|
+
def assert_log_event(exp_level, exp_message, event)
|
51
|
+
assert_equal exp_level, event.getLevel().toInt()
|
52
|
+
assert_equal exp_message, event.getFormattedMessage()
|
53
|
+
end
|
54
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
require 'tempfile'
|
4
|
+
|
5
|
+
# Just to provide some shim ;)
|
6
|
+
module Loggr
|
7
|
+
module SLF4J
|
8
|
+
end
|
9
|
+
module Adapter
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class MiniTest::Unit::TestCase
|
14
|
+
|
15
|
+
# Path to root
|
16
|
+
ROOT = File.dirname(File.dirname(__FILE__))
|
17
|
+
|
18
|
+
# Returns `true` if running in java/jruby
|
19
|
+
def self.jruby?; !!(RUBY_PLATFORM =~ /java/) end
|
20
|
+
|
21
|
+
# Same at instance level
|
22
|
+
def jruby?; self.class.jruby? end
|
23
|
+
|
24
|
+
# Yield block if java
|
25
|
+
def if_jruby(&block)
|
26
|
+
yield if block_given? && jruby?
|
27
|
+
end
|
28
|
+
|
29
|
+
# Skip tests, unless using jruby
|
30
|
+
def skip_unless_jruby
|
31
|
+
skip("requires JRuby") unless jruby?
|
32
|
+
end
|
33
|
+
|
34
|
+
# Yields path to tempfile into block, ensures is cleaned up
|
35
|
+
# afterwards
|
36
|
+
def with_tempfile(name = 'file', &block)
|
37
|
+
tempfile = Tempfile.new(name)
|
38
|
+
yield(tempfile.path) if block_given?
|
39
|
+
tempfile.close
|
40
|
+
ensure
|
41
|
+
tempfile.unlink
|
42
|
+
end
|
43
|
+
|
44
|
+
# Ensure all log files are unlinked after block
|
45
|
+
def unlink_log_files(&block)
|
46
|
+
yield if block_given?
|
47
|
+
ensure
|
48
|
+
Dir[File.join(File.dirname(File.dirname(__FILE__))), '*.log'].each { |f| File.unlink(f) if f =~ /\.log$/ }
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'loggr/adapter/abstract'
|
3
|
+
|
4
|
+
class Loggr::Adapter::AbstractTest < MiniTest::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@adapter = Loggr::Adapter::AbstractAdapter.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_logger_must_be_implemented_and_thus_throws_exception
|
10
|
+
assert_raises(RuntimeError) { @adapter.logger("logger") }
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'loggr/lint'
|
3
|
+
require 'loggr/adapter/base'
|
4
|
+
|
5
|
+
module ATestModule
|
6
|
+
class ATestClass
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class Loggr::Adapter::BaseTest < MiniTest::Unit::TestCase
|
11
|
+
def setup
|
12
|
+
@adapter = Loggr::Adapter::BaseAdapter.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def teardown
|
16
|
+
unlink_log_files
|
17
|
+
end
|
18
|
+
|
19
|
+
include Loggr::Lint::Tests
|
20
|
+
|
21
|
+
def test_base_should_be_a_base_adapter
|
22
|
+
assert Loggr::Adapter::Base.is_a?(Loggr::Adapter::BaseAdapter)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_logger_instance_should_be_a_stdlib_logger_with_level_info
|
26
|
+
@logger = @adapter.logger 'test'
|
27
|
+
assert_kind_of ::Logger, @logger
|
28
|
+
assert_same ::Logger::INFO, @logger.level
|
29
|
+
assert_equal 'test', @logger.progname
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_logger_should_use_name_as_path
|
33
|
+
@logger = @adapter.logger 'test'
|
34
|
+
assert File.exist?(File.join(ROOT, 'test.log')), "./test.log should exist"
|
35
|
+
|
36
|
+
@logger = @adapter.logger 'test name'
|
37
|
+
assert File.exist?(File.join(ROOT, 'test_name.log')), "./test_name.log should exist"
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_logger_should_use_class_name_as_name
|
41
|
+
@logger = @adapter.logger self
|
42
|
+
assert File.exist?(File.join(ROOT, 'Loggr_Adapter_BaseTest.log')), "./Loggr_Adapter_BaseTest.log should exist"
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_should_allow_to_option_to_provide_path
|
46
|
+
@logger = @adapter.logger 'test', :to => "other.log"
|
47
|
+
assert File.exist?(File.join(ROOT, 'other.log')), "./other.log should exist"
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_should_setting_level_via_options
|
51
|
+
@logger = @adapter.logger 'test', :level => ::Logger::ERROR
|
52
|
+
assert_same ::Logger::ERROR, @logger.level
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_normalize_name_converts_all_inputs_to_sane_strings
|
56
|
+
assert_equal "logger", @adapter.send(:normalize_name, "logger")
|
57
|
+
assert_equal "logger", @adapter.send(:normalize_name, :logger)
|
58
|
+
assert_equal "Loggr::Logger", @adapter.send(:normalize_name, "Loggr::Logger")
|
59
|
+
assert_equal "Loggr::Adapter", @adapter.send(:normalize_name, Loggr::Adapter)
|
60
|
+
assert_equal "Loggr::Adapter::BaseTest", @adapter.send(:normalize_name, self)
|
61
|
+
assert_equal "ATestModule", @adapter.send(:normalize_name, ATestModule)
|
62
|
+
assert_equal "ATestModule::ATestClass", @adapter.send(:normalize_name, ATestModule::ATestClass)
|
63
|
+
assert_equal "ATestModule::ATestClass", @adapter.send(:normalize_name, ATestModule::ATestClass.new)
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'loggr/lint'
|
3
|
+
require 'loggr/adapter/buffered'
|
4
|
+
|
5
|
+
class Loggr::Adapter::BufferedTest < MiniTest::Unit::TestCase
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@adapter = Loggr::Adapter::BufferedAdapter.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def teardown
|
12
|
+
unlink_log_files
|
13
|
+
end
|
14
|
+
|
15
|
+
include Loggr::Lint::Tests
|
16
|
+
|
17
|
+
def test_buffered_should_be_a_buffered_adapter
|
18
|
+
assert_kind_of Loggr::Adapter::BufferedAdapter, Loggr::Adapter::Buffered
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_logger_instance_should_be_a_buffered_logger_with_level_debug
|
22
|
+
@logger = @adapter.logger 'test'
|
23
|
+
assert_kind_of ActiveSupport::BufferedLogger, @logger
|
24
|
+
assert_same ActiveSupport::BufferedLogger::INFO, @logger.level
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_logger_should_use_name_as_path
|
28
|
+
@logger = @adapter.logger 'test'
|
29
|
+
assert File.exist?(File.join(ROOT, 'test.log')), "./test.log should not exist"
|
30
|
+
|
31
|
+
@logger = @adapter.logger 'test name'
|
32
|
+
assert File.exist?(File.join(ROOT, 'test_name.log')), "./test_name.log should not exist"
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_should_allow_to_option_to_provide_path
|
36
|
+
@logger = @adapter.logger 'test', :to => "other.log"
|
37
|
+
assert File.exist?(File.join(ROOT, 'other.log')), "./other.log should not exist"
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_should_setting_level_via_options
|
41
|
+
@logger = @adapter.logger 'test', :level => ActiveSupport::BufferedLogger::ERROR
|
42
|
+
assert_same ActiveSupport::BufferedLogger::ERROR, @logger.level
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'loggr/lint'
|
3
|
+
require 'loggr/adapter/nop'
|
4
|
+
|
5
|
+
class Loggr::Adapter::NOPTest < MiniTest::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@adapter = Loggr::Adapter::NOPAdapter.new
|
8
|
+
end
|
9
|
+
|
10
|
+
include Loggr::Lint::Tests
|
11
|
+
|
12
|
+
def test_nop_should_be_a_nop_adapter
|
13
|
+
assert_kind_of Loggr::Adapter::NOPAdapter, Loggr::Adapter::NOP
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_nop_should_not_write_any_files
|
17
|
+
with_tempfile do |file|
|
18
|
+
logger = @adapter.logger('nop', :to => file)
|
19
|
+
logger.error "oops, i failed?"
|
20
|
+
logger.close
|
21
|
+
assert File.read(file).length == 0, "Nop logger should not log anything at all, wtf!"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'logger'
|
3
|
+
require 'loggr/lint'
|
4
|
+
require 'loggr/adapter'
|
5
|
+
require 'loggr/adapter/rails'
|
6
|
+
|
7
|
+
# mock Rails
|
8
|
+
module MockRails
|
9
|
+
def self.logger
|
10
|
+
@logger ||= ::Logger.new('/dev/null')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Loggr::Adapter::RailsTest < MiniTest::Unit::TestCase
|
15
|
+
def setup
|
16
|
+
Object.send(:remove_const, :Rails) if Object.const_defined?(:Rails)
|
17
|
+
Object.const_set(:Rails, ::MockRails)
|
18
|
+
@adapter = Loggr::Adapter::RailsAdapter.new
|
19
|
+
end
|
20
|
+
|
21
|
+
include Loggr::Lint::Tests
|
22
|
+
|
23
|
+
def test_rails_should_be_a_rails_adapter
|
24
|
+
assert_kind_of Loggr::Adapter::RailsAdapter, Loggr::Adapter::Rails
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_should_use_same_logger_as_rails
|
28
|
+
assert_equal ::Rails.logger, Loggr::Adapter::Rails.logger('log')
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_should_default_to_rails_adapter
|
32
|
+
clazz = Class.new do
|
33
|
+
extend Loggr::Adapter
|
34
|
+
end
|
35
|
+
|
36
|
+
assert_equal Loggr::Adapter::Rails, clazz.adapter
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'loggr/lint'
|
3
|
+
require 'loggr/adapter'
|
4
|
+
|
5
|
+
class Loggr::Adapter::SLF4JTest < MiniTest::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
setup_logback!
|
8
|
+
if_jruby do
|
9
|
+
require 'loggr/adapter/slf4j'
|
10
|
+
@adapter = Loggr::Adapter::SLF4JAdapter.new
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_lint
|
15
|
+
skip_unless_jruby
|
16
|
+
pass "include Loggr::Lint::Tests"
|
17
|
+
end
|
18
|
+
|
19
|
+
include(Loggr::Lint::Tests) if jruby?
|
20
|
+
|
21
|
+
def test_slf4j_should_be_a_slf4j_adapter
|
22
|
+
skip_unless_jruby
|
23
|
+
assert Loggr::Adapter::SLF4J.is_a?(Loggr::Adapter::SLF4JAdapter)
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'loggr/lint'
|
3
|
+
require 'loggr/adapter'
|
4
|
+
require 'loggr/adapter/base'
|
5
|
+
require 'loggr/factory'
|
6
|
+
|
7
|
+
class MockInstanceFactory
|
8
|
+
include Loggr::Adapter
|
9
|
+
end
|
10
|
+
|
11
|
+
module Mocks
|
12
|
+
class MyAdapter < Loggr::Adapter::BaseAdapter; end
|
13
|
+
end
|
14
|
+
|
15
|
+
class Loggr::FactoryTest < MiniTest::Unit::TestCase
|
16
|
+
def setup
|
17
|
+
Object.send(:remove_const, :Rails) if Object.const_defined?(:Rails)
|
18
|
+
@factory = MockInstanceFactory.new
|
19
|
+
@adapter = LoggerFactory # lint it!
|
20
|
+
@adapter.adapter = Loggr::Adapter::Base
|
21
|
+
end
|
22
|
+
|
23
|
+
def teardown
|
24
|
+
unlink_log_files
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_default_adapter_is_base
|
28
|
+
assert_equal @factory.adapter, Loggr::Adapter::Base
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_change_adapter_using_symbol
|
32
|
+
@factory.adapter = :buffered
|
33
|
+
assert_equal @factory.adapter, Loggr::Adapter::Buffered
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_change_adapter_to_slf4j_using_symbol
|
37
|
+
skip_unless_jruby
|
38
|
+
@factory.adapter = :slf4j
|
39
|
+
assert_equal @factory.adapter, Loggr::Adapter::SLF4J
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_change_adapter_using_string
|
43
|
+
@factory.adapter = 'NOP'
|
44
|
+
assert_equal @factory.adapter, Loggr::Adapter::NOP
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_change_adapter_to_instance
|
48
|
+
@factory.adapter = Mocks::MyAdapter.new
|
49
|
+
assert_kind_of Mocks::MyAdapter, @factory.adapter
|
50
|
+
end
|
51
|
+
|
52
|
+
# Lint LoggerFactory, should work the same as an adapter
|
53
|
+
include Loggr::Lint::Tests
|
54
|
+
|
55
|
+
# Ensure class
|
56
|
+
def test_logger_factory
|
57
|
+
singleton_class = (class << LoggerFactory; self end)
|
58
|
+
assert singleton_class.included_modules.include?(Loggr::Adapter), "LoggerFactory should extend Loggr::Adapter"
|
59
|
+
end
|
60
|
+
end
|