unicorn-cuba-base 1.1.2 → 1.2.0

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.
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