unicorn-cuba-base 1.1.2 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -15,4 +15,5 @@ group :development do
15
15
  gem "rspec", "~> 2.13"
16
16
  gem "rdoc", "~> 3.9"
17
17
  gem "jeweler", "~> 1.8.4"
18
+ gem "capture-output", "~> 1.0"
18
19
  end
data/Gemfile.lock CHANGED
@@ -1,6 +1,7 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
+ capture-output (1.0.0)
4
5
  cli (1.3.1)
5
6
  cuba (3.1.0)
6
7
  rack
@@ -37,6 +38,7 @@ PLATFORMS
37
38
  ruby
38
39
 
39
40
  DEPENDENCIES
41
+ capture-output (~> 1.0)
40
42
  cli (~> 1.3)
41
43
  cuba (~> 3.0)
42
44
  facter (~> 1.6.11)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.2
1
+ 1.2.0
@@ -1,4 +1,6 @@
1
- class DefaultErrorReporter < Controler
1
+ require 'pp'
2
+
3
+ class DefaultErrorReporter < Controller
2
4
  self.define do
3
5
  on error Rack::UnhandledRequest::UnhandledRequestError do |error|
4
6
  write_error 404, error
@@ -9,6 +11,10 @@ class DefaultErrorReporter < Controler
9
11
  raise error
10
12
  end
11
13
 
14
+ on error URI::InvalidURIError do |error|
15
+ write_error 400, error
16
+ end
17
+
12
18
  on error StandardError do |error|
13
19
  log.error "unhandled error while processing request: #{env['REQUEST_METHOD']} #{env['SCRIPT_NAME']}[#{env["PATH_INFO"]}]", error
14
20
  log.debug {
@@ -0,0 +1,15 @@
1
+ module Rack
2
+ class CommonLoggerXID < Rack::CommonLogger
3
+ def log(env, *args)
4
+ # this is called after body was sent so it won't be in scope of XIDLogging - setting xid again
5
+ xid = env['xid'] && env['xid'].first.last
6
+ if xid
7
+ @logger.with_meta_context(xid: xid) do
8
+ super(env, *args)
9
+ end
10
+ else
11
+ super(env, *args)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,5 +1,3 @@
1
- require 'pp'
2
-
3
1
  module Rack
4
2
  class ErrorHandling
5
3
  def initialize(app, &block)
@@ -22,7 +20,7 @@ module Rack
22
20
 
23
21
  return @app.call(env)
24
22
  rescue
25
- raise
23
+ raise
26
24
  end
27
25
  end
28
26
  end
@@ -0,0 +1,24 @@
1
+ module Rack
2
+ class XIDLogging
3
+ def initialize(app, root_logger, header_name = 'XID', &block)
4
+ @root_logger = root_logger
5
+ @header_name = header_name
6
+ @app = app
7
+ end
8
+
9
+ def call(env)
10
+ begin
11
+ xid = env["HTTP_#{@header_name.upcase.tr('-', '_')}"]
12
+ if xid
13
+ env['xid'] = {@header_name => xid}
14
+ @root_logger.with_meta_context(xid: xid) do
15
+ return @app.call(env)
16
+ end
17
+ else
18
+ return @app.call(env)
19
+ end
20
+ ensure
21
+ end
22
+ end
23
+ end
24
+ end
@@ -6,10 +6,7 @@ class RootLogger < Logger
6
6
 
7
7
  def initialize(root_logger, class_obj)
8
8
  @root_logger = root_logger
9
- @progname = class_obj.name
10
- @root_logger.formatter = proc do |severity, datetime, progname, msg|
11
- "[#{datetime.utc.strftime "%Y-%m-%d %H:%M:%S.%6N %Z"}] [#{$$} #{progname}] #{severity}: #{msg}\n"
12
- end
9
+ @class_name = class_obj.name
13
10
  end
14
11
 
15
12
  def respond_to?(method)
@@ -18,22 +15,24 @@ class RootLogger < Logger
18
15
 
19
16
  def method_missing(name, *args, &block)
20
17
  if @@levels.include? name
21
- message = if block_given?
22
- self.progname
18
+ root_logger = @root_logger.with_meta('className' => @class_name)
19
+
20
+ if block
21
+ root_logger.send(name, &block)
23
22
  else
24
- args.map do |arg|
25
- if arg.is_a? Exception
26
- "#{arg.class.name}: #{arg.message}\n#{arg.backtrace.join("\n")}"
27
- else
28
- arg.to_s
29
- end
30
- end.join(': ')
31
- end
23
+ message = args.first
24
+
25
+ if args.last.is_a? Exception
26
+ error = args.last
27
+ root_logger = root_logger.with_meta('exceptionClass' => error.class.name)
28
+ message = "#{message}: #{error.class.name}: #{error.message}\n#{error.backtrace.join("\n")}"
29
+ end
32
30
 
33
- # set program name to current class
34
- @root_logger.progname = @progname
35
- @root_logger.send(name, message.chomp, &block)
31
+ # log with class name
32
+ root_logger.send(name, message.chomp, &block)
33
+ end
36
34
  else
35
+ # forward to root logger
37
36
  @root_logger.send(name, *args, &block)
38
37
  end
39
38
  end
@@ -45,6 +44,50 @@ class RootLogger < Logger
45
44
  end
46
45
  end
47
46
 
47
+ class MetaData < Hash
48
+ def initialize(parent = nil)
49
+ @parent = parent
50
+ end
51
+
52
+ attr_accessor :parent
53
+
54
+ def to_s
55
+ chain = []
56
+ parent = self
57
+ while parent
58
+ chain << parent
59
+ parent = parent.parent
60
+ end
61
+
62
+ hash = {}
63
+
64
+ chain.reverse.each do |child|
65
+ hash.merge! child
66
+ end
67
+
68
+ "[meta #{hash.map{|k, v| "#{k}=\"#{v.to_s.tr('"', "'")}\""}.join(' ')}]"
69
+ end
70
+ end
71
+
72
+ def initialize(logdev = STDERR, &formatter)
73
+ super(logdev)
74
+
75
+ @ext_formatter = proc do |severity, datetime, progname, meta, msg|
76
+ if formatter
77
+ formatter.call(severity, datetime, progname, meta, msg)
78
+ else
79
+ "#{datetime.utc.strftime "%Y-%m-%d %H:%M:%S.%6N %Z"} #{meta.to_s} #{severity}: #{msg}\n"
80
+ end
81
+ end
82
+
83
+ @meta = MetaData.new
84
+ @meta['pid'] = $$
85
+
86
+ self.formatter = proc do |severity, datetime, progname, msg|
87
+ @ext_formatter.call(severity, datetime, progname, @meta, msg)
88
+ end
89
+ end
90
+
48
91
  def logger_for(class_obj)
49
92
  ClassLogger.new(self, class_obj)
50
93
  end
@@ -53,11 +96,87 @@ class RootLogger < Logger
53
96
  self
54
97
  end
55
98
 
99
+ attr_accessor :meta
100
+
101
+ def with_meta(hash)
102
+ n = self.dup
103
+ n.meta = MetaData.new(@meta)
104
+ n.meta.merge! hash
105
+
106
+ # capture new meta hash with this new formatter proc - needed since old formatter proc will point to old object
107
+ n.formatter = proc do |severity, datetime, progname, msg|
108
+ @ext_formatter.call(severity, datetime, progname, n.meta, msg)
109
+ end
110
+ n
111
+ end
112
+
113
+ def with_meta_context(hash)
114
+ old_meta = @meta
115
+ new_meta = MetaData.new(old_meta)
116
+ new_meta.merge! hash
117
+
118
+ begin
119
+ @meta = new_meta
120
+ yield
121
+ ensure
122
+ @meta = old_meta
123
+ end
124
+ end
125
+
56
126
  def inspect
57
127
  "#<RootLogger #{"0x%X" % object_id}>"
58
128
  end
59
129
  end
60
130
 
131
+ class SyslogLogDev
132
+ def initialize(program_name, facility = 'daemon', log_to_stderr = false)
133
+ require 'syslog'
134
+
135
+ facility = "LOG_#{facility.upcase}".to_sym
136
+ Syslog.constants.include? facility or fail "No such syslog facility: #{facility}"
137
+ facility = Syslog.const_get facility
138
+
139
+ @log_level_mapping = Hash[%w{DEBUG INFO WARN ERROR FATAL}.zip(
140
+ [Syslog::LOG_DEBUG, Syslog::LOG_INFO, Syslog::LOG_WARNING, Syslog::LOG_ERR, Syslog::LOG_CRIT]
141
+ )]
142
+ @log_level_mapping.default = Syslog::LOG_NOTICE
143
+
144
+ flags = Syslog::LOG_PID | Syslog::LOG_NDELAY
145
+
146
+ if log_to_stderr
147
+ STDERR.sync = true
148
+ flags |= Syslog::LOG_PERROR
149
+ end
150
+
151
+ @syslog = Syslog.open(program_name, flags, facility)
152
+ end
153
+
154
+ def write(msg)
155
+ log_level, msg = *msg.match(/([^ ]+) (.*)/m).captures
156
+ @syslog.log(@log_level_mapping[log_level], "%s", msg.chomp)
157
+ end
158
+
159
+ def close
160
+ @syslog.close
161
+ end
162
+ end
163
+
164
+ class RootSyslogLogger < RootLogger
165
+ def initialize(program_name, facility = 'daemon', log_to_stderr = false)
166
+ super(SyslogLogDev.new(program_name, facility, log_to_stderr)) do |severity, datetime, progname, meta, msg|
167
+ # provide severity to SyslogLogDev
168
+ "#{severity} #{meta} #{msg}\n"
169
+ end
170
+
171
+ @meta.delete 'pid' # pid is already within syslog message header
172
+ end
173
+
174
+ # used when obj is used as log device (access logs)
175
+ def write(msg)
176
+ info(msg)
177
+ end
178
+ end
179
+
61
180
  module ClassLogging
62
181
  module ClassMethods
63
182
  def init_logger
@@ -69,22 +188,16 @@ module ClassLogging
69
188
  end
70
189
 
71
190
  def log
72
- unless @@logger[self]
73
- new_root_logger = false
74
- # use root logger from ancestor or create new one
75
- root_logger =
76
- if logging_class = ancestors.find{|an| an != self and an.respond_to? :log}
77
- logging_class.log.respond_to?(:root_logger) ? logging_class.log.root_logger : logging_class.log
78
- else
79
- new_root_logger = true
80
- Logger.new(STDERR)
191
+ unless @@logger.include? self
192
+ root_logger = if an = ancestors.find{|an| an != self and an.respond_to? :log and an.log.respond_to? :root_logger}
193
+ an.log.root_logger
194
+ else
195
+ RootLogger.new.tap do |logger|
196
+ logger.warn 'no root logger found; using default logger'
81
197
  end
198
+ end
82
199
 
83
- root_logger.kind_of? RootLogger::ClassLogger and fail "got ClassLogger root logger: #{self}"
84
-
85
- logger = RootLogger::ClassLogger.new(root_logger, self)
86
- logger.warn "new default logger crated" if new_root_logger
87
- @@logger[self] = logger
200
+ @@logger[self] = RootLogger::ClassLogger.new(root_logger, self)
88
201
  end
89
202
  @@logger[self]
90
203
  end
@@ -1,8 +1,8 @@
1
- class StatsReporter < Controler
1
+ class StatsReporter < Controller
2
2
  def self.<<(stats)
3
3
  (@@stats ||= []) << stats
4
4
  end
5
-
5
+
6
6
  self.define do
7
7
  all_stats = {}
8
8
  @@stats.each do |stats|
@@ -0,0 +1,20 @@
1
+ require 'uri'
2
+
3
+ module URI
4
+ class << self
5
+ alias_method :pct_decode, :decode
6
+ end
7
+
8
+ # From http://en.wikipedia.org/wiki/Percent-encoding:
9
+ # The generic URI syntax mandates that new URI schemes that provide for the representation of character data in a URI must, in effect, represent characters from the unreserved set without translation, and should convert all other characters to bytes according to UTF-8, and then percent-encode those values.
10
+ def self.utf_decode(str)
11
+ pct_decode(str).force_encoding('UTF-8').tap do |u|
12
+ raise URI::InvalidURIError, "invalid UTF-8 encoding in URI: #{u.inspect}" if not u.valid_encoding?
13
+ end
14
+ end
15
+
16
+ # Use it by default
17
+ def self.decode(str)
18
+ self.utf_decode(str)
19
+ end
20
+ end
@@ -6,6 +6,7 @@ require 'facter'
6
6
  require 'pathname'
7
7
  require 'ip'
8
8
 
9
+ require_relative 'unicorn-cuba-base/uri_ext'
9
10
  require_relative 'unicorn-cuba-base/stats'
10
11
  require_relative 'unicorn-cuba-base/root_logger'
11
12
  require_relative 'unicorn-cuba-base/plugin/error_matcher'
@@ -15,8 +16,10 @@ require_relative 'unicorn-cuba-base/plugin/memory_limit'
15
16
  require_relative 'unicorn-cuba-base/rack/error_handling'
16
17
  require_relative 'unicorn-cuba-base/rack/unhandled_request'
17
18
  require_relative 'unicorn-cuba-base/rack/memory_limit'
19
+ require_relative 'unicorn-cuba-base/rack/xid_logging'
20
+ require_relative 'unicorn-cuba-base/rack/common_logger_xid'
18
21
 
19
- class Controler < Cuba
22
+ class Controller < Cuba
20
23
  include ClassLogging
21
24
  end
22
25
 
@@ -46,12 +49,19 @@ class Application
46
49
  @cli = setup_cli(program_name, defaults, @cli_setup) or fail 'no cli defined'
47
50
  @settings = @settings_setup ? setup_settings(@settings_setup) : @cli.parse!
48
51
 
49
- root_logger = RootLogger.new(STDERR)
52
+ root_logger = if @settings.syslog_facility
53
+ # open /dev/null as log file if we are using syslog and we are not in foreground
54
+ @settings.log_file = Pathname.new '/dev/null' unless @settings.foreground
55
+ RootSyslogLogger.new(program_name, @settings.syslog_facility, @settings.foreground)
56
+ else
57
+ RootLogger.new
58
+ end
59
+
50
60
  root_logger.level = RootLogger::WARN
51
61
  root_logger.level = RootLogger::INFO if @settings.verbose
52
62
  root_logger.level = RootLogger::DEBUG if @settings.debug
53
- Controler.logger = root_logger
54
- MemoryLimit.logger = Controler.logger_for(MemoryLimit)
63
+ Controller.logger = root_logger
64
+ MemoryLimit.logger = Controller.logger_for(MemoryLimit)
55
65
 
56
66
  unicorn_settings = {}
57
67
  unicorn_settings[:logger] = root_logger.logger_for(Unicorn::HttpServer)
@@ -67,7 +77,7 @@ class Application
67
77
  unicorn_settings[:stderr_path] = @settings.log_file.to_s
68
78
  unicorn_settings[:stdout_path] = @settings.log_file.to_s
69
79
 
70
- Unicorn::Launcher.daemonize!(unicorn_settings)
80
+ Unicorn::Launcher.daemonize!(unicorn_settings)
71
81
 
72
82
  # capture startup messages
73
83
  @settings.log_file.open('ab') do |log|
@@ -77,25 +87,30 @@ class Application
77
87
  end
78
88
  end
79
89
 
80
- Controler.settings[:listeners] = @settings.listener
81
- Controler.settings[:access_log_file] = @settings.access_log_file
82
-
83
- Controler.plugin Plugin::ErrorMatcher
84
- Controler.plugin Plugin::Logging
85
- Controler.plugin Plugin::ResponseHelpers
86
- Controler.plugin Plugin::MemoryLimit
87
-
88
- @main_setup or fail 'no main controler provided'
89
- main_controler = setup_main(@main_setup) or fail 'no main controler class returned'
90
-
91
- access_log_file = @settings.access_log_file.open('a+')
92
- access_log_file.sync = true
93
- main_controler.use Rack::CommonLogger, access_log_file
94
- main_controler.use Rack::MemoryLimit, @settings.limit_memory * 1024 ** 2
95
- main_controler.use Rack::ErrorHandling
96
- main_controler.use Rack::UnhandledRequest
90
+ Controller.settings[:listeners] = @settings.listener
91
+ #Controller.settings[:access_log_file] = @settings.access_log_file
92
+
93
+ Controller.plugin Plugin::ErrorMatcher
94
+ Controller.plugin Plugin::Logging
95
+ Controller.plugin Plugin::ResponseHelpers
96
+ Controller.plugin Plugin::MemoryLimit
97
+
98
+ @main_setup or fail 'no main controller provided'
99
+ main_controller = setup_main(@main_setup) or fail 'no main controller class returned'
100
+
101
+ main_controller.use Rack::ErrorHandling
102
+ main_controller.use Rack::XIDLogging, root_logger, @settings.xid_header if @settings.xid_header
103
+ if @settings.syslog_facility
104
+ main_controller.use Rack::CommonLoggerXID, root_logger.with_meta(type: 'http-access')
105
+ else
106
+ access_log_file = @settings.access_log_file.open('a+')
107
+ access_log_file.sync = true
108
+ main_controller.use Rack::CommonLogger, access_log_file
109
+ end
110
+ main_controller.use Rack::MemoryLimit, @settings.limit_memory * 1024 ** 2
111
+ main_controller.use Rack::UnhandledRequest
97
112
 
98
- Unicorn::HttpServer.new(main_controler, unicorn_settings).start.join
113
+ Unicorn::HttpServer.new(main_controller, unicorn_settings).start.join
99
114
  end
100
115
 
101
116
  private
@@ -108,11 +123,17 @@ class Application
108
123
  cast: Pathname,
109
124
  description: 'log file location',
110
125
  default: "#{program_name}.log"
126
+ option :syslog_facility,
127
+ short: :s,
128
+ description: 'when set logs will be sent to syslog instead of log files; one of: auth, authpriv, cron, daemon, ftp, kern, lpr, mail, news, syslog, user, uucp, local0, local1, local2, local3, local4, local5, local6, local7'
111
129
  option :access_log_file,
112
130
  short: :a,
113
131
  cast: Pathname,
114
132
  description: 'NCSA access log file location',
115
133
  default: "#{program_name}_access.log"
134
+ option :xid_header,
135
+ short: :x,
136
+ description: 'log value of named request header with request context'
116
137
  option :pid_file,
117
138
  short: :p,
118
139
  cast: Pathname,
@@ -3,7 +3,7 @@ require_relative 'spec_helper'
3
3
  require 'unicorn-cuba-base/root_logger'
4
4
  require 'stringio'
5
5
 
6
- describe do
6
+ describe RootLogger do
7
7
  let! :log_out do
8
8
  StringIO.new
9
9
  end
@@ -44,15 +44,109 @@ describe do
44
44
  subject.logger_for(String).info 'hello world'
45
45
  log_out.string.should include 'String'
46
46
  end
47
+ end
48
+
49
+ it 'should log exceptions' do
50
+ begin
51
+ raise RuntimeError, 'bad luck'
52
+ rescue => error
53
+ subject.logger_for(String).error 'hello world', error
54
+ end
55
+ log_out.string.should include 'hello world: RuntimeError: bad luck'
56
+ end
57
+
58
+ describe 'meta data' do
59
+ it 'should log with metadata in RFC5424 format' do
60
+ subject.with_meta(type: 'access-log').info 'GET /asdfas'
61
+ log_out.string.should include 'type="access-log"'
47
62
 
48
- it 'should log exceptions' do
49
- begin
50
- raise RuntimeError, 'bad luck'
51
- rescue => error
52
- subject.logger_for(String).error 'hello world', error
63
+ subject.info 'GET /asdfas'
64
+ log_out.string.lines.to_a.last.should_not include 'type="access-log"'
65
+ end
66
+
67
+ it 'should work with chaining' do
68
+ subject.with_meta(type: 'access-log').with_meta(blah: 'xxx').info 'GET /asdfas'
69
+ log_out.string.should include 'type="access-log" blah="xxx"'
70
+ end
71
+
72
+ it 'should log with metadata context' do
73
+ subject.with_meta_context(type: 'app-log') do
74
+ subject.info 'GET /asdfas'
53
75
  end
54
- log_out.string.should include 'hello world: RuntimeError: bad luck'
76
+ log_out.string.should include 'type="app-log"'
77
+
78
+ subject.info 'GET /asdfas'
79
+ log_out.string.lines.to_a.last.should_not include 'type="app-log"'
55
80
  end
56
81
  end
57
82
  end
58
83
 
84
+ require 'capture-output'
85
+
86
+ describe SyslogLogDev do
87
+ subject do
88
+ SyslogLogDev.new('unicorn-cuba-base-test', 'daemon', true)
89
+ end
90
+
91
+ after :each do
92
+ subject.close
93
+ end
94
+
95
+ it 'should write messages to syslog expecting first word to be log level' do
96
+ Capture.stderr{subject.write 'INFO hello world'}.should include '<Info>'
97
+ Capture.stderr{subject.write 'WARN hello world'}.should include '<Warning>'
98
+ Capture.stderr{subject.write 'INFO hello world'}.should include 'hello world'
99
+ end
100
+
101
+ it 'should handle multiline log entries' do
102
+ Capture.stderr{subject.write "INFO hello\nworld"}.should include "<Info>: hello\n\tworld\n"
103
+ end
104
+ end
105
+
106
+ describe RootSyslogLogger do
107
+ subject do
108
+ @subject ||= RootSyslogLogger.new('unicorn-cuba-base-test', 'daemon', true).logger_for(RSpec)
109
+ end
110
+
111
+ after :each do
112
+ subject.close
113
+ end
114
+
115
+ it 'should log to syslog' do
116
+ log_out = Capture.stderr{subject.info 'hello world'}
117
+
118
+ log_out.should include 'unicorn-cuba-base-test'
119
+ log_out.should match /\[[0-9]+\]/
120
+ log_out.should include '<Info>:'
121
+ end
122
+
123
+ it 'should include message' do
124
+ Capture.stderr{subject.info 'hello world'}.should include 'hello world'
125
+ end
126
+
127
+ it 'should include class name' do
128
+ Capture.stderr{subject.info 'hello world'}.should include 'RSpec'
129
+ end
130
+
131
+ it 'should map log levels to syslog severities' do
132
+ Capture.stderr{subject.debug 'hello world'}.should include '<Debug>'
133
+ Capture.stderr{subject.info 'hello world'}.should include '<Info>'
134
+ Capture.stderr{subject.warn 'hello world'}.should include '<Warning>'
135
+ Capture.stderr{subject.error 'hello world'}.should include '<Error>'
136
+ Capture.stderr{subject.fatal 'hello world'}.should include '<Critical>'
137
+ end
138
+
139
+ it 'should handle multiline logs by appending tab after new line (done by syslog?)' do
140
+ Capture.stderr{subject.info "hello\nworld\ntest"}.should include "hello\n\tworld\n\ttest\n"
141
+ end
142
+
143
+ describe 'direct wirtes' do
144
+ it 'should use Info level' do
145
+ Capture.stderr{subject.write "hello world"}.should include '<Info>'
146
+ end
147
+
148
+ it 'should allow use of meta data' do
149
+ Capture.stderr{subject.with_meta('type' => 'access-log').write "hello world"}.should include 'type="access-log"'
150
+ end
151
+ end
152
+ end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "unicorn-cuba-base"
8
- s.version = "1.1.2"
8
+ s.version = "1.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jakub Pastuszek"]
12
- s.date = "2013-10-22"
12
+ s.date = "2014-07-28"
13
13
  s.description = "web application base powered by Unicorn HTTP server and based on Cuba framework extended with additional Rack middleware and Cuba plugins"
14
14
  s.email = "jpastuszek@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -32,12 +32,15 @@ Gem::Specification.new do |s|
32
32
  "lib/unicorn-cuba-base/plugin/logging.rb",
33
33
  "lib/unicorn-cuba-base/plugin/memory_limit.rb",
34
34
  "lib/unicorn-cuba-base/plugin/response_helpers.rb",
35
+ "lib/unicorn-cuba-base/rack/common_logger_xid.rb",
35
36
  "lib/unicorn-cuba-base/rack/error_handling.rb",
36
37
  "lib/unicorn-cuba-base/rack/memory_limit.rb",
37
38
  "lib/unicorn-cuba-base/rack/unhandled_request.rb",
39
+ "lib/unicorn-cuba-base/rack/xid_logging.rb",
38
40
  "lib/unicorn-cuba-base/root_logger.rb",
39
41
  "lib/unicorn-cuba-base/stats.rb",
40
42
  "lib/unicorn-cuba-base/stats_reporter.rb",
43
+ "lib/unicorn-cuba-base/uri_ext.rb",
41
44
  "spec/memory_limit_spec.rb",
42
45
  "spec/root_logger_spec.rb",
43
46
  "spec/spec_helper.rb",
@@ -46,7 +49,7 @@ Gem::Specification.new do |s|
46
49
  s.homepage = "http://github.com/jpastuszek/unicorn-cuba-base"
47
50
  s.licenses = ["MIT"]
48
51
  s.require_paths = ["lib"]
49
- s.rubygems_version = "1.8.25"
52
+ s.rubygems_version = "1.8.23"
50
53
  s.summary = "web appliaction base powered by Unicorn and Cuba"
51
54
 
52
55
  if s.respond_to? :specification_version then
@@ -62,6 +65,7 @@ Gem::Specification.new do |s|
62
65
  s.add_development_dependency(%q<rspec>, ["~> 2.13"])
63
66
  s.add_development_dependency(%q<rdoc>, ["~> 3.9"])
64
67
  s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
68
+ s.add_development_dependency(%q<capture-output>, ["~> 1.0"])
65
69
  else
66
70
  s.add_dependency(%q<cuba>, ["~> 3.0"])
67
71
  s.add_dependency(%q<unicorn>, [">= 4.6.2"])
@@ -72,6 +76,7 @@ Gem::Specification.new do |s|
72
76
  s.add_dependency(%q<rspec>, ["~> 2.13"])
73
77
  s.add_dependency(%q<rdoc>, ["~> 3.9"])
74
78
  s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
79
+ s.add_dependency(%q<capture-output>, ["~> 1.0"])
75
80
  end
76
81
  else
77
82
  s.add_dependency(%q<cuba>, ["~> 3.0"])
@@ -83,6 +88,7 @@ Gem::Specification.new do |s|
83
88
  s.add_dependency(%q<rspec>, ["~> 2.13"])
84
89
  s.add_dependency(%q<rdoc>, ["~> 3.9"])
85
90
  s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
91
+ s.add_dependency(%q<capture-output>, ["~> 1.0"])
86
92
  end
87
93
  end
88
94
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unicorn-cuba-base
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-10-22 00:00:00.000000000 Z
12
+ date: 2014-07-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: cuba
@@ -155,6 +155,22 @@ dependencies:
155
155
  - - ~>
156
156
  - !ruby/object:Gem::Version
157
157
  version: 1.8.4
158
+ - !ruby/object:Gem::Dependency
159
+ name: capture-output
160
+ requirement: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ~>
164
+ - !ruby/object:Gem::Version
165
+ version: '1.0'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ~>
172
+ - !ruby/object:Gem::Version
173
+ version: '1.0'
158
174
  description: web application base powered by Unicorn HTTP server and based on Cuba
159
175
  framework extended with additional Rack middleware and Cuba plugins
160
176
  email: jpastuszek@gmail.com
@@ -179,12 +195,15 @@ files:
179
195
  - lib/unicorn-cuba-base/plugin/logging.rb
180
196
  - lib/unicorn-cuba-base/plugin/memory_limit.rb
181
197
  - lib/unicorn-cuba-base/plugin/response_helpers.rb
198
+ - lib/unicorn-cuba-base/rack/common_logger_xid.rb
182
199
  - lib/unicorn-cuba-base/rack/error_handling.rb
183
200
  - lib/unicorn-cuba-base/rack/memory_limit.rb
184
201
  - lib/unicorn-cuba-base/rack/unhandled_request.rb
202
+ - lib/unicorn-cuba-base/rack/xid_logging.rb
185
203
  - lib/unicorn-cuba-base/root_logger.rb
186
204
  - lib/unicorn-cuba-base/stats.rb
187
205
  - lib/unicorn-cuba-base/stats_reporter.rb
206
+ - lib/unicorn-cuba-base/uri_ext.rb
188
207
  - spec/memory_limit_spec.rb
189
208
  - spec/root_logger_spec.rb
190
209
  - spec/spec_helper.rb
@@ -204,7 +223,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
204
223
  version: '0'
205
224
  segments:
206
225
  - 0
207
- hash: -4100788801450601384
226
+ hash: 668318932229336882
208
227
  required_rubygems_version: !ruby/object:Gem::Requirement
209
228
  none: false
210
229
  requirements:
@@ -213,7 +232,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
213
232
  version: '0'
214
233
  requirements: []
215
234
  rubyforge_project:
216
- rubygems_version: 1.8.25
235
+ rubygems_version: 1.8.23
217
236
  signing_key:
218
237
  specification_version: 3
219
238
  summary: web appliaction base powered by Unicorn and Cuba