salestation 0.1.0 → 0.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7af82fc0b7698f3f66945b5291d2a2d9ccf869bd
4
- data.tar.gz: e0f635d0e541cb790124900cc7c6b2cc10a8fc5e
3
+ metadata.gz: 8ebf9157080bc595e5627ac9dd0a63a24afd3f12
4
+ data.tar.gz: 06f85ef72b8cf37c248129448e9466040016c6c2
5
5
  SHA512:
6
- metadata.gz: deab697cdfd27d779bdf67e09508e0dbadb602e0351b6727592f9d695e54de121223133f01d8e92af3ca818fe5952b3f8831f49c776b5e508ea8f61c23081db5
7
- data.tar.gz: 818726078b70b2e9a44b6af528e81a8e2aaef8ceffba89ec299b61c345c67a002152d164f6200fd31dfa5f33ca46f584118760728c70ad8fd713f6cca194f0b3
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
@@ -33,3 +33,5 @@ end
33
33
  require_relative './web/responses'
34
34
  require_relative './web/error_mapper'
35
35
  require_relative './result_helper'
36
+ require_relative './web/request_logger'
37
+ require_relative './web/statsd_middleware'
data/salestation.gemspec CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "salestation"
7
- spec.version = "0.1.0"
7
+ spec.version = "0.1.1"
8
8
  spec.authors = ["SaleMove TechMovers"]
9
9
  spec.email = ["techmovers@salemove.com"]
10
10
 
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.0
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: