low 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,66 @@
1
+ module Low
2
+ module Middleware
3
+ # `RequestLogger` set the env key "logger" to an instance of
4
+ # `Low::ScopedLogger`, with various attributes set according to the state
5
+ # of the request:
6
+ # * _IO_: if RACK_ENV is development or test, use an eponymous file in
7
+ # the log directory, otherwise use STDOUT (as Heroku likes).
8
+ # * _log_level_: If set, use the LOG_LEVEL environment variable value;
9
+ # otherwise, use INFO.
10
+ # * _group_key_: Use request_id env value.
11
+ class RequestLogger
12
+ def self.level
13
+ # If `LOG_LEVEL` is a valid level other than INFO,
14
+ if ['FATAL', 'ERROR', 'WARN', 'DEBUG'].include? ENV['LOG_LEVEL']
15
+ # use it;
16
+ eval "::Logger::#{ENV['LOG_LEVEL']}"
17
+ else
18
+ # otherwise, use `::Logger::INFO`
19
+ ::Logger::INFO
20
+ end
21
+ end
22
+
23
+ def self.io
24
+ # If `RACK_ENV` is development or test,
25
+ if ['development', 'test'].include? ENV['RACK_ENV']
26
+ # make sure the log directory exists,
27
+ Dir.mkdir('log') unless Dir.exists?('log')
28
+
29
+ # and log to the appropriate file;
30
+ File.open("log/#{ENV['RACK_ENV']}.log", 'a')
31
+ else
32
+ # otherwise, log to STDOUT (Heroku likes it this way).
33
+ STDOUT
34
+ end
35
+ end
36
+
37
+ DEFAULT_KEY = 'logger'
38
+
39
+ def initialize(app, opts = {})
40
+ @app = app
41
+ @key = opts[:key] || DEFAULT_KEY
42
+ end
43
+
44
+ def call(env)
45
+ # Set the 'rack.errors' environment key to the above `Logger.io`
46
+ # (other rack components, such as Sinatra, use this),
47
+ env['rack.errors'] = Logger.io
48
+
49
+ # instantiate a new `Useless::Logger`,
50
+ logger = Useless::Logger.new(env['rack.errors'])
51
+
52
+ # set the logger level to the above `Logger.level`,
53
+ logger.level = Logger.level
54
+
55
+ # set the request_id if one is available
56
+ logger.scope_key = env['request_id']
57
+
58
+ # add it to the env,
59
+ env[@key] = logger
60
+
61
+ # and call the app
62
+ @app.call(env)
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,48 @@
1
+ require 'logger'
2
+
3
+ module Low
4
+ # `Low::ScopedLogger` is a tiny wrapper around `Logger`. It allows
5
+ # `scope` to be specified, making it easy to grep any messages generated
6
+ # by a particular instance.
7
+ class ScopedLogger
8
+ attr_accessor :scope
9
+
10
+ def initialize(io = $stdout)
11
+ @logger = ::Logger.new(io)
12
+ end
13
+
14
+ def level=(level)
15
+ @logger.level = level
16
+ end
17
+
18
+ def level
19
+ @logger.level
20
+ end
21
+
22
+ def fatal(message = nil, progname = nil, &block)
23
+ add ::Logger::FATAL, message, progname, &block
24
+ end
25
+
26
+ def error(message = nil, progname = nil, &block)
27
+ add ::Logger::ERROR, message, progname, &block
28
+ end
29
+
30
+ def warn(message = nil, progname = nil, &block)
31
+ add ::Logger::WARN, message, progname, &block
32
+ end
33
+
34
+ def info(message = nil, progname = nil, &block)
35
+ add ::Logger::INFO, message, progname, &block
36
+ end
37
+
38
+ def debug(message = nil, progname = nil, &block)
39
+ add ::Logger::DEBUG, message, progname, &block
40
+ end
41
+
42
+ def add(level, message = nil, progname = nil, &block)
43
+ formatted_message = message
44
+ formatted_message = "[#{@scope}] #{formatted_message}" if @scope
45
+ @logger.add level, formatted_message, progname, &block
46
+ end
47
+ end
48
+ end
data/lib/low/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Low
2
- VERSION = '0.0.6'
2
+ VERSION = '0.0.7'
3
3
  end
data/lib/low.rb CHANGED
@@ -1,9 +1,11 @@
1
1
  require 'low/version'
2
2
 
3
3
  module Low
4
+ autoload :ScopedLogger, 'low/scoped_logger'
4
5
  autoload :Mongo, 'low/mongo'
5
6
 
6
7
  module Middleware
7
- autoload :SubdomainMap, 'low/middleware/subdomain_map'
8
+ autoload :RequestLogger, 'low/middleware/request_logger'
9
+ autoload :SubdomainMap, 'low/middleware/subdomain_map'
8
10
  end
9
11
  end
@@ -0,0 +1,61 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+ require 'logger'
3
+
4
+ describe Low::Middleware::RequestLogger do
5
+ describe '.level' do
6
+ it 'should return Logger::FATAL if the LOG_LEVEL evironment var is \'FATAL\'' do
7
+ ENV['LOG_LEVEL'] = 'FATAL'
8
+ Low::Middleware::RequestLogger.level.should == Logger::FATAL
9
+ end
10
+
11
+ it 'should return Logger::ERROR if the LOG_LEVEL evironment var is \'ERROR\'' do
12
+ ENV['LOG_LEVEL'] = 'ERROR'
13
+ Low::Middleware::RequestLogger.level.should == Logger::ERROR
14
+ end
15
+
16
+ it 'should return Logger::WARN if the LOG_LEVEL evironment var is \'WARN\'' do
17
+ ENV['LOG_LEVEL'] = 'WARN'
18
+ Low::Middleware::RequestLogger.level.should == Logger::WARN
19
+ end
20
+
21
+ it 'should return Logger::INFO if the LOG_LEVEL evironment var is \'INFO\'' do
22
+ ENV['LOG_LEVEL'] = 'INFO'
23
+ Low::Middleware::RequestLogger.level.should == Logger::INFO
24
+ end
25
+
26
+ it 'should return Logger::DEBUG if the LOG_LEVEL evironment var is \'DEBUG\'' do
27
+ ENV['LOG_LEVEL'] = 'DEBUG'
28
+ Low::Middleware::RequestLogger.level.should == Logger::DEBUG
29
+ end
30
+
31
+ it 'should return Logger::INFO if the LOG_LEVEL evironment var is not set' do
32
+ ENV['LOG_LEVEL'] = nil
33
+ Low::Middleware::RequestLogger.level.should == Logger::INFO
34
+ end
35
+ end
36
+
37
+ describe '.io' do
38
+ it 'should return \'log/development.log\' if the RACK_ENV evironment var is \'development\'' do
39
+ begin
40
+ ENV['RACK_ENV'] = 'development'
41
+ Low::Middleware::RequestLogger.io.path.should == 'log/development.log'
42
+ ensure
43
+ ENV['RACK_ENV'] = 'test'
44
+ end
45
+ end
46
+
47
+ it 'should return \'log/test.log\' if the RACK_ENV evironment var is \'test\'' do
48
+ ENV['RACK_ENV'] = 'test'
49
+ Low::Middleware::RequestLogger.io.path.should == 'log/test.log'
50
+ end
51
+
52
+ it 'should return STDOUT if the RACK_ENV evironment var is \'production\'' do
53
+ begin
54
+ ENV['RACK_ENV'] = 'production'
55
+ Low::Middleware::RequestLogger.io.should == STDOUT
56
+ ensure
57
+ ENV['RACK_ENV'] = 'test'
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,86 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Low::ScopedLogger do
4
+ describe '#fatal' do
5
+ it 'should emit a fatal message' do
6
+ io = StringIO.new
7
+ logger = Low::ScopedLogger.new(io)
8
+ logger.fatal 'Oh noes!'
9
+
10
+ io.rewind; message = io.read
11
+ message.should =~ /FATAL/
12
+ message.should =~ /Oh noes!$/
13
+ end
14
+ end
15
+
16
+ describe '#error' do
17
+ it 'should emit an error message' do
18
+ io = StringIO.new
19
+ logger = Low::ScopedLogger.new(io)
20
+ logger.error 'Wrong!'
21
+
22
+ io.rewind; message = io.read
23
+ message.should =~ /ERROR/
24
+ message.should =~ /Wrong!$/
25
+ end
26
+ end
27
+
28
+ describe '#warn' do
29
+ it 'should emit a warn message' do
30
+ io = StringIO.new
31
+ logger = Low::ScopedLogger.new(io)
32
+ logger.warn 'Watchout!'
33
+
34
+ io.rewind; message = io.read
35
+ message.should =~ /WARN/
36
+ message.should =~ /Watchout!$/
37
+ end
38
+ end
39
+
40
+ describe '#info' do
41
+ it 'should emit an info message' do
42
+ io = StringIO.new
43
+ logger = Low::ScopedLogger.new(io)
44
+ logger.info 'Such and such'
45
+
46
+ io.rewind; message = io.read
47
+ message.should =~ /INFO/
48
+ message.should =~ /Such and such$/
49
+ end
50
+ end
51
+
52
+ describe '#debug' do
53
+ it 'should emit a debug message' do
54
+ io = StringIO.new
55
+ logger = Low::ScopedLogger.new(io)
56
+ logger.debug '101011'
57
+
58
+ io.rewind; message = io.read
59
+ message.should =~ /DEBUG/
60
+ message.should =~ /101011$/
61
+ end
62
+
63
+ it 'should emit nothing if the level is too high' do
64
+ io = StringIO.new
65
+ logger = Low::ScopedLogger.new(io)
66
+ logger.level = ::Logger::INFO
67
+ logger.debug '101011'
68
+
69
+ io.rewind; message = io.read
70
+ message.should == ''
71
+ end
72
+ end
73
+
74
+ describe '#group_key' do
75
+ it 'should append the specified key to all messages' do
76
+ io = StringIO.new
77
+ logger = Low::ScopedLogger.new(io)
78
+ logger.scope = 'abc123'
79
+ logger.info 'Yadda'
80
+
81
+ io.rewind; message = io.read
82
+ message.should =~ /abc123/
83
+ message.should =~ /Yadda$/
84
+ end
85
+ end
86
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: low
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -105,15 +105,19 @@ files:
105
105
  - README.md
