lookout-rack-utils 4.0.0.44 → 5.0.0.49
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 +5 -5
- data/.travis.yml +1 -1
- data/README.md +11 -2
- data/lib/lookout/rack/utils/log.rb +100 -64
- data/lib/lookout/rack/utils/version.rb +1 -1
- data/lookout-rack-utils.gemspec +1 -1
- data/spec/log_spec.rb +59 -2
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 07ec222e8dfb77be261665631a968c43ec2f4a96e480ec7526315884a9c7518f
|
4
|
+
data.tar.gz: 5b8203b6bccc84e42275726154290f991e3fdbdcee903d8ee4e4d34a4be2f72c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b04ac7ce56b5b97da144db91eed4348b4282a670954e38f62bc47e8027de3c742b015a3c4ab0f3b1fb6fa9e1bd1aa62336ff759661a46f5cbb2cb01272fcd80c
|
7
|
+
data.tar.gz: 6dd0b2f45b7c1ccec1240b83eccbff9033114043bcb9f4060f94655032cd8254bf88da0865283220f3fa6c0d0334e9e23f2e928d5ece75eba7405679efbf8832
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -59,8 +59,17 @@ app:
|
|
59
59
|
Note that we expect `t(*args)` to be called in the context of a request.
|
60
60
|
|
61
61
|
### Lookout::Rack::Utils::Log
|
62
|
-
|
63
|
-
|
62
|
+
|
63
|
+
The logger can be configured with
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
Lookout::Rack::Utils::Log.set_instance(my_logger)
|
67
|
+
```
|
68
|
+
|
69
|
+
By default it will use a Lookout::Rack::Utils::LookoutLogger, which
|
70
|
+
wraps Log4R. You'll need configatron set up. If
|
71
|
+
`Lookout::Rack::Utils::Graphite` is present, it will increment those
|
72
|
+
stats whenever a log is written.
|
64
73
|
|
65
74
|
```ruby
|
66
75
|
configatron.project_name = 'My project name'
|
@@ -1,90 +1,126 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'log4r'
|
3
|
-
require 'singleton'
|
4
3
|
require 'time'
|
4
|
+
require 'thread'
|
5
5
|
require 'configatron'
|
6
6
|
|
7
7
|
module Lookout::Rack::Utils
|
8
|
-
# Logging.
|
8
|
+
# Logging. By default, logs to log/<project_name>.log with the format:
|
9
9
|
#
|
10
10
|
# [Log Level]: [Timestamp (ISO-8601)]: [File:linenum]: [Log Message]
|
11
11
|
#
|
12
12
|
# Use through the helper:
|
13
13
|
# log.warn 'This is my log message'
|
14
14
|
#
|
15
|
+
# Default logger may be replaced by calling
|
16
|
+
#
|
17
|
+
# Log.set_instance(my_logger)
|
15
18
|
class Log
|
16
|
-
|
17
|
-
include Log4r
|
19
|
+
@@instance = nil
|
18
20
|
|
19
|
-
#
|
20
|
-
#
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
# Initialize singleton instance to be an instance of
|
22
|
+
# +Lookout::Rack::Utils::LookoutLogger+, with the given options
|
23
|
+
def self.create_instance
|
24
|
+
raise "Already initialized Log" if instance_set?
|
25
|
+
@@instance = LookoutLogger.new
|
26
|
+
end
|
27
|
+
|
28
|
+
# Explicitly set singleton instance. The instance must implement the
|
29
|
+
# same base API as +::Logger+
|
30
|
+
def self.set_instance(instance)
|
31
|
+
raise "Already initialized Log" if instance_set?
|
32
|
+
@@instance = instance
|
33
|
+
end
|
34
|
+
|
35
|
+
# Clear singleton instance, for use in testing ONLY
|
36
|
+
def self.clear_instance
|
37
|
+
@@instance = nil
|
38
|
+
end
|
39
|
+
|
40
|
+
# Check if the instance has been set
|
41
|
+
def self.instance_set?
|
42
|
+
defined?(@@instance) && !!@@instance
|
43
|
+
end
|
44
|
+
|
45
|
+
# Access singleton instance, which must have been initialized with
|
46
|
+
# .create_instance or .set_instance
|
47
|
+
def self.instance
|
48
|
+
create_instance if @@instance.nil?
|
49
|
+
@@instance
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Formatter that include the filename and relative path, and line number in
|
54
|
+
# output of the caller.
|
55
|
+
#
|
56
|
+
# Since all callers go through the methods defined in this class to log, we
|
57
|
+
# look at the second line of the tracer output, removing everything but the
|
58
|
+
# directories after the project directory.
|
59
|
+
#
|
60
|
+
class LookoutFormatter < Log4r::Formatter
|
61
|
+
# Return the project base directory for filtering to help with
|
62
|
+
# identifiying the filename and line number when formatting the log
|
63
|
+
# message
|
25
64
|
#
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
#
|
31
|
-
# @return [String] Base directory for the project
|
32
|
-
def basedir
|
33
|
-
@basedir ||= File.expand_path(File.join(File.dirname(__FILE__), ".."))
|
34
|
-
end
|
65
|
+
# @return [String] Base directory for the project
|
66
|
+
def basedir
|
67
|
+
@basedir ||= File.expand_path(File.join(File.dirname(__FILE__), ".."))
|
68
|
+
end
|
35
69
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
end
|
56
|
-
# If there were no common directories (besides /), return our basedir
|
57
|
-
@common_basedir = (i <= 1) ? basedir : basedir_pieces[0...i].join(File::SEPARATOR)
|
70
|
+
# Return the common base directory between this project and the
|
71
|
+
# given trace. If no common base directory is found, return
|
72
|
+
# basedir.
|
73
|
+
#
|
74
|
+
# This memoizes the result, which can be bad if the first log
|
75
|
+
# comes from an unusual place. However, in all current uses this
|
76
|
+
# is running from an unpacked jar/war and its vastly faster to
|
77
|
+
# memoize the result.
|
78
|
+
#
|
79
|
+
# @param [String] tracer A line from the LogEvent#tracer Array
|
80
|
+
# @return [String] Common base directory with the trace
|
81
|
+
def common_basedir(tracer)
|
82
|
+
return @common_basedir if @common_basedir
|
83
|
+
|
84
|
+
basedir_pieces = basedir.split(File::SEPARATOR)
|
85
|
+
trace_pieces = tracer.split(File::SEPARATOR)
|
86
|
+
i = 0
|
87
|
+
while basedir_pieces[i] == trace_pieces[i]
|
88
|
+
i += 1
|
58
89
|
end
|
90
|
+
# If there were no common directories (besides /), return our basedir
|
91
|
+
@common_basedir = (i <= 1) ? basedir : basedir_pieces[0...i].join(File::SEPARATOR)
|
92
|
+
end
|
59
93
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
end
|
72
|
-
return parts[-1] if parts
|
94
|
+
# Return a trimmed version of the filename from where a LogEvent occurred
|
95
|
+
# @param [String] tracer A line from the LogEvent#tracer Array
|
96
|
+
# @return [String] Trimmed and parsed version of the file and line number
|
97
|
+
def event_filename(tracer)
|
98
|
+
base = common_basedir(tracer)
|
99
|
+
parts = tracer.match(/#{base}\/(.*:[0-9]+).*:/)
|
100
|
+
|
101
|
+
# If we get no matches back, we're probably in a jar file in which case
|
102
|
+
# the format of the tracer is going to be abbreviated
|
103
|
+
if parts.nil?
|
104
|
+
parts = tracer.match(/(.*:[0-9]+).*:/)
|
73
105
|
end
|
106
|
+
return parts[-1] if parts
|
107
|
+
end
|
74
108
|
|
75
|
-
|
76
|
-
|
77
|
-
|
109
|
+
# Receive the LogEvent and pull out the log message and format it for
|
110
|
+
# display in the logs
|
111
|
+
#
|
78
112
|
# @param [Log4r::LogEvent] event
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
end
|
113
|
+
# @return [String] Formatted log message
|
114
|
+
def format(event)
|
115
|
+
filename = event_filename(event.tracer[1])
|
116
|
+
# CCYY-MM-DDThh:mm:ss.sssTZD
|
117
|
+
time = Time.now.utc.iso8601 3
|
118
|
+
return "#{Log4r::LNAMES[event.level]}: #{time}: #{filename}: #{event.data}\n"
|
86
119
|
end
|
120
|
+
end
|
87
121
|
|
122
|
+
class LookoutLogger
|
123
|
+
include Log4r
|
88
124
|
|
89
125
|
attr_reader :outputter
|
90
126
|
|
data/lookout-rack-utils.gemspec
CHANGED
@@ -23,7 +23,7 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_development_dependency "rspec", "~> 3.0"
|
24
24
|
spec.add_development_dependency "rspec-its"
|
25
25
|
spec.add_development_dependency "rack-test"
|
26
|
-
spec.add_development_dependency "sinatra"
|
26
|
+
spec.add_development_dependency "sinatra", '~> 2.0'
|
27
27
|
spec.add_development_dependency "timecop"
|
28
28
|
|
29
29
|
spec.add_runtime_dependency "i18n"
|
data/spec/log_spec.rb
CHANGED
@@ -4,7 +4,64 @@ require 'timecop'
|
|
4
4
|
require 'configatron'
|
5
5
|
|
6
6
|
describe Lookout::Rack::Utils::Log do
|
7
|
-
|
7
|
+
before(:each) do
|
8
|
+
described_class.clear_instance
|
9
|
+
end
|
10
|
+
|
11
|
+
after(:each) do
|
12
|
+
described_class.clear_instance
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '.create_instance' do
|
16
|
+
it 'creates an instance' do
|
17
|
+
described_class.create_instance
|
18
|
+
expect(described_class.instance).to be_a(Lookout::Rack::Utils::LookoutLogger)
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'if an instance has been created' do
|
22
|
+
before :each do
|
23
|
+
described_class.create_instance
|
24
|
+
end
|
25
|
+
it 'raises if called twice' do
|
26
|
+
expect { described_class.create_instance }.to raise_error /Already initialized/
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '.set_instance' do
|
32
|
+
let(:instance) { double('Logger') }
|
33
|
+
|
34
|
+
it 'sets instance' do
|
35
|
+
described_class.set_instance(instance)
|
36
|
+
expect(described_class.instance).to eq instance
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'if an instance has been created' do
|
40
|
+
before :each do
|
41
|
+
described_class.set_instance(instance)
|
42
|
+
end
|
43
|
+
it 'raises if called twice' do
|
44
|
+
expect { described_class.set_instance(instance) }.to raise_error /Already initialized/
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe '.instance' do
|
50
|
+
let(:instance) { double('Logger') }
|
51
|
+
|
52
|
+
it 'creates default instance if not set' do
|
53
|
+
expect(described_class.instance).to be_a(Lookout::Rack::Utils::LookoutLogger)
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'returns set instance if set' do
|
57
|
+
described_class.set_instance(instance)
|
58
|
+
expect(described_class.instance).to eq(instance)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe Lookout::Rack::Utils::LookoutLogger do
|
64
|
+
subject(:log) { described_class.new }
|
8
65
|
let(:log_message) { 'foo' }
|
9
66
|
let(:filename) { "log" }
|
10
67
|
let(:exclude_levels) { [] }
|
@@ -90,7 +147,7 @@ describe Lookout::Rack::Utils::Log do
|
|
90
147
|
end
|
91
148
|
end
|
92
149
|
|
93
|
-
describe Lookout::Rack::Utils::
|
150
|
+
describe Lookout::Rack::Utils::LookoutFormatter do
|
94
151
|
subject(:formatter) { described_class.new }
|
95
152
|
let(:logger) do
|
96
153
|
logger = double('Mock Logger')
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lookout-rack-utils
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.0.49
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ian Smith
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-12-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -84,16 +84,16 @@ dependencies:
|
|
84
84
|
name: sinatra
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - "
|
87
|
+
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
89
|
+
version: '2.0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - "
|
94
|
+
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
96
|
+
version: '2.0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: timecop
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -241,7 +241,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
241
241
|
version: '0'
|
242
242
|
requirements: []
|
243
243
|
rubyforge_project:
|
244
|
-
rubygems_version: 2.
|
244
|
+
rubygems_version: 2.7.8
|
245
245
|
signing_key:
|
246
246
|
specification_version: 4
|
247
247
|
summary: ''
|