lookout-rack-utils 4.0.0.44 → 5.0.0.49
Sign up to get free protection for your applications and to get access to all the features.
- 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: ''
|