106
106
  - Rakefile
107
107
  - lib/low.rb
108
+ - lib/low/middleware/request_logger.rb
108
109
  - lib/low/middleware/subdomain_map.rb
109
110
  - lib/low/mongo.rb
110
111
  - lib/low/mongo/heroku.rb
111
112
  - lib/low/mongo/util.rb
113
+ - lib/low/scoped_logger.rb
112
114
  - lib/low/version.rb
113
115
  - low.gemspec
116
+ - spec/low/middleware/request_logger_spec.rb
114
117
  - spec/low/middleware/subdomain_map_spec.rb
115
118
  - spec/low/mongo/util_spec.rb
116
119
  - spec/low/mongo_spec.rb
120
+ - spec/low/scoped_logger_spec.rb
117
121
  - spec/spec_helper.rb
118
122
  homepage: ''
119
123
  licenses: []
@@ -140,7 +144,9 @@ signing_key:
140
144
  specification_version: 3
141
145
  summary: A low-level utility library.
142
146
  test_files:
147
+ - spec/low/middleware/request_logger_spec.rb
143
148
  - spec/low/middleware/subdomain_map_spec.rb
144
149
  - spec/low/mongo/util_spec.rb
145
150
  - spec/low/mongo_spec.rb
151
+ - spec/low/scoped_logger_spec.rb
146
152
  - spec/spec_helper.rb