salestation 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +26 -0
- data/lib/salestation/web/request_logger.rb +91 -0
- data/lib/salestation/web/statsd_middleware.rb +28 -0
- data/lib/salestation/web.rb +2 -0
- data/salestation.gemspec +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8ebf9157080bc595e5627ac9dd0a63a24afd3f12
|
4
|
+
data.tar.gz: 06f85ef72b8cf37c248129448e9466040016c6c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a1ceaacece5be4693ce08f0542486b86e7c4462b273b8e9efebe958f30ac3471e21e3f95e77f7b90b7f77a01f64861b5a63b9ac7f9599dcfa86c2f91304925e2
|
7
|
+
data.tar.gz: 54fd1b4f4a7dca1e60959d3f213f2a33d2178ca400c3e4170bfab88a43ab1356775ad25075519aadbdb7b7c164c7f9bfcb2e03f83a392e68135a3b4355dfa3ed
|
data/README.md
CHANGED
@@ -73,6 +73,32 @@ Salestation allows and recommends you to define your own custom errors. This is
|
|
73
73
|
})
|
74
74
|
```
|
75
75
|
|
76
|
+
### Using a logger
|
77
|
+
|
78
|
+
Salestation provides a rack logging middleware which can be used to log structured objects.
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
class Webapp < Sinatra::Base
|
82
|
+
# ...
|
83
|
+
use Salestation::Web::RequestLogger, my_logger
|
84
|
+
end
|
85
|
+
```
|
86
|
+
|
87
|
+
### Using StatsD
|
88
|
+
|
89
|
+
Salestation provides a StatsD middleware which can be used record request
|
90
|
+
execution time. A `timing` call with elapsed seconds is made to the provided
|
91
|
+
StatsD instance with `path`, `method`, `status` tags.
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
class Webapp < Sinatra::Base
|
95
|
+
# ...
|
96
|
+
use Salestation::Web::StatsdMiddleware,
|
97
|
+
Statsd.new(host, port),
|
98
|
+
metric: 'my-metric'
|
99
|
+
end
|
100
|
+
```
|
101
|
+
|
76
102
|
## Development
|
77
103
|
|
78
104
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Salestation
|
2
|
+
class Web < Module
|
3
|
+
class RequestLogger
|
4
|
+
|
5
|
+
REMOTE_ADDR = 'REMOTE_ADDR'.freeze
|
6
|
+
REQUEST_URI = 'REQUEST_URI'.freeze
|
7
|
+
REQUEST_METHOD = 'REQUEST_METHOD'.freeze
|
8
|
+
QUERY_STRING = 'QUERY_STRING'.freeze
|
9
|
+
CONTENT_TYPE = 'CONTENT_TYPE'.freeze
|
10
|
+
HTTP_USER_AGENT = 'HTTP_USER_AGENT'.freeze
|
11
|
+
HTTP_ACCEPT = 'HTTP_ACCEPT'.freeze
|
12
|
+
SERVER_NAME = 'SERVER_NAME'.freeze
|
13
|
+
JSON_CONTENT_TYPE = 'application/json'.freeze
|
14
|
+
|
15
|
+
def initialize(app, logger)
|
16
|
+
@app = app
|
17
|
+
@logger = logger
|
18
|
+
end
|
19
|
+
|
20
|
+
def call(env)
|
21
|
+
request_id = SecureRandom.hex(4)
|
22
|
+
request_logger = Logger.new(@logger, request_id)
|
23
|
+
|
24
|
+
env['request_logger'] = request_logger
|
25
|
+
began_at = Time.now
|
26
|
+
|
27
|
+
request_logger.info('Received request', request_log(env))
|
28
|
+
@app.call(env).tap do |status, headers, body|
|
29
|
+
type = status >= 500 ? :info : :error
|
30
|
+
request_logger.public_send(type, 'Processed request', response_log(env, status, headers, body, began_at))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def request_log(env)
|
37
|
+
{
|
38
|
+
remote_addr: env[REMOTE_ADDR],
|
39
|
+
method: env[REQUEST_METHOD],
|
40
|
+
path: env[REQUEST_URI],
|
41
|
+
query: env[QUERY_STRING],
|
42
|
+
content_type: env[CONTENT_TYPE],
|
43
|
+
http_agent: env[HTTP_USER_AGENT],
|
44
|
+
http_accept: env[HTTP_ACCEPT],
|
45
|
+
server_name: env[SERVER_NAME]
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
def response_log(env, status, headers, body, began_at)
|
50
|
+
response_payload =
|
51
|
+
if status >= 400
|
52
|
+
{ error: parse_body(body) }
|
53
|
+
else
|
54
|
+
{ body: parse_body(body) }
|
55
|
+
end
|
56
|
+
|
57
|
+
{
|
58
|
+
path: env[REQUEST_URI],
|
59
|
+
method: env[REQUEST_METHOD],
|
60
|
+
status: status,
|
61
|
+
duration: Time.now - began_at,
|
62
|
+
headers: headers.slice(
|
63
|
+
'Location', 'Content-Length', 'Content-Type'
|
64
|
+
)
|
65
|
+
}.merge(response_payload)
|
66
|
+
end
|
67
|
+
|
68
|
+
def parse_body(body)
|
69
|
+
begin
|
70
|
+
# Rack body is an array
|
71
|
+
JSON.parse(body.join())
|
72
|
+
rescue Exception
|
73
|
+
{error: "Failed to parse response body"}
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class Logger
|
78
|
+
def initialize(logger, request_id)
|
79
|
+
@logger = logger
|
80
|
+
@request_id = request_id
|
81
|
+
end
|
82
|
+
|
83
|
+
[:debug, :info, :warn, :error].each do |name|
|
84
|
+
define_method(name) do |msg, metadata = {}|
|
85
|
+
@logger.public_send(name, msg, metadata.merge(request_id: @request_id))
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Salestation
|
2
|
+
class Web < Module
|
3
|
+
class StatsdMiddleware
|
4
|
+
|
5
|
+
def initialize(app, statsd, metric:)
|
6
|
+
@app = app
|
7
|
+
@statsd = statsd
|
8
|
+
@metric = metric
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
start = Time.now
|
13
|
+
|
14
|
+
status, header, body = @app.call env
|
15
|
+
|
16
|
+
method, path = env['sinatra.route'].split
|
17
|
+
|
18
|
+
@statsd.timing(@metric, (Time.now - start) * 1000, tags: [
|
19
|
+
"path:#{ path }",
|
20
|
+
"method:#{ method }",
|
21
|
+
"status:#{ status }"
|
22
|
+
])
|
23
|
+
|
24
|
+
[status, header, body]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/salestation/web.rb
CHANGED
data/salestation.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: salestation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- SaleMove TechMovers
|
@@ -116,7 +116,9 @@ files:
|
|
116
116
|
- lib/salestation/result_helper.rb
|
117
117
|
- lib/salestation/web.rb
|
118
118
|
- lib/salestation/web/error_mapper.rb
|
119
|
+
- lib/salestation/web/request_logger.rb
|
119
120
|
- lib/salestation/web/responses.rb
|
121
|
+
- lib/salestation/web/statsd_middleware.rb
|
120
122
|
- salestation.gemspec
|
121
123
|
homepage: ''
|
122
124
|
licenses:
|