gem_logger 0.1.0 → 0.2.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 CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ZTIzNzQ0NzlhNDdlMjkzMDk5NDM1ZTBjZWU3NmYxN2ZmMzhmNWQ1OQ==
5
- data.tar.gz: !binary |-
6
- MmFkOTczODI3NGFjZTczNWEzOTk2OTU4N2Q4MWY2ZDdmYTgyYTBkMQ==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- YmU1OWJkMTFmMTg5MWExNDYwMzJjOWQ2OWM4N2ViZTI1ZDU3ZDQyM2MzOTc4
10
- ZDBlZGVjODBhMGIwNTk3MmM0NzFkNGNjMTZlNTcxMGJmMTBkZWU4MTI0ZjYy
11
- OTE1NDBlYzRiNjZhYmJiZWU2MDA0MmYxY2U2OGVjZjgwZjU1MzA=
12
- data.tar.gz: !binary |-
13
- MzYzZmMxYzAzYTZjOTRmNjUyOWI4YWY5NGRjYjZiNDhiNzM2OTdhMDAwNzdk
14
- NzI4ZDhkZGY5OTBhZWY2MDI4ZjdlY2E2MzNiNzNlYzFhYzc0ZjljM2YxZGIx
15
- NWEzODBlZDcxY2FkMTQ5MzQxNTlhNjdlYjc4Njc1NTI1ODMwMGY=
2
+ SHA1:
3
+ metadata.gz: cac9834fee2a3e0b443c0385601b22831093517f
4
+ data.tar.gz: 312e92da1a677e310c80b02b42ccb94cce8cfa52
5
+ SHA512:
6
+ metadata.gz: 31460132ab3adec8fa05f3457cdf1b39629b7870aa86a5f3a619e43661afeb66f11b0f94cb55e7a13a50089e8e0c51637c3112456b64201ea6ef4f652eb5db53
7
+ data.tar.gz: 09e7ed4a79a2ee5ab9e5cb45e8781b021cfd249148a21f6d99883a1dd98fe453b41f83275058de4f6092596850b5107613070b28e805cfdd352c890a250c85bb
data/.gitignore CHANGED
@@ -15,3 +15,4 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ /.idea
data/.travis.yml CHANGED
@@ -2,7 +2,12 @@ language: ruby
2
2
  rvm:
3
3
  - 1.9.3
4
4
  - 2.0.0
5
+ - 2.1.1
5
6
  - jruby-19mode
6
- - rbx-19mode
7
+ - rbx
7
8
 
8
9
  script: bundle exec rake
10
+
11
+ matrix:
12
+ allow_failures:
13
+ - rvm: rbx
data/Gemfile CHANGED
@@ -2,9 +2,10 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in gem_logger.gemspec
4
4
  gemspec
5
-
6
5
  # so we can test GemLogger.logger_concern
7
6
  gem "lumber", :require => false
8
7
 
9
8
  # for code coverage during travis-ci test runs
10
9
  gem 'coveralls', :require => false
10
+
11
+ gem "mocha", :require => false
data/README.md CHANGED
@@ -21,3 +21,29 @@ Include the GemLogger::Logger concern into the classes that need to be able to l
21
21
 
22
22
  end
23
23
 
24
+ ## Context
25
+
26
+ It is also possible to add context to your log messages through the context call:
27
+
28
+ MyClass.logger.context(:key => 'value').debug("I want context here")
29
+
30
+ as well as include backtraces and context to exceptions by calling the log_exception method with the error and a custom message:
31
+
32
+ MyClass.logger.log_exception(StandardError.new('uh oh'), 'This is bad')
33
+
34
+ By default, log_exception uses the ERROR level, but also accepts a level as an option:
35
+
36
+ MyClass.logger.log_exception(StandardError.new('uh oh'), 'This is bad', {:level => :debug})
37
+
38
+ Unless otherwise specified, the context is added to the beginning of the log message in a basic key = value format. You can, however, define your own context handler, and pass it in on initialization:
39
+
40
+ GemLogger.configure do |config| do
41
+ config.context_handler = MyHandler
42
+ end
43
+
44
+ The class should implement:
45
+ get_context - initialize and return the context
46
+ add_to_context(key, val) - add a given value to the context at key
47
+ remove_from_context(key) - remove the key from the context
48
+ format_msg_with_context(msg) - takes the base log message and adds the context to it, returning the final message.
49
+
data/gem_logger.gemspec CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_development_dependency "bundler", "~> 1.3"
22
22
  spec.add_development_dependency "rake"
23
- spec.add_development_dependency "minitest"
23
+ spec.add_development_dependency "minitest", "~> 4.0"
24
24
  spec.add_development_dependency "minitest_should"
25
25
  spec.add_development_dependency "minitest-reporters"
26
26
  spec.add_development_dependency "factory_girl"
data/lib/gem_logger.rb CHANGED
@@ -2,51 +2,10 @@ require "gem_logger/version"
2
2
 
3
3
  require 'logger'
4
4
  require 'active_support/concern'
5
+ require 'active_support/core_ext/object'
5
6
  require 'active_support/core_ext/module/delegation'
6
7
 
7
8
  require "gem_logger/basic_logger"
9
+ require "gem_logger/context_handler"
10
+ require "gem_logger/gem_logger"
8
11
  require "gem_logger/logger_support"
9
-
10
- # To configure gem_logger, add something like the
11
- # following to an initializer (defaults shown):
12
- #
13
- # GemLogger.configure do |config|
14
- #
15
- # # The default logger instance to use
16
- # # (optional, defaults to Logger.new)
17
- # config.default_logger = CustomLogger.new
18
- #
19
- # # module to include when GemLogger::LoggerSupport is included
20
- # # (optional, defaults to GemLogger::BasicLogger)
21
- # config.logger_concern = SomeModule
22
- #
23
- # end
24
- #
25
- module GemLogger
26
-
27
- # Allows configuring via class accessors
28
- class << self
29
- # The logger concern (ActiveSupport::Concern) to include when clients include GemLogger::Logger
30
- # The module needs to cause a class level "logger" method (returning the logger instance) to be deSupportfined on the client
31
- attr_accessor :logger_concern
32
- end
33
-
34
- # default values
35
- self.logger_concern = GemLogger::BasicLogger
36
-
37
- # The default_logger to use with GemLogger::BasicLogger
38
- def self.default_logger
39
- @default_logger ||= ::Logger.new(STDOUT)
40
- end
41
-
42
- # Set the default_logger to use with GemLogger::BasicLogger
43
- def self.default_logger=(default_logger)
44
- @default_logger = default_logger
45
- end
46
-
47
- # Allows configuring via class accessors
48
- def self.configure
49
- yield self
50
- end
51
-
52
- end
@@ -10,7 +10,7 @@ module GemLogger
10
10
  GemLogger::default_logger
11
11
  end
12
12
  end
13
-
13
+
14
14
  end
15
-
15
+
16
16
  end
@@ -0,0 +1,31 @@
1
+ module GemLogger
2
+ module ContextHandler
3
+ extend ActiveSupport::Concern
4
+
5
+ # Initializes and returns context hash.
6
+ def get_context
7
+ @context_hash ||= {}
8
+ end
9
+
10
+ def add_to_context(key, value)
11
+ @context_hash[key.to_s] = value.to_s
12
+ end
13
+
14
+ def remove_from_context(key)
15
+ @context_hash.delete(key.to_s)
16
+ end
17
+
18
+ # Adds the keys/values to the message to be logged in a basic [key=val] format.
19
+ def format_msg_with_context(msg)
20
+ if @context_hash.keys.length > 0
21
+ msg_context = '['
22
+ @context_hash.each do |k, v|
23
+ msg_context += "#{k}=#{v} "
24
+ end
25
+ msg_context += '] '
26
+ msg = msg.prepend(msg_context)
27
+ end
28
+ msg
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,45 @@
1
+ # To configure gem_logger, add something like the
2
+ # following to an initializer (defaults shown):
3
+ #
4
+ # GemLogger.configure do |config|
5
+ #
6
+ # # The default logger instance to use
7
+ # # (optional, defaults to Logger.new)
8
+ # config.default_logger = CustomLogger.new
9
+ #
10
+ # # module to include when GemLogger::LoggerSupport is included
11
+ # # (optional, defaults to GemLogger::BasicLogger)
12
+ # config.logger_concern = SomeModule
13
+ #
14
+ # end
15
+ #
16
+ module GemLogger
17
+
18
+ # Allows configuring via class accessors
19
+ class << self
20
+ # The logger concern (ActiveSupport::Concern) to include when clients include GemLogger::Logger
21
+ # The module needs to cause a class level "logger" method (returning the logger instance) to be defined on the client
22
+ attr_accessor :logger_concern
23
+ attr_accessor :context_handler
24
+ end
25
+
26
+ # default values
27
+ self.logger_concern = GemLogger::BasicLogger
28
+ self.context_handler = GemLogger::ContextHandler
29
+
30
+ # The default_logger to use with GemLogger::BasicLogger
31
+ def self.default_logger
32
+ @default_logger ||= ::Logger.new(STDOUT).extend(LoggerSupport::LogContext)
33
+ end
34
+
35
+ # Set the default_logger to use with GemLogger::BasicLogger
36
+ def self.default_logger=(default_logger)
37
+ @default_logger = default_logger
38
+ end
39
+
40
+ # Allows configuring via class accessors
41
+ def self.configure
42
+ yield self
43
+ end
44
+
45
+ end
@@ -1,21 +1,21 @@
1
1
  module GemLogger
2
2
  module LoggerSupport
3
-
3
+
4
4
  extend ActiveSupport::Concern
5
-
5
+
6
6
  included do
7
7
  # A guard to prevent misuse, may just want a log message instead of a hard fail
8
8
  if self.class == Module && ! self.singleton_class.included_modules.include?(ActiveSupport::Concern)
9
9
  raise ArgumentError, "module that includes #{self.name} must be an ActiveSupport::Concern"
10
10
  end
11
-
11
+
12
12
  include GemLogger.logger_concern
13
-
14
- delegate :logger, :log_exception, :log_warning, :log_message, :to => "self.class"
13
+
14
+ delegate :logger, :log_exception, :log_warning, :log_message, :to => "self.class"
15
15
  end
16
-
17
- module ClassMethods
18
16
 
17
+ module ClassMethods
18
+ # @deprecated Consider using {#logger.context(:exception => exception.class).error("Exception: ...")} instead
19
19
  def log_exception(exception, opts={})
20
20
  logger.error("Exception #{generate_message(exception, opts)}")
21
21
  end
@@ -44,7 +44,71 @@ module GemLogger
44
44
 
45
45
  "#{log_encode(message_prefix)}#{log_encode(exception.inspect)}, #{log_encode(opts.inspect)}:\n#{exception.backtrace.collect {|x| log_encode(x)}.join("\n") rescue 'no backtrace'}"
46
46
  end
47
-
47
+
48
+ end
49
+
50
+
51
+ module ContextLoggerCommon
52
+ # @param [Hash] added_context - A hash containing context that will be added to the log messages produced by the
53
+ # returned logger
54
+ # @returns [LogContextLogger] - logger with the added context
55
+ def context(added_context)
56
+ LogContextLogger.new(self.logger, self.log_context.merge(added_context))
57
+ end
58
+
59
+ # Adds an event_type to the context
60
+ # @param [Symbol] event_type - The event type, which will be added to the context of this log statement
61
+ def event_context(event_type)
62
+ context(:event_type => event_type)
63
+ end
64
+
65
+ # Adds an exception class to the context
66
+ # @param [Exception] exception
67
+ def exception_context(exception)
68
+ context(:exception => exception.class.to_s)
69
+ end
70
+
71
+ # Logs an exception, including the backtrace.
72
+ # @param [Exception] exception
73
+ # @param [String] message
74
+ # @option [Symbol] :level - The log level to log the message at (default :error)
75
+ def log_exception(e, message, options = {})
76
+ level = options.delete(:level) || :error
77
+ backtrace = e.backtrace.try{ |b| b.join("\n") } || '(no backtrace)'
78
+ exception_context(e).send(level, "#{message}: #{e} #{backtrace}")
79
+ end
80
+ end
81
+
82
+ # The base context logger.
83
+ module LogContext
84
+ include ContextLoggerCommon
85
+
86
+ def log_context
87
+ {}
88
+ end
89
+
90
+ def logger
91
+ self
92
+ end
93
+ end
94
+
95
+ LogContextLogger = Struct.new(:logger, :log_context) do
96
+ include ContextLoggerCommon
97
+ include GemLogger.context_handler
98
+
99
+ [:debug, :info, :warn, :error, :fatal].each do |method|
100
+ define_method(method) { |msg| self.log(method, msg) }
101
+ end
102
+
103
+ def log(level, msg)
104
+ existing_context = get_context
105
+ self.log_context.each { |k,v| add_to_context(k, v) }
106
+ msg = format_msg_with_context(msg)
107
+ self.logger.send(level, msg)
108
+ ensure
109
+ self.log_context.each { |k,v| remove_from_context(k) }
110
+ existing_context.each { |k,v| add_to_context(k, v) }
111
+ end
48
112
  end
49
113
 
50
114
  end
@@ -1,3 +1,3 @@
1
1
  module GemLogger
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
data/test/test_helper.rb CHANGED
@@ -17,14 +17,15 @@ end
17
17
  require 'minitest/autorun'
18
18
  require 'minitest/should'
19
19
  require "minitest/reporters"
20
+ require "mocha/setup"
20
21
 
21
22
  reporter = ENV['REPORTER']
22
23
  reporter = case reporter
23
- when 'none' then nil
24
- when 'spec' then MiniTest::Reporters::SpecReporter.new
25
- when 'progress' then MiniTest::Reporters::ProgressReporter.new
26
- else MiniTest::Reporters::DefaultReporter.new
27
- end
24
+ when 'none' then nil
25
+ when 'spec' then MiniTest::Reporters::SpecReporter.new
26
+ when 'progress' then MiniTest::Reporters::ProgressReporter.new
27
+ else MiniTest::Reporters::DefaultReporter.new
28
+ end
28
29
  MiniTest::Reporters.use!(reporter) if reporter
29
30
 
30
31
  require 'gem_logger'
@@ -36,7 +37,7 @@ class << MiniTest::Unit.runner
36
37
  # Minitest runs each context as a suite
37
38
  # Minitest filters methods by matching against: <suite>#test_0001_<should>
38
39
  # Nested contexts are separted by spaces in rubymine, but ::s in minitest
39
-
40
+
40
41
  def _run_suites(suites, type)
41
42
  if options[:filter]
42
43
  if options[:filter] =~ /\/\\Atest\\: (.*) should (.*)\\\.\//
@@ -49,21 +50,21 @@ class << MiniTest::Unit.runner
49
50
  options[:filter] = "/\\A#{context_filter}(Test)?#test(_\\d+)?_should_#{should_filter}\\Z/"
50
51
  end
51
52
  end
52
-
53
+
53
54
  super
54
55
  end
55
-
56
+
56
57
  # Prevent "Empty test suite" verbosity when running in rubymine
57
58
  def _run_suite(suite, type)
58
-
59
+
59
60
  filter = options[:filter] || '/./'
60
- filter = Regexp.new $1 if filter =~ /\/(.*)\//
61
+ filter = Regexp.new $1 if filter =~ /\/(.*)\//
61
62
  all_test_methods = suite.send "#{type}_methods"
62
63
  filtered_test_methods = all_test_methods.find_all { |m|
63
64
  filter === m || filter === "#{suite}##{m}"
64
65
  }
65
-
66
- if filtered_test_methods.size > 0
66
+
67
+ if filtered_test_methods.size > 0
67
68
  super
68
69
  else
69
70
  [0, 0]
@@ -0,0 +1,45 @@
1
+ require_relative '../../test_helper'
2
+
3
+ module GemLogger
4
+ class ContextHandlerTest < Minitest::Should::TestCase
5
+
6
+ setup do
7
+ class MyClass
8
+ include GemLogger::ContextHandler
9
+ end
10
+ end
11
+
12
+ should "return empty hash on get_context" do
13
+ assert_equal Hash.new, MyClass.new.get_context
14
+ end
15
+
16
+ should 'add given arguments to context on add_context' do
17
+ klass = MyClass.new
18
+ klass.get_context
19
+ klass.add_to_context('foo', 'bar')
20
+ assert_equal Hash['foo', 'bar'], klass.get_context
21
+ end
22
+
23
+ should "convert add_to_context args to strings" do
24
+ klass = MyClass.new
25
+ klass.get_context
26
+ klass.add_to_context(:foo, :bar)
27
+ assert_equal Hash['foo', 'bar'], klass.get_context
28
+ end
29
+
30
+ should "pass remove_from_context to Log4r remove" do
31
+ klass = MyClass.new
32
+ klass.get_context
33
+ klass.remove_from_context('foo')
34
+ assert_equal Hash.new, klass.get_context
35
+ end
36
+
37
+ should "convert remove_from_context args to strings" do
38
+ klass = MyClass.new
39
+ klass.get_context
40
+ klass.add_to_context('foo', 'bar')
41
+ klass.remove_from_context(:foo)
42
+ assert_equal Hash.new, klass.get_context
43
+ end
44
+ end
45
+ end
@@ -2,42 +2,42 @@ require_relative '../../test_helper'
2
2
 
3
3
  module GemLogger
4
4
  class LoggerSupportTest < Minitest::Should::TestCase
5
-
5
+
6
6
  setup do
7
7
  @uniq = SecureRandom.uuid.gsub("-", "")
8
8
  end
9
-
9
+
10
10
  teardown do
11
11
  LoggerSupportTest.constants.grep(/^Foo/).each do |c|
12
12
  LoggerSupportTest.send(:remove_const, c)
13
13
  end
14
14
  end
15
-
15
+
16
16
  def new_module(module_name, &block)
17
17
  mod = self.class.const_set module_name, Module.new
18
18
  mod.class_eval(&block)
19
19
  mod
20
20
  end
21
-
21
+
22
22
  # can't do this dynamically as the class name needs to be set at inheritance time for lumber to work
23
23
  def new_class(class_name, super_class=nil, &block)
24
24
  s = "class #{class_name}"
25
25
  s << " < #{super_class}" if super_class
26
26
  s << "; end"
27
-
27
+
28
28
  eval(s)
29
29
  clazz = self.class.const_get(class_name)
30
30
  clazz.class_eval(&block)
31
31
  clazz
32
32
  end
33
-
33
+
34
34
  context "BasicLogger" do
35
-
35
+
36
36
  setup do
37
37
  @old_default_logger = GemLogger.default_logger
38
38
  GemLogger.default_logger = Minitest::Mock.new
39
39
  end
40
-
40
+
41
41
  teardown do
42
42
  GemLogger.default_logger.verify
43
43
  GemLogger.default_logger = @old_default_logger
@@ -49,14 +49,14 @@ module GemLogger
49
49
  foo.logger.expect(:debug, nil, ['hi'])
50
50
  foo.new.member_method
51
51
  end
52
-
52
+
53
53
  should "have a logger instance accessible from a class method " do
54
54
  foo = new_class("Foo#{@uniq}") { include GemLogger::LoggerSupport; def self.class_method; logger.debug('hi'); end; }
55
55
  assert foo.respond_to?(:logger)
56
56
  foo.logger.expect(:debug, nil, ['hi'])
57
57
  foo.class_method
58
58
  end
59
-
59
+
60
60
  should "have a logger instance when in a nested module" do
61
61
  foomod = new_module("FooMod#{@uniq}") { extend ActiveSupport::Concern; include GemLogger::LoggerSupport; }
62
62
  foo = new_class("Foo#{@uniq}") { include foomod; def member_method; logger.debug('hi'); end; }
@@ -64,50 +64,50 @@ module GemLogger
64
64
  foo.logger.expect(:debug, nil, ['hi'])
65
65
  foo.new.member_method
66
66
  end
67
-
67
+
68
68
  should "fail when included in a module that is not a Concern" do
69
69
  assert_raises(ArgumentError) do
70
70
  new_module("FooMod#{@uniq}") { include GemLogger::LoggerSupport; }
71
71
  end
72
72
  end
73
-
73
+
74
74
  should "have a log_exception method accessible from an instance method" do
75
75
  foo = new_class("Foo#{@uniq}") { include GemLogger::LoggerSupport; def member_method; log_exception(RuntimeError.new("hell")); end; }
76
76
  assert foo.new.respond_to?(:log_exception)
77
77
  foo.logger.expect(:error, nil, [/.*/])
78
78
  foo.new.member_method
79
79
  end
80
-
80
+
81
81
  should "have a log_exception method accessible from a class method " do
82
82
  foo = new_class("Foo#{@uniq}") { include GemLogger::LoggerSupport; def self.class_method; log_exception(RuntimeError.new("hell")); end; }
83
83
  assert foo.respond_to?(:log_exception)
84
84
  foo.logger.expect(:error, nil, [/.*/])
85
85
  foo.class_method
86
86
  end
87
-
87
+
88
88
  should "log_exception should populate class name as controller and method name as action" do
89
89
  foo = new_class("Foo#{@uniq}") { include GemLogger::LoggerSupport; def self.class_method; log_exception(RuntimeError.new("hell")); end; }
90
90
  foo.logger.expect(:error, nil, [/.*/])
91
91
  foo.class_method
92
92
  end
93
-
93
+
94
94
  should "not raise exception on bad encoding" do
95
95
  foo = new_class("Foo#{@uniq}") { include GemLogger::LoggerSupport; def self.class_method; log_exception(RuntimeError.new("\xE2".force_encoding('ASCII-8BIT'))); end; }
96
96
  foo.logger.expect(:error, nil, [/.*/])
97
97
  foo.class_method
98
98
  end
99
-
99
+
100
100
  context 'Generate Message' do
101
101
  should 'properly generate messages with a message prefix' do
102
102
  foo = new_class("Foo#{@uniq}") { include GemLogger::LoggerSupport; }
103
103
  assert_match /^prefix /, foo.generate_message(StandardError.new('Hello'), {:message_prefix => 'prefix'})
104
104
  end
105
-
105
+
106
106
  should 'properly generate messages with a blank message prefix' do
107
107
  foo = new_class("Foo#{@uniq}") { include GemLogger::LoggerSupport; }
108
108
  assert_match /^#<StandardError: Hello>/, foo.generate_message(StandardError.new('Hello'), {:message_prefix => ''})
109
109
  end
110
-
110
+
111
111
  should 'properly generate messages with no message prefix' do
112
112
  foo = new_class("Foo#{@uniq}") { include GemLogger::LoggerSupport; }
113
113
  assert_match /^#<StandardError: Hello>/, foo.generate_message(StandardError.new('Hello'), {})
@@ -115,75 +115,193 @@ module GemLogger
115
115
  end
116
116
 
117
117
  end
118
-
118
+
119
+ context "logger with added context" do
120
+
121
+ setup do
122
+ class Foo; include GemLogger::LoggerSupport; end
123
+ end
124
+
125
+ should "add the context to generated messages" do
126
+
127
+ GemLogger::LoggerSupport::LogContextLogger.any_instance.expects(:add_to_context).with("ctx", "1")
128
+ GemLogger::LoggerSupport::LogContextLogger.any_instance.expects(:remove_from_context).with('ctx')
129
+ Foo.logger.expects(:info).with("msg")
130
+
131
+ Foo.logger.context("ctx" => "1").info("msg")
132
+ end
133
+
134
+ should "allow symbols as contexts" do
135
+ GemLogger::LoggerSupport::LogContextLogger.any_instance.expects(:add_to_context).with(:ctx, "1")
136
+ GemLogger::LoggerSupport::LogContextLogger.any_instance.expects(:remove_from_context).with(:ctx)
137
+
138
+ Foo.logger.context(:ctx => "1").info("msg")
139
+ end
140
+
141
+ should "implement debug" do
142
+ Foo.logger.expects(:debug).with("[ctx=1 ] msg")
143
+ Foo.logger.context(:ctx => "1").debug("msg")
144
+ end
145
+
146
+ should "implement info" do
147
+ Foo.logger.expects(:info).with("[ctx=1 ] msg")
148
+ Foo.logger.context(:ctx => "1").info("msg")
149
+ end
150
+
151
+ should "implement warn" do
152
+ Foo.logger.expects(:warn).with("[ctx=1 ] msg")
153
+ Foo.logger.context(:ctx => "1").warn("msg")
154
+ end
155
+
156
+ should "implement error" do
157
+ Foo.logger.expects(:error).with("[ctx=1 ] msg")
158
+ Foo.logger.context(:ctx => "1").error("msg")
159
+ end
160
+
161
+ should "implement fatal" do
162
+ Foo.logger.expects(:fatal).with("[ctx=1 ] msg")
163
+ Foo.logger.context(:ctx => "1").fatal("msg")
164
+ end
165
+
166
+ should 'allow context to be chained' do
167
+ GemLogger::LoggerSupport::LogContextLogger.any_instance.expects(:add_to_context).with('ctx', '1')
168
+ GemLogger::LoggerSupport::LogContextLogger.any_instance.expects(:remove_from_context).with('ctx')
169
+ GemLogger::LoggerSupport::LogContextLogger.any_instance.expects(:add_to_context).with('ctx2', '2')
170
+ GemLogger::LoggerSupport::LogContextLogger.any_instance.expects(:remove_from_context).with('ctx2')
171
+ Foo.logger.expects(:info).with("msg")
172
+
173
+ Foo.logger.context("ctx" => "1").context("ctx2" => "2").info("msg")
174
+ end
175
+
176
+ context "event_context" do
177
+ should "add the event_type as context" do
178
+ GemLogger::LoggerSupport::LogContextLogger.any_instance.expects(:add_to_context).with(:event_type, :test_event)
179
+ GemLogger::LoggerSupport::LogContextLogger.any_instance.expects(:remove_from_context).with(:event_type)
180
+
181
+ Foo.logger.expects(:info).with("msg")
182
+ Foo.logger.event_context(:test_event).info("msg")
183
+ end
184
+
185
+ should "include the context of the logger used" do
186
+ GemLogger::LoggerSupport::LogContextLogger.any_instance.expects(:add_to_context).with(:event_type, :test_event)
187
+ GemLogger::LoggerSupport::LogContextLogger.any_instance.expects(:remove_from_context).with(:event_type)
188
+ GemLogger::LoggerSupport::LogContextLogger.any_instance.expects(:add_to_context).with(:ctx, '1')
189
+ GemLogger::LoggerSupport::LogContextLogger.any_instance.expects(:remove_from_context).with(:ctx)
190
+
191
+ Foo.logger.expects(:error).with("msg")
192
+ Foo.logger.context(:ctx => "1").event_context(:test_event).error("msg")
193
+ end
194
+
195
+ should 'restore previous log context after logging' do
196
+ GemLogger::LoggerSupport::LogContextLogger.any_instance.stubs(:get_context).returns({'foo' => 'bar'})
197
+ GemLogger::LoggerSupport::LogContextLogger.any_instance.expects(:add_to_context).with(:event_type, {'foo' => 'baz'})
198
+ GemLogger::LoggerSupport::LogContextLogger.any_instance.expects(:remove_from_context).with(:event_type)
199
+ GemLogger::LoggerSupport::LogContextLogger.any_instance.expects(:format_msg_with_context).with('msg')
200
+ GemLogger::LoggerSupport::LogContextLogger.any_instance.expects(:add_to_context).with('foo', 'bar')
201
+
202
+ Foo.logger.event_context('foo' => 'baz').info("msg")
203
+ end
204
+ end
205
+
206
+ context "exception_context" do
207
+ should "add the exception class as context" do
208
+ GemLogger::LoggerSupport::LogContextLogger.any_instance.expects(:add_to_context).with(:exception, 'StandardError')
209
+ GemLogger::LoggerSupport::LogContextLogger.any_instance.expects(:remove_from_context).with(:exception)
210
+
211
+ Foo.logger.expects(:info).with("msg")
212
+ Foo.logger.exception_context(StandardError.new).info("msg")
213
+ end
214
+ end
215
+
216
+ context "log_exception" do
217
+ should "add the exception class as context" do
218
+ GemLogger::LoggerSupport::LogContextLogger.any_instance.expects(:add_to_context).with(:exception, 'StandardError')
219
+ GemLogger::LoggerSupport::LogContextLogger.any_instance.expects(:remove_from_context).with(:exception)
220
+
221
+ Foo.logger.expects(:error)
222
+ Foo.logger.log_exception(StandardError.new, "msg")
223
+ end
224
+
225
+ should "log the backtrace" do
226
+ Foo.logger.expects(:error).with("[exception=StandardError ] msg: err (no backtrace)")
227
+ Foo.logger.log_exception(StandardError.new("err"), "msg")
228
+ end
229
+
230
+ should 'allow the level to be changed as an option' do
231
+ Foo.logger.expects(:warn).with("[exception=StandardError ] msg: err (no backtrace)")
232
+ Foo.logger.log_exception(StandardError.new("err"), "msg", :level => :warn)
233
+ end
234
+ end
235
+ end
236
+
119
237
  context "lumber integration" do
120
-
238
+
121
239
  setup do
122
240
  require 'lumber'
123
-
241
+
124
242
  yml = <<-EOF
125
- log4r_config:
126
- pre_config:
127
- root:
128
- level: 'DEBUG'
129
- loggers:
130
- - name: "rails"
131
- level: DEBUG
132
- outputters: []
243
+ log4r_config:
244
+ pre_config:
245
+ root:
246
+ level: 'DEBUG'
247
+ loggers:
248
+ - name: "rails"
249
+ level: DEBUG
250
+ outputters: []
133
251
  EOF
134
-
252
+
135
253
  cfg = Log4r::YamlConfigurator
136
254
  cfg.load_yaml_string(yml)
137
255
  logger = Log4r::Logger['rails']
138
- sio = StringIO.new
256
+ sio = StringIO.new
139
257
  logger.outputters = [Log4r::IOOutputter.new("sbout", sio)]
140
-
258
+
141
259
  Log4r::YamlConfigurator.stub(:load_yaml_file, nil) do
142
260
  root = File.expand_path("../../..", __FILE__)
143
261
  Lumber.init(:root => root, :env => 'test', :config_file => __FILE__)
144
262
  end
145
-
263
+
146
264
  @old_logger_concern = GemLogger.logger_concern
147
265
  GemLogger.logger_concern = Lumber::LoggerSupport
148
266
  end
149
-
267
+
150
268
  teardown do
151
269
  GemLogger.logger_concern = @old_logger_concern
152
270
  end
153
-
271
+
154
272
  should "have a logger instance accessible from an instance method" do
155
273
  foo = new_class("Foo#{@uniq}") { include GemLogger::LoggerSupport; }
156
274
  assert_equal "rails::GemLogger::LoggerSupportTest::#{foo.name.split('::').last}", foo.new.logger.fullname
157
275
  end
158
-
276
+
159
277
  should "have a logger instance accessible from a class method " do
160
278
  foo = new_class("Foo#{@uniq}") { include GemLogger::LoggerSupport; }
161
279
  assert_equal "rails::GemLogger::LoggerSupportTest::#{foo.name.split('::').last}", foo.logger.fullname
162
280
  end
163
-
281
+
164
282
  should "have a logger instance when in a nested module" do
165
283
  foomod = new_module("FooMod#{@uniq}") { extend ActiveSupport::Concern; include GemLogger::LoggerSupport; }
166
284
  foo = new_class("Foo#{@uniq}") { include foomod; }
167
285
  assert_equal "rails::GemLogger::LoggerSupportTest::#{foo.name.split('::').last}", foo.logger.fullname
168
286
  end
169
-
287
+
170
288
  should "have correct logger instance with multiple includes" do
171
289
  foomod = new_module("FooMod#{@uniq}") { extend ActiveSupport::Concern; include GemLogger::LoggerSupport; }
172
290
  foo = new_class("Foo#{@uniq}") { include GemLogger::LoggerSupport; include foomod; }
173
291
  assert_equal "rails::GemLogger::LoggerSupportTest::#{foo.name.split('::').last}", foo.logger.fullname
174
292
  end
175
-
293
+
176
294
  should "have correct logger instance with includes and inheritance" do
177
295
  foosuper = new_class("FooSuper#{@uniq}") { include GemLogger::LoggerSupport; }
178
296
  foo = new_class("Foo#{@uniq}", foosuper) { }
179
- assert_equal "rails::GemLogger::LoggerSupportTest::#{foosuper.name.split('::').last}::#{foo.name.split('::').last}", foo.logger.fullname
297
+ assert_equal "rails::GemLogger::LoggerSupportTest::#{foo.name.split('::').last}", foo.logger.fullname
180
298
  end
181
-
299
+
182
300
  should "have correct logger instance with multiple includes and inheritance" do
183
301
  foomod = new_module("FooMod#{@uniq}") { extend ActiveSupport::Concern; include GemLogger::LoggerSupport; }
184
302
  foosuper = new_class("FooSuper#{@uniq}") { include foomod; }
185
303
  foo = new_class("Foo#{@uniq}", foosuper) { include GemLogger::LoggerSupport; include foomod; }
186
- assert_equal "rails::GemLogger::LoggerSupportTest::#{foosuper.name.split('::').last}::#{foo.name.split('::').last}", foo.logger.fullname
304
+ assert_equal "rails::GemLogger::LoggerSupportTest::#{foo.name.split('::').last}", foo.logger.fullname
187
305
  end
188
306
 
189
307
  end
metadata CHANGED
@@ -1,141 +1,127 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gem_logger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Conway
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-08-23 00:00:00.000000000 Z
11
+ date: 2014-10-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- prerelease: false
15
14
  name: bundler
16
15
  requirement: !ruby/object:Gem::Requirement
17
16
  requirements:
18
- - - ~>
17
+ - - "~>"
19
18
  - !ruby/object:Gem::Version
20
19
  version: '1.3'
20
+ type: :development
21
+ prerelease: false
21
22
  version_requirements: !ruby/object:Gem::Requirement
22
23
  requirements:
23
- - - ~>
24
+ - - "~>"
24
25
  - !ruby/object:Gem::Version
25
26
  version: '1.3'
26
- type: :development
27
27
  - !ruby/object:Gem::Dependency
28
- prerelease: false
29
28
  name: rake
30
29
  requirement: !ruby/object:Gem::Requirement
31
30
  requirements:
32
- - - ! '>='
31
+ - - ">="
33
32
  - !ruby/object:Gem::Version
34
- version: !binary |-
35
- MA==
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ! '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: !binary |-
41
- MA==
42
- type: :development
40
+ version: '0'
43
41
  - !ruby/object:Gem::Dependency
44
- prerelease: false
45
42
  name: minitest
46
43
  requirement: !ruby/object:Gem::Requirement
47
44
  requirements:
48
- - - ! '>='
45
+ - - "~>"
49
46
  - !ruby/object:Gem::Version
50
- version: !binary |-
51
- MA==
47
+ version: '4.0'
48
+ type: :development
49
+ prerelease: false
52
50
  version_requirements: !ruby/object:Gem::Requirement
53
51
  requirements:
54
- - - ! '>='
52
+ - - "~>"
55
53
  - !ruby/object:Gem::Version
56
- version: !binary |-
57
- MA==
58
- type: :development
54
+ version: '4.0'
59
55
  - !ruby/object:Gem::Dependency
60
- prerelease: false
61
56
  name: minitest_should
62
57
  requirement: !ruby/object:Gem::Requirement
63
58
  requirements:
64
- - - ! '>='
59
+ - - ">="
65
60
  - !ruby/object:Gem::Version
66
- version: !binary |-
67
- MA==
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
68
64
  version_requirements: !ruby/object:Gem::Requirement
69
65
  requirements:
70
- - - ! '>='
66
+ - - ">="
71
67
  - !ruby/object:Gem::Version
72
- version: !binary |-
73
- MA==
74
- type: :development
68
+ version: '0'
75
69
  - !ruby/object:Gem::Dependency
76
- prerelease: false
77
70
  name: minitest-reporters
78
71
  requirement: !ruby/object:Gem::Requirement
79
72
  requirements:
80
- - - ! '>='
73
+ - - ">="
81
74
  - !ruby/object:Gem::Version
82
- version: !binary |-
83
- MA==
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
84
78
  version_requirements: !ruby/object:Gem::Requirement
85
79
  requirements:
86
- - - ! '>='
80
+ - - ">="
87
81
  - !ruby/object:Gem::Version
88
- version: !binary |-
89
- MA==
90
- type: :development
82
+ version: '0'
91
83
  - !ruby/object:Gem::Dependency
92
- prerelease: false
93
84
  name: factory_girl
94
85
  requirement: !ruby/object:Gem::Requirement
95
86
  requirements:
96
- - - ! '>='
87
+ - - ">="
97
88
  - !ruby/object:Gem::Version
98
- version: !binary |-
99
- MA==
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
100
92
  version_requirements: !ruby/object:Gem::Requirement
101
93
  requirements:
102
- - - ! '>='
94
+ - - ">="
103
95
  - !ruby/object:Gem::Version
104
- version: !binary |-
105
- MA==
106
- type: :development
96
+ version: '0'
107
97
  - !ruby/object:Gem::Dependency
108
- prerelease: false
109
98
  name: faker
110
99
  requirement: !ruby/object:Gem::Requirement
111
100
  requirements:
112
- - - ! '>='
101
+ - - ">="
113
102
  - !ruby/object:Gem::Version
114
- version: !binary |-
115
- MA==
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
116
106
  version_requirements: !ruby/object:Gem::Requirement
117
107
  requirements:
118
- - - ! '>='
108
+ - - ">="
119
109
  - !ruby/object:Gem::Version
120
- version: !binary |-
121
- MA==
122
- type: :development
110
+ version: '0'
123
111
  - !ruby/object:Gem::Dependency
124
- prerelease: false
125
112
  name: activesupport
126
113
  requirement: !ruby/object:Gem::Requirement
127
114
  requirements:
128
- - - ! '>='
115
+ - - ">="
129
116
  - !ruby/object:Gem::Version
130
- version: !binary |-
131
- MA==
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
132
120
  version_requirements: !ruby/object:Gem::Requirement
133
121
  requirements:
134
- - - ! '>='
122
+ - - ">="
135
123
  - !ruby/object:Gem::Version
136
- version: !binary |-
137
- MA==
138
- type: :runtime
124
+ version: '0'
139
125
  description: Allows classes/modules in gems to have logger class/instance methods
140
126
  with a pluggable Logger implementation
141
127
  email:
@@ -144,9 +130,9 @@ executables: []
144
130
  extensions: []
145
131
  extra_rdoc_files: []
146
132
  files:
147
- - .coveralls.yml
148
- - .gitignore
149
- - .travis.yml
133
+ - ".coveralls.yml"
134
+ - ".gitignore"
135
+ - ".travis.yml"
150
136
  - Gemfile
151
137
  - LICENSE.txt
152
138
  - README.md
@@ -154,10 +140,13 @@ files:
154
140
  - gem_logger.gemspec
155
141
  - lib/gem_logger.rb
156
142
  - lib/gem_logger/basic_logger.rb
143
+ - lib/gem_logger/context_handler.rb
144
+ - lib/gem_logger/gem_logger.rb
157
145
  - lib/gem_logger/logger_support.rb
158
146
  - lib/gem_logger/version.rb
159
147
  - test/test_helper.rb
160
148
  - test/unit/gem_logger/basic_logger_test.rb
149
+ - test/unit/gem_logger/context_handler_test.rb
161
150
  - test/unit/gem_logger/logger_support_test.rb
162
151
  - test/unit/gem_logger_test.rb
163
152
  homepage: ''
@@ -170,19 +159,17 @@ require_paths:
170
159
  - lib
171
160
  required_ruby_version: !ruby/object:Gem::Requirement
172
161
  requirements:
173
- - - ! '>='
162
+ - - ">="
174
163
  - !ruby/object:Gem::Version
175
- version: !binary |-
176
- MA==
164
+ version: '0'
177
165
  required_rubygems_version: !ruby/object:Gem::Requirement
178
166
  requirements:
179
- - - ! '>='
167
+ - - ">="
180
168
  - !ruby/object:Gem::Version
181
- version: !binary |-
182
- MA==
169
+ version: '0'
183
170
  requirements: []
184
171
  rubyforge_project:
185
- rubygems_version: 2.0.6
172
+ rubygems_version: 2.2.2
186
173
  signing_key:
187
174
  specification_version: 4
188
175
  summary: Allows classes/modules in gems to have logger class/instance methods with
@@ -190,5 +177,7 @@ summary: Allows classes/modules in gems to have logger class/instance methods wi
190
177
  test_files:
191
178
  - test/test_helper.rb
192
179
  - test/unit/gem_logger/basic_logger_test.rb
180
+ - test/unit/gem_logger/context_handler_test.rb
193
181
  - test/unit/gem_logger/logger_support_test.rb
194
182
  - test/unit/gem_logger_test.rb
183
+ has_rdoc: