lumber 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3a46d745783b60fff11ef0721004f12f9f63bd96
4
+ data.tar.gz: 3eba30bf67000eb632ed7a43b874b9311c06ea7d
5
+ SHA512:
6
+ metadata.gz: 90f2ac82d2c07a1c41de9f1135bf635826829bb26f055d65c0d71935276eb407a5f07f23e27a2bdcb41075f655492ce566392f8606cac0c440df7fac4f8874bc
7
+ data.tar.gz: e982a2aa70f9201f721cbd05fb9a32a7a6cdf651e9a2afb3ad324a9e3ae1bf4035c734049a4c4b52be67ef4b9c0480c61b5cb8cd2f96bc1c7955a1664376eef4
data/CHANGELOG CHANGED
@@ -1,3 +1,15 @@
1
+ 1.0.1 (10/11/2013)
2
+ ------------------
3
+
4
+ add log4r json formatter
5
+
6
+ 1.0.0 (10/11/2013)
7
+ ------------------
8
+
9
+ Add coveralls and use poltergeist/phantomjs instead of capybara-webkit so we
10
+ fix capybara usage for capybara 2.x for travis
11
+ only supporting ruby 1.9.3 and higher
12
+
1
13
  0.13.6 (08/23/2013)
2
14
  -------------------
3
15
 
@@ -0,0 +1,114 @@
1
+ require "log4r/formatter/formatter"
2
+ require 'json'
3
+
4
+ module Lumber
5
+
6
+ class JsonFormatter < Log4r::BasicFormatter
7
+
8
+ def initialize(hash={})
9
+ @key_mapping = {}
10
+ mapping = hash['key_mapping'] || {}
11
+ @key_mapping = Hash[mapping.collect {|k, v| [k.to_s, v.to_s.split('.')]}]
12
+ end
13
+
14
+ def format(logevent)
15
+ data = {}
16
+ assign_mapped_key(data, :timestamp, Time.now.to_s)
17
+ assign_mapped_key(data, :logger, logevent.fullname)
18
+ assign_mapped_key(data, :level, Log4r::LNAMES[logevent.level].downcase)
19
+
20
+ if logevent.data.kind_of? Exception
21
+ message = "Caught #{logevent.data.class}"
22
+ message << ": #{logevent.data.message}" if logevent.data.message
23
+ assign_mapped_key(data, :message, message)
24
+ assign_mapped_key(data, :exception, logevent.data.class.to_s)
25
+ trace = logevent.data.backtrace if logevent.data.respond_to?(:backtrace)
26
+ if trace
27
+ assign_mapped_key(data, :backtrace, trace.join("\n\t"))
28
+ assign_mapped_key(data, :file, trace[0].split(":")[0])
29
+ assign_mapped_key(data, :line, trace[0].split(":")[1].to_i)
30
+ end
31
+ else
32
+ assign_mapped_key(data, :message, format_object(logevent.data))
33
+ end
34
+
35
+ if logevent.tracer
36
+ file, line, method = parse_caller(logevent.tracer[0])
37
+ assign_mapped_key(data, :file, file)
38
+ assign_mapped_key(data, :line, line)
39
+ assign_mapped_key(data, :method, method)
40
+ end
41
+
42
+ gdc = Log4r::GDC.get
43
+ if gdc && gdc != $0
44
+ value = nil
45
+ begin
46
+ value = gdc.inspect
47
+ rescue
48
+ end
49
+ assign_mapped_key(data, :gdc, value)
50
+ end
51
+
52
+ if Log4r::NDC.get_depth > 0
53
+ value = []
54
+ Log4r::NDC.clone_stack.each do |x|
55
+ begin
56
+ value << x.inspect
57
+ rescue
58
+ end
59
+ end
60
+ assign_mapped_key(data, :ndc, value)
61
+ end
62
+
63
+ mdc = Log4r::MDC.get_context
64
+ if mdc && mdc.size > 0
65
+ value = {}
66
+ mdc.each do |k, v|
67
+ begin
68
+ value[k] = v.inspect
69
+ rescue
70
+ end
71
+ end
72
+ assign_mapped_key(data, :mdc, value)
73
+ end
74
+
75
+ data.to_json
76
+ end
77
+
78
+ private
79
+
80
+ def assign_mapped_key(data, key, value)
81
+ return if value.nil? || (value.respond_to?(:size) && value.size == 0)
82
+ key = key.to_s
83
+ mapped_key = @key_mapping[key]
84
+ if mapped_key.nil?
85
+ data[key] = value
86
+ else
87
+ current = data
88
+ mapped_key.each_with_index do |k, i|
89
+ if mapped_key.size > i+1
90
+ current[k] ||= {}
91
+ current = current[k]
92
+ else
93
+ current[k] = value
94
+ end
95
+ end
96
+ end
97
+ end
98
+
99
+ def parse_caller(line)
100
+ if /^(.+?):(\d+)(?::in `(.*)')?/ =~ line
101
+ file = Regexp.last_match[1]
102
+ line = Regexp.last_match[2].to_i
103
+ method = Regexp.last_match[3]
104
+ [file, line, method]
105
+ else
106
+ []
107
+ end
108
+ end
109
+ end
110
+
111
+ end
112
+
113
+ # Log4r yml config only looks for constants in Log4r namespace
114
+ Log4r::JsonFormatter = Lumber::JsonFormatter
@@ -1,3 +1,3 @@
1
1
  module Lumber
2
- VERSION = "1.0.0"
2
+ VERSION = "1.0.1"
3
3
  end
data/lib/lumber.rb CHANGED
@@ -5,6 +5,7 @@ require "lumber/lumber"
5
5
  require "lumber/logger_support"
6
6
  require "lumber/log4r"
7
7
  require "lumber/level_util"
8
+ require "lumber/json_formatter"
8
9
 
9
10
 
10
11
  if defined?(Rails::Railtie)
@@ -0,0 +1,199 @@
1
+ require "spec_helper"
2
+
3
+ describe Lumber::JsonFormatter do
4
+
5
+ context "log4r yaml configuration" do
6
+
7
+ it "has default values without configuration" do
8
+ yml = <<-EOF
9
+ log4r_config:
10
+ pre_config:
11
+ root:
12
+ level: 'DEBUG'
13
+ loggers:
14
+ - name: "mylogger"
15
+
16
+ outputters:
17
+ - type: StdoutOutputter
18
+ name: stdout
19
+ formatter:
20
+ type: JsonFormatter
21
+ EOF
22
+
23
+ cfg = Log4r::YamlConfigurator
24
+ cfg.load_yaml_string(yml)
25
+ outputter = Log4r::Outputter['stdout']
26
+ outputter.formatter.should_not be_nil
27
+ outputter.formatter.should be_a_kind_of Lumber::JsonFormatter
28
+ end
29
+
30
+ it "can receive configuration" do
31
+ yml = <<-EOF
32
+ log4r_config:
33
+ pre_config:
34
+ root:
35
+ level: 'DEBUG'
36
+ loggers:
37
+ - name: "mylogger"
38
+
39
+ outputters:
40
+ - type: StdoutOutputter
41
+ name: stdout
42
+ formatter:
43
+ type: JsonFormatter
44
+ key_mapping:
45
+ level: severity
46
+ backtrace: exception.bt
47
+ EOF
48
+
49
+ cfg = Log4r::YamlConfigurator
50
+ cfg.load_yaml_string(yml)
51
+ outputter = Log4r::Outputter['stdout']
52
+ outputter.formatter.should_not be_nil
53
+ outputter.formatter.should be_a_kind_of Lumber::JsonFormatter
54
+ outputter.formatter.instance_variable_get(:@key_mapping).should eq({'level' => ['severity'], 'backtrace' => ['exception', 'bt']})
55
+ end
56
+
57
+ end
58
+
59
+ context "#assign_mapped_key" do
60
+
61
+ it "handles no mapping" do
62
+ formatter = Lumber::JsonFormatter.new()
63
+ data = {}
64
+ formatter.send(:assign_mapped_key, data, 'foo', 'bar')
65
+ data['foo'].should == 'bar'
66
+ end
67
+
68
+ it "handles simple mapping" do
69
+ formatter = Lumber::JsonFormatter.new('key_mapping' => {'foo' => 'baz'})
70
+ data = {}
71
+ formatter.send(:assign_mapped_key, data, 'foo', 'bar')
72
+ data['foo'].should be_nil
73
+ data['baz'].should == 'bar'
74
+ end
75
+
76
+ it "handles deep mapping" do
77
+ formatter = Lumber::JsonFormatter.new('key_mapping' => {'foo' => 'baz.bum'})
78
+ data = {}
79
+ formatter.send(:assign_mapped_key, data, 'foo', 'bar')
80
+ data['foo'].should be_nil
81
+ data['baz'].should eq({'bum' => 'bar'})
82
+ end
83
+
84
+ it "handles overlapping deep mapping" do
85
+ formatter = Lumber::JsonFormatter.new('key_mapping' => {'foo' => 'baz.bum', 'dum' => 'baz.derf'})
86
+ data = {}
87
+ formatter.send(:assign_mapped_key, data, 'foo', 'bar')
88
+ formatter.send(:assign_mapped_key, data, 'dum', 'hum')
89
+ data['foo'].should be_nil
90
+ data['dum'].should be_nil
91
+ data['baz'].should eq({'bum' => 'bar', 'derf' => 'hum'})
92
+ end
93
+
94
+ end
95
+
96
+ context "log contents" do
97
+
98
+ before(:each) do
99
+ @logger = Lumber.find_or_create_logger('mylogger')
100
+ @sio = StringIO.new
101
+ @outputter = Log4r::IOOutputter.new("sbout", @sio)
102
+ @formatter = Lumber::JsonFormatter.new
103
+ @outputter.formatter = @formatter
104
+ @logger.outputters.clear
105
+ @logger.outputters << @outputter
106
+
107
+ Log4r::GDC.set(nil)
108
+ Log4r::NDC.clear
109
+ Log4r::MDC.get_context.keys.each {|k| Log4r::MDC.remove(k) }
110
+ end
111
+
112
+ it "logs as json" do
113
+ @logger.info("howdy")
114
+ @sio.string.size.should be_present
115
+ json = JSON.parse(@sio.string)
116
+ json['logger'].should == 'mylogger'
117
+ json['level'].should == 'info'
118
+ json['message'].should == 'howdy'
119
+ json['timestamp'].should be_present
120
+ end
121
+
122
+ it "logs as json with mapping" do
123
+ @formatter = Lumber::JsonFormatter.new('key_mapping' => {'level' => 'severity'})
124
+ @outputter.formatter = @formatter
125
+
126
+ @logger.info("howdy")
127
+ json = JSON.parse(@sio.string)
128
+ json['level'].should be_nil
129
+ json['severity'].should == 'info'
130
+ end
131
+
132
+ it "logs exception as json" do
133
+ ex = StandardError.new("mybad")
134
+ raise ex rescue nil
135
+ @logger.error(ex)
136
+ json = JSON.parse(@sio.string)
137
+ json['message'].should == 'Caught StandardError: mybad'
138
+ json['level'].should == 'error'
139
+ json['backtrace'].should =~ /json_formatter_spec.rb:\d+/
140
+ json['file'].should =~ /^\/.*json_formatter_spec.rb$/
141
+ json['line'].should > 0
142
+ end
143
+
144
+ it "doesn't set file/line/method by default" do
145
+ @logger.fatal("no tracing")
146
+ json = JSON.parse(@sio.string)
147
+ json['file'].should be_nil
148
+ json['line'].should be_nil
149
+ json['method'].should be_nil
150
+ end
151
+
152
+ it "uses trace data if enabled" do
153
+ @logger.trace = true
154
+ @logger.fatal("no tracing")
155
+ json = JSON.parse(@sio.string)
156
+ json['file'].should =~ /^\/.*json_formatter_spec.rb$/
157
+ json['line'].should > 0
158
+ json['method'].should be_present
159
+ end
160
+
161
+ it "uses global log4r context if available" do
162
+ Log4r::GDC.set("mygdc")
163
+ @logger.info("context")
164
+ json = JSON.parse(@sio.string)
165
+ json['gdc'].should == '"mygdc"'
166
+ end
167
+
168
+ it "uses nested log4r context if available" do
169
+ Log4r::NDC.push("myndc0")
170
+ Log4r::NDC.push(99)
171
+ @logger.info("context")
172
+ json = JSON.parse(@sio.string)
173
+ json['ndc'].should == ['"myndc0"', "99"]
174
+ end
175
+
176
+ it "uses mapped log4r context if available" do
177
+ Log4r::MDC.put("foo", "mymdcfoo")
178
+ Log4r::MDC.put("lucky", 7)
179
+ Log4r::MDC.put("myclass", Object)
180
+ @logger.info("context")
181
+ json = JSON.parse(@sio.string)
182
+ json['mdc'].should == {"foo" => '"mymdcfoo"', "lucky" => "7", "myclass" => "Object"}
183
+ end
184
+
185
+ it "handles failure inspecting log4r context" do
186
+ o = Object.new
187
+ o.stub(:inspect).and_raise("bad")
188
+ Log4r::GDC.set(o)
189
+ Log4r::NDC.push(o); Log4r::NDC.push(5)
190
+ Log4r::MDC.put("obj", o); Log4r::MDC.put("foo", "bar")
191
+ @logger.info("context")
192
+ json = JSON.parse(@sio.string)
193
+ json['gdc'].should be_nil
194
+ json['ndc'].should == ["5"]
195
+ json['mdc'].should == {"foo" => '"bar"'}
196
+ end
197
+ end
198
+
199
+ end
data/spec/spec_helper.rb CHANGED
@@ -5,7 +5,16 @@ if ENV['CI']
5
5
  Coveralls.wear!
6
6
  end
7
7
 
8
- Bundler.require(:development, :test)
8
+ require 'bundler'
9
+ begin
10
+ Bundler.setup(:default, :development)
11
+ rescue Bundler::BundlerError => e
12
+ $stderr.puts e.message
13
+ $stderr.puts "Run `bundle install` to install missing gems"
14
+ exit e.status_code
15
+ end
16
+
17
+ require 'sinatra'
9
18
  Sinatra::Base.set :environment, :test
10
19
 
11
20
  require 'lumber'
metadata CHANGED
@@ -1,177 +1,159 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lumber
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 1.0.0
4
+ version: 1.0.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Matt Conway
9
- autorequire:
8
+ autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-08-23 00:00:00.000000000 Z
11
+ date: 2013-10-11 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: log4r
16
- version_requirements: !ruby/object:Gem::Requirement
15
+ requirement: !ruby/object:Gem::Requirement
17
16
  requirements:
18
17
  - - ~>
19
18
  - !ruby/object:Gem::Version
20
19
  version: 1.1.10
21
- none: false
22
- requirement: !ruby/object:Gem::Requirement
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ~>
25
25
  - !ruby/object:Gem::Version
26
26
  version: 1.1.10
27
- none: false
28
- prerelease: false
29
- type: :runtime
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: activesupport
32
- version_requirements: !ruby/object:Gem::Requirement
33
- requirements:
34
- - - '>='
35
- - !ruby/object:Gem::Version
36
- version: '0'
37
- none: false
38
29
  requirement: !ruby/object:Gem::Requirement
39
30
  requirements:
40
31
  - - '>='
41
32
  - !ruby/object:Gem::Version
42
33
  version: '0'
43
- none: false
44
- prerelease: false
45
34
  type: :runtime
46
- - !ruby/object:Gem::Dependency
47
- name: sinatra
35
+ prerelease: false
48
36
  version_requirements: !ruby/object:Gem::Requirement
49
37
  requirements:
50
38
  - - '>='
51
39
  - !ruby/object:Gem::Version
52
40
  version: '0'
53
- none: false
41
+ - !ruby/object:Gem::Dependency
42
+ name: sinatra
54
43
  requirement: !ruby/object:Gem::Requirement
55
44
  requirements:
56
45
  - - '>='
57
46
  - !ruby/object:Gem::Version
58
47
  version: '0'
59
- none: false
60
- prerelease: false
61
48
  type: :runtime
62
- - !ruby/object:Gem::Dependency
63
- name: rake
49
+ prerelease: false
64
50
  version_requirements: !ruby/object:Gem::Requirement
65
51
  requirements:
66
52
  - - '>='
67
53
  - !ruby/object:Gem::Version
68
54
  version: '0'
69
- none: false
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
70
57
  requirement: !ruby/object:Gem::Requirement
71
58
  requirements:
72
59
  - - '>='
73
60
  - !ruby/object:Gem::Version
74
61
  version: '0'
75
- none: false
76
- prerelease: false
77
62
  type: :development
78
- - !ruby/object:Gem::Dependency
79
- name: rspec
63
+ prerelease: false
80
64
  version_requirements: !ruby/object:Gem::Requirement
81
65
  requirements:
82
66
  - - '>='
83
67
  - !ruby/object:Gem::Version
84
68
  version: '0'
85
- none: false
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
86
71
  requirement: !ruby/object:Gem::Requirement
87
72
  requirements:
88
73
  - - '>='
89
74
  - !ruby/object:Gem::Version
90
75
  version: '0'
91
- none: false
92
- prerelease: false
93
76
  type: :development
94
- - !ruby/object:Gem::Dependency
95
- name: rack-test
77
+ prerelease: false
96
78
  version_requirements: !ruby/object:Gem::Requirement
97
79
  requirements:
98
80
  - - '>='
99
81
  - !ruby/object:Gem::Version
100
82
  version: '0'
101
- none: false
83
+ - !ruby/object:Gem::Dependency
84
+ name: rack-test
102
85
  requirement: !ruby/object:Gem::Requirement
103
86
  requirements:
104
87
  - - '>='
105
88
  - !ruby/object:Gem::Version
106
89
  version: '0'
107
- none: false
108
- prerelease: false
109
90
  type: :development
110
- - !ruby/object:Gem::Dependency
111
- name: capybara
91
+ prerelease: false
112
92
  version_requirements: !ruby/object:Gem::Requirement
113
93
  requirements:
114
94
  - - '>='
115
95
  - !ruby/object:Gem::Version
116
96
  version: '0'
117
- none: false
97
+ - !ruby/object:Gem::Dependency
98
+ name: capybara
118
99
  requirement: !ruby/object:Gem::Requirement
119
100
  requirements:
120
101
  - - '>='
121
102
  - !ruby/object:Gem::Version
122
103
  version: '0'
123
- none: false
124
- prerelease: false
125
104
  type: :development
126
- - !ruby/object:Gem::Dependency
127
- name: poltergeist
105
+ prerelease: false
128
106
  version_requirements: !ruby/object:Gem::Requirement
129
107
  requirements:
130
108
  - - '>='
131
109
  - !ruby/object:Gem::Version
132
110
  version: '0'
133
- none: false
111
+ - !ruby/object:Gem::Dependency
112
+ name: poltergeist
134
113
  requirement: !ruby/object:Gem::Requirement
135
114
  requirements:
136
115
  - - '>='
137
116
  - !ruby/object:Gem::Version
138
117
  version: '0'
139
- none: false
140
- prerelease: false
141
118
  type: :development
142
- - !ruby/object:Gem::Dependency
143
- name: awesome_print
119
+ prerelease: false
144
120
  version_requirements: !ruby/object:Gem::Requirement
145
121
  requirements:
146
122
  - - '>='
147
123
  - !ruby/object:Gem::Version
148
124
  version: '0'
149
- none: false
125
+ - !ruby/object:Gem::Dependency
126
+ name: awesome_print
150
127
  requirement: !ruby/object:Gem::Requirement
151
128
  requirements:
152
129
  - - '>='
153
130
  - !ruby/object:Gem::Version
154
131
  version: '0'
155
- none: false
156
- prerelease: false
157
132
  type: :development
158
- - !ruby/object:Gem::Dependency
159
- name: sinatra-contrib
133
+ prerelease: false
160
134
  version_requirements: !ruby/object:Gem::Requirement
161
135
  requirements:
162
136
  - - '>='
163
137
  - !ruby/object:Gem::Version
164
138
  version: '0'
165
- none: false
139
+ - !ruby/object:Gem::Dependency
140
+ name: sinatra-contrib
166
141
  requirement: !ruby/object:Gem::Requirement
167
142
  requirements:
168
143
  - - '>='
169
144
  - !ruby/object:Gem::Version
170
145
  version: '0'
171
- none: false
172
- prerelease: false
173
146
  type: :development
174
- description: Lumber tries to make it easy to use the more robust log4r logging system within your rails application. To do this it sets up log4r configuration from a yml file, and provides utility methods for adding a :logger accessor to classes dynamicaly as they get created.
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - '>='
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ description: Lumber tries to make it easy to use the more robust log4r logging system
154
+ within your rails application. To do this it sets up log4r configuration from a
155
+ yml file, and provides utility methods for adding a :logger accessor to classes
156
+ dynamicaly as they get created.
175
157
  email:
176
158
  - matt@conwaysplace.com
177
159
  executables: []
@@ -193,6 +175,7 @@ files:
193
175
  - generators/lumber/lumber_generator.rb
194
176
  - generators/lumber/templates/log4r.yml
195
177
  - lib/lumber.rb
178
+ - lib/lumber/json_formatter.rb
196
179
  - lib/lumber/level_util.rb
197
180
  - lib/lumber/log4r.rb
198
181
  - lib/lumber/logger_support.rb
@@ -213,6 +196,7 @@ files:
213
196
  - lib/lumber/server/views/levels.erb
214
197
  - lib/lumber/version.rb
215
198
  - lumber.gemspec
199
+ - spec/json_formatter_spec.rb
216
200
  - spec/level_util_spec.rb
217
201
  - spec/logger_support_spec.rb
218
202
  - spec/lumber_spec.rb
@@ -222,7 +206,8 @@ files:
222
206
  homepage: http://github.com/wr0ngway/lumber
223
207
  licenses:
224
208
  - MIT
225
- post_install_message:
209
+ metadata: {}
210
+ post_install_message:
226
211
  rdoc_options: []
227
212
  require_paths:
228
213
  - lib
@@ -230,30 +215,24 @@ required_ruby_version: !ruby/object:Gem::Requirement
230
215
  requirements:
231
216
  - - '>='
232
217
  - !ruby/object:Gem::Version
233
- segments:
234
- - 0
235
- hash: 2
236
218
  version: '0'
237
- none: false
238
219
  required_rubygems_version: !ruby/object:Gem::Requirement
239
220
  requirements:
240
221
  - - '>='
241
222
  - !ruby/object:Gem::Version
242
- segments:
243
- - 0
244
- hash: 2
245
223
  version: '0'
246
- none: false
247
224
  requirements: []
248
- rubyforge_project:
249
- rubygems_version: 1.8.24
250
- signing_key:
251
- specification_version: 3
225
+ rubyforge_project:
226
+ rubygems_version: 2.0.6
227
+ signing_key:
228
+ specification_version: 4
252
229
  summary: Lumber integrates the log4r logging system within your application.
253
230
  test_files:
231
+ - spec/json_formatter_spec.rb
254
232
  - spec/level_util_spec.rb
255
233
  - spec/logger_support_spec.rb
256
234
  - spec/lumber_spec.rb
257
235
  - spec/server_spec.rb
258
236
  - spec/spec.opts
259
237
  - spec/spec_helper.rb
238
+ has_rdoc: