loggr 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|