rack-json-logs 0.0.1

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/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rack-json-logs.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Kenneth Ballenegger
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,144 @@
1
+ # Rack::JsonLogs
2
+
3
+ Rack::JsonLogs is a gem that helps log sanely in production.
4
+
5
+ Ever request will log a JSON object to the real *stdout*, containing the
6
+ following (note: whitespace added here for clarity, in production it would only
7
+ be a single line, for easier processig through tools like `grep`):
8
+
9
+ ```json
10
+ {
11
+ "request": "GET /hello",
12
+ "status": 500,
13
+ "time": 1379703636,
14
+ "duration": 0.05,
15
+ "from": "server-1",
16
+ "stdout": "This contains the STDOUT\nLines are separated by \\n",
17
+ "stderr": "This contains the STDERR\nLines are separated by \\n",
18
+ "events": [
19
+ {
20
+ "type": "event",
21
+ "value": "something awesome happened",
22
+ "time": 0.3
23
+ }
24
+ ],
25
+ "exception": {
26
+ "message": "Throwing an exception on purpose.",
27
+ "backtrace": [
28
+ "config.ru:9:in `block (2 levels) in <main>'",
29
+ ".../rack-json-logs/lib/rack-json-logs.rb:23:in `call'",
30
+ ".../rack-json-logs/lib/rack-json-logs.rb:23:in `call'",
31
+ "etc... you get the idea"
32
+ ]
33
+ }
34
+ }
35
+ ```
36
+
37
+ Rack::JsonLogs comes with a command-line tool to which you can pipe the log
38
+ files, which will be pretty-printed for legibility and in color:
39
+
40
+ ```
41
+ $ tail -F my.log | json-log-pp
42
+
43
+ Request: GET /hello
44
+ From: server-1
45
+
46
+ stdout:
47
+ hello world
48
+
49
+ stderr:
50
+ bye world
51
+
52
+ Exception: exception on purpose
53
+ config.ru:12:in `block (2 levels) in <main>'
54
+ /Users/kenneth/Dropbox/dev/azure/rack-json-logs/lib/rack-json-logs.rb:24:in `call'
55
+ /Users/kenneth/Dropbox/dev/azure/rack-json-logs/lib/rack-json-logs.rb:24:in `call'
56
+ /Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/thin-1.5.0/lib/thin/connection.rb:81:in `block in pre_process'
57
+ /Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/thin-1.5.0/lib/thin/connection.rb:79:in `catch'
58
+ /Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/thin-1.5.0/lib/thin/connection.rb:79:in `pre_process'
59
+ /Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/thin-1.5.0/lib/thin/connection.rb:54:in `process'
60
+ /Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/thin-1.5.0/lib/thin/connection.rb:39:in `receive_data'
61
+ /Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/eventmachine-1.0.0/lib/eventmachine.rb:187:in `run_machine'
62
+ /Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/eventmachine-1.0.0/lib/eventmachine.rb:187:in `run'
63
+ /Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/thin-1.5.0/lib/thin/backends/base.rb:63:in `start'
64
+ /Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/thin-1.5.0/lib/thin/server.rb:159:in `start'
65
+ /Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/thin-1.5.0/lib/thin/controllers/controller.rb:86:in `start'
66
+ /Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/thin-1.5.0/lib/thin/runner.rb:187:in `run_command'
67
+ /Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/thin-1.5.0/lib/thin/runner.rb:152:in `run!'
68
+ /Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/thin-1.5.0/bin/thin:6:in `<top (required)>'
69
+ /Users/kenneth/.rvm/gems/ruby-1.9.3-p327/bin/thin:19:in `load'
70
+ /Users/kenneth/.rvm/gems/ruby-1.9.3-p327/bin/thin:19:in `<main>'
71
+ /Users/kenneth/.rvm/gems/ruby-1.9.3-p327/bin/ruby_noexec_wrapper:14:in `eval'
72
+ /Users/kenneth/.rvm/gems/ruby-1.9.3-p327/bin/ruby_noexec_wrapper:14:in `<main>'
73
+
74
+
75
+ Request: GET /hello
76
+ From: server-2
77
+
78
+ stdout:
79
+ hello world
80
+
81
+ stderr:
82
+ bye world
83
+ ```
84
+
85
+
86
+ ## Installation
87
+
88
+ Add this line to your application's Gemfile:
89
+
90
+ gem 'rack-json-logs'
91
+
92
+ And then execute:
93
+
94
+ $ bundle
95
+
96
+ Or install it yourself as:
97
+
98
+ $ gem install rack-json-logs
99
+
100
+ ## Usage
101
+
102
+ Using Rack::JsonLogs is easy, all you need to do is add it to your middleware
103
+ stack:
104
+
105
+ ```ruby
106
+ use Rack::JsonLogs
107
+ ```
108
+
109
+ Using the command line tool is also easy. Output can be configured, see:
110
+
111
+ $ json-log-pp -h
112
+ Options:
113
+ --stdout, -o: Print stdout.
114
+ --stderr, -e: Print stderr.
115
+ --from, --no-from, -f: Print from. (Default: true)
116
+ --trace, -b: Print full backtraces.
117
+ --duration, --no-duration, -d: Print request duration. (Default: true)
118
+ --events, -v: Print events.
119
+ --help, -h: Show this message
120
+
121
+
122
+ ## Changelog
123
+
124
+ #### 1.0
125
+
126
+ Production release. Deployed and used in a large-scale system.
127
+
128
+ - Big feature: Event logging.
129
+ - `json-log-pp` output can be configured with CLI options.
130
+ - Log request duration.
131
+ - Logs status codes.
132
+ - Bug fixes.
133
+
134
+ #### 0.0.1
135
+
136
+ Initial release.
137
+
138
+ ## Contributing
139
+
140
+ 1. Fork it
141
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
142
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
143
+ 4. Push to the branch (`git push origin my-new-feature`)
144
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/json-log-pp ADDED
@@ -0,0 +1,90 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'json'
4
+ require 'colorize'
5
+ require 'stringio'
6
+ require 'trollop'
7
+
8
+ opts = Trollop.options do
9
+ opt :stdout, 'Print stdout.', default: false, short: 'o'
10
+ opt :stderr, 'Print stderr.', default: false, short: 'e'
11
+ opt :from, 'Print from.', default: true, short: 'f'
12
+ opt :trace, 'Print full backtraces.', default: false, short: 'b'
13
+ opt :duration, 'Print request duration.', default: true, short: 'd'
14
+ opt :events, 'Print events.', default: false, short: 'v'
15
+ end
16
+
17
+ STDOUT.sync = true
18
+
19
+ Signal.trap(2) do
20
+ Process.exit(0)
21
+ end
22
+
23
+ while line = STDIN.gets
24
+ break if line == nil
25
+
26
+ json = JSON.parse(line) rescue nil
27
+
28
+ json = json['data'] if json && json['data']
29
+
30
+ if json && json.is_a?(Hash) && json['request']
31
+
32
+ out = StringIO.new
33
+
34
+ status_color = case json['status']
35
+ when 200...300; :green
36
+ when 300...600; :red
37
+ else :cyan; end
38
+
39
+
40
+ resp = 'Response: '
41
+ resp << "#{json['status']} " if json['status']
42
+ resp << "(#{(json['duration']*1000).round}ms) " if opts[:duration] && json['duration']
43
+
44
+ out.puts ' * * *'
45
+ out.puts
46
+ out.puts "Request: #{json['request']}".cyan
47
+ out.puts resp.send(status_color)
48
+ out.puts "From: #{json['from']}".cyan if opts[:from] && json['from']
49
+ out.puts "At: #{Time.at(json['time']).strftime('%b %-e %Y, %-l:%M%P')}"
50
+ out.puts
51
+
52
+ %w{stdout stderr}.each do |b|
53
+ next unless opts[b.to_sym]
54
+ color = b == 'stdout' ? :green : :yellow
55
+ log = json[b] || ''
56
+ if log == '' || log == "\n"
57
+ out.puts "No #{b}.".send(color)
58
+ else
59
+ out.puts "#{b}:".cyan
60
+ out.puts log.send(color)
61
+ end
62
+ # Typically log statements start end with a \n, so skiping puts here.
63
+ end
64
+
65
+ if opts[:events] && json['events'] && !json['events'].empty?
66
+ out.puts 'Events:'.cyan
67
+ out.puts
68
+ json['events'].each do |e|
69
+ out.puts "Event: #{e['type']}"
70
+ out.puts "At: #{(e['time']*1000).round}ms"
71
+ out.puts "Value: #{e['value'].to_json}"
72
+ out.puts
73
+ end
74
+ end
75
+
76
+ if json['exception']
77
+ out.puts "Exception: #{json['exception']['message']}".red
78
+ out.puts json['exception']['backtrace'].map {|e| " #{e}"}.join("\n").blue if opts[:trace]
79
+ out.puts
80
+ end
81
+
82
+ STDOUT.print(out.string)
83
+
84
+ else
85
+ puts line
86
+ end
87
+
88
+ end
89
+
90
+ puts "\nEOF.".red
@@ -0,0 +1,103 @@
1
+ require 'rack-json-logs/version'
2
+ require 'json'
3
+ require 'stringio'
4
+ require 'socket'
5
+
6
+ module Rack
7
+
8
+ # JsonLogs is a rack middleware that will buffer output, capture exceptions,
9
+ # and log the entire thing as a json object for each request.
10
+ #
11
+ # Options are:
12
+ #
13
+ # :reraise_exceptions
14
+ #
15
+ # Whether to re-raise exceptions, or just respond with a standard JSON
16
+ # 500 response.
17
+ #
18
+ # :from
19
+ #
20
+ # A string that describes where the request happened. This is useful if,
21
+ # for example, you want to log which server the request is from. Defaults
22
+ # to the machine's hostname.
23
+ #
24
+ class JsonLogs
25
+
26
+ def initialize(app, options={})
27
+ @app = app
28
+ @options = {
29
+ reraise_exceptions: false
30
+ }.merge(options)
31
+ @options[:from] ||= Socket.gethostname
32
+ end
33
+
34
+ def call(env)
35
+ start_time = Time.now
36
+ $stdout, previous_stdout = (stdout_buffer = StringIO.new), $stdout
37
+ $stderr, previous_stderr = (stderr_buffer = StringIO.new), $stderr
38
+
39
+ logger = EventLogger.new(start_time)
40
+ env = env.dup; env[:logger] = logger
41
+
42
+ begin
43
+ response = @app.call(env)
44
+ rescue Exception => e
45
+ exception = e
46
+ end
47
+
48
+ # restore output IOs
49
+ $stderr = previous_stderr; $stdout = previous_stdout
50
+
51
+ log = {
52
+ time: start_time.to_i,
53
+ duration: (Time.now - start_time).round(3),
54
+ request: "#{env['REQUEST_METHOD']} #{env['PATH_INFO']}",
55
+ status: (response || [500]).first,
56
+ from: @options[:from],
57
+ stdout: stdout_buffer.string,
58
+ stderr: stderr_buffer.string
59
+ }
60
+ log[:events] = logger.events if logger.used
61
+ if exception
62
+ log[:exception] = {
63
+ message: exception.message,
64
+ backtrace: exception.backtrace
65
+ }
66
+ end
67
+ STDOUT.puts(log.to_json)
68
+
69
+ raise exception if exception && @options[:reraise_exceptions]
70
+
71
+ response || response_500
72
+ end
73
+
74
+ def response_500
75
+ [500, {'Content-Type' => 'application/json'}, [{status: 500, message: 'Something went wrong...'}.to_json]]
76
+ end
77
+
78
+
79
+ # This class can be used to log arbitrary events to the request.
80
+ #
81
+ class EventLogger
82
+ attr_reader :events, :used
83
+
84
+ def initialize(start_time)
85
+ @start_time = start_time
86
+ @events = []
87
+ @used = false
88
+ end
89
+
90
+ # Log an event of type `type` and value `value`.
91
+ #
92
+ def log(type, value)
93
+ @used = true
94
+ @events << {
95
+ type: type,
96
+ value: value,
97
+ time: (Time.now - @start_time).round(3)
98
+ }
99
+ end
100
+ end
101
+ end
102
+ end
103
+
@@ -0,0 +1,5 @@
1
+ module Rack
2
+ class JsonLogs
3
+ VERSION = '0.0.1'
4
+ end
5
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rack-json-logs/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = 'rack-json-logs'
8
+ gem.version = Rack::JsonLogs::VERSION
9
+ gem.authors = ['Kenneth Ballenegger']
10
+ gem.email = ['kenneth@ballenegger.com']
11
+ gem.description = %q{Rack::JsonLogs is a gem that helps log sanely in production.}
12
+ gem.summary = %q{Rack::JsonLogs is a gem that helps log sanely in production.}
13
+ gem.homepage = ''
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ['lib']
19
+
20
+ gem.add_dependency 'json'
21
+ gem.add_dependency 'colorize'
22
+ gem.add_dependency 'trollop'
23
+ end
data/test/.gitignore ADDED
@@ -0,0 +1 @@
1
+ sample-input
data/test/config.ru ADDED
@@ -0,0 +1,15 @@
1
+
2
+ # TODO: write actual unit tests :).
3
+
4
+ $: << File.expand_path('../lib/', __FILE__)
5
+ require 'rack-json-logs'
6
+
7
+ use Rack::JsonLogs
8
+
9
+ run ->(env) do
10
+ puts "hello world"
11
+ env[:logger].log(:event, 'something awesome happened')
12
+ $stderr.puts "bye world"
13
+ raise "exception on purpose"
14
+ [200, {'Content-Type' => 'text/html'}, ['Hello Rack!']]
15
+ end
data/test/log ADDED
@@ -0,0 +1,6 @@
1
+ >> Thin web server (v1.5.0 codename Knife)
2
+ >> Maximum connections set to 1024
3
+ >> Listening on 0.0.0.0:9292, CTRL+C to stop
4
+ {"time":1379703632,"duration":0.001,"request":"GET /","status":500,"from":"eye.local","stdout":"hello world\n","stderr":"bye world\n","events":[{"event":"event","value":"something awesome happened","time":0.0}],"exception":{"message":"exception on purpose","backtrace":["/Users/kenneth/Dropbox/dev/azure/rack-json-logs/test/config.ru:13:in `block (2 levels) in <main>'","/Users/kenneth/Dropbox/dev/azure/rack-json-logs/lib/rack-json-logs.rb:43:in `call'","/Users/kenneth/Dropbox/dev/azure/rack-json-logs/lib/rack-json-logs.rb:43:in `call'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/rack-1.5.2/lib/rack/lint.rb:49:in `_call'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/rack-1.5.2/lib/rack/lint.rb:37:in `call'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/rack-1.5.2/lib/rack/showexceptions.rb:24:in `call'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/rack-1.5.2/lib/rack/commonlogger.rb:33:in `call'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/rack-1.5.2/lib/rack/chunked.rb:43:in `call'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/rack-1.5.2/lib/rack/content_length.rb:14:in `call'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/thin-1.5.0/lib/thin/connection.rb:81:in `block in pre_process'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/thin-1.5.0/lib/thin/connection.rb:79:in `catch'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/thin-1.5.0/lib/thin/connection.rb:79:in `pre_process'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/thin-1.5.0/lib/thin/connection.rb:54:in `process'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/thin-1.5.0/lib/thin/connection.rb:39:in `receive_data'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/eventmachine-1.0.0/lib/eventmachine.rb:187:in `run_machine'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/eventmachine-1.0.0/lib/eventmachine.rb:187:in `run'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/thin-1.5.0/lib/thin/backends/base.rb:63:in `start'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/thin-1.5.0/lib/thin/server.rb:159:in `start'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/rack-1.5.2/lib/rack/handler/thin.rb:16:in `run'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/rack-1.5.2/lib/rack/server.rb:264:in `start'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/rack-1.5.2/lib/rack/server.rb:141:in `start'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/rack-1.5.2/bin/rackup:4:in `<top (required)>'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/bin/rackup:19:in `load'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/bin/rackup:19:in `<main>'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/bin/ruby_noexec_wrapper:14:in `eval'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/bin/ruby_noexec_wrapper:14:in `<main>'"]}}
5
+ {"time":1379703636,"duration":0.0,"request":"GET /","status":500,"from":"eye.local","stdout":"hello world\n","stderr":"bye world\n","events":[{"event":"event","value":"something awesome happened","time":0.0}],"exception":{"message":"exception on purpose","backtrace":["/Users/kenneth/Dropbox/dev/azure/rack-json-logs/test/config.ru:13:in `block (2 levels) in <main>'","/Users/kenneth/Dropbox/dev/azure/rack-json-logs/lib/rack-json-logs.rb:43:in `call'","/Users/kenneth/Dropbox/dev/azure/rack-json-logs/lib/rack-json-logs.rb:43:in `call'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/rack-1.5.2/lib/rack/lint.rb:49:in `_call'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/rack-1.5.2/lib/rack/lint.rb:37:in `call'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/rack-1.5.2/lib/rack/showexceptions.rb:24:in `call'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/rack-1.5.2/lib/rack/commonlogger.rb:33:in `call'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/rack-1.5.2/lib/rack/chunked.rb:43:in `call'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/rack-1.5.2/lib/rack/content_length.rb:14:in `call'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/thin-1.5.0/lib/thin/connection.rb:81:in `block in pre_process'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/thin-1.5.0/lib/thin/connection.rb:79:in `catch'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/thin-1.5.0/lib/thin/connection.rb:79:in `pre_process'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/thin-1.5.0/lib/thin/connection.rb:54:in `process'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/thin-1.5.0/lib/thin/connection.rb:39:in `receive_data'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/eventmachine-1.0.0/lib/eventmachine.rb:187:in `run_machine'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/eventmachine-1.0.0/lib/eventmachine.rb:187:in `run'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/thin-1.5.0/lib/thin/backends/base.rb:63:in `start'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/thin-1.5.0/lib/thin/server.rb:159:in `start'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/rack-1.5.2/lib/rack/handler/thin.rb:16:in `run'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/rack-1.5.2/lib/rack/server.rb:264:in `start'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/rack-1.5.2/lib/rack/server.rb:141:in `start'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/gems/rack-1.5.2/bin/rackup:4:in `<top (required)>'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/bin/rackup:19:in `load'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/bin/rackup:19:in `<main>'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/bin/ruby_noexec_wrapper:14:in `eval'","/Users/kenneth/.rvm/gems/ruby-1.9.3-p327/bin/ruby_noexec_wrapper:14:in `<main>'"]}}
6
+ >> Stopping ...
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rack-json-logs
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Kenneth Ballenegger
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-10-07 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: json
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: colorize
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: trollop
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: Rack::JsonLogs is a gem that helps log sanely in production.
63
+ email:
64
+ - kenneth@ballenegger.com
65
+ executables:
66
+ - json-log-pp
67
+ extensions: []
68
+ extra_rdoc_files: []
69
+ files:
70
+ - .gitignore
71
+ - Gemfile
72
+ - LICENSE.txt
73
+ - README.md
74
+ - Rakefile
75
+ - bin/json-log-pp
76
+ - lib/rack-json-logs.rb
77
+ - lib/rack-json-logs/version.rb
78
+ - rack-json-logs.gemspec
79
+ - test/.gitignore
80
+ - test/config.ru
81
+ - test/log
82
+ homepage: ''
83
+ licenses: []
84
+ post_install_message:
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ! '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ requirements: []
101
+ rubyforge_project:
102
+ rubygems_version: 1.8.24
103
+ signing_key:
104
+ specification_version: 3
105
+ summary: Rack::JsonLogs is a gem that helps log sanely in production.
106
+ test_files:
107
+ - test/.gitignore
108
+ - test/config.ru
109
+ - test/log
110
+ has_rdoc: