rack-json-logs 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +144 -0
- data/Rakefile +1 -0
- data/bin/json-log-pp +90 -0
- data/lib/rack-json-logs.rb +103 -0
- data/lib/rack-json-logs/version.rb +5 -0
- data/rack-json-logs.gemspec +23 -0
- data/test/.gitignore +1 -0
- data/test/config.ru +15 -0
- data/test/log +6 -0
- metadata +110 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
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,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:
|