api_valve 0.0.1.beta.1 → 0.0.1.beta.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/api_valve/error_responder.rb +1 -1
- data/lib/api_valve/forwarder/request.rb +1 -0
- data/lib/api_valve/logger.rb +21 -0
- data/lib/api_valve/middleware/logging.rb +127 -0
- data/lib/api_valve/proxy.rb +2 -2
- data/lib/api_valve.rb +2 -0
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 88db069feae42e9dc2fe3397891acfc31567a36b057a78c57d0a8ed2be567be7
|
4
|
+
data.tar.gz: 29aba6e067ae80f88effcde5d03d048eff6137c34b11376ae0dfba9a0b47669b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c7d05c3e3788a426844ea4628c2fc8fa83def60bfba39e85f0138407c820ba81b942e947e3576e85d1fb27c62206698b6b60b517fdb08478cbeb202f541ab6f
|
7
|
+
data.tar.gz: 3c57ae3efe82c65ff552084300bc7b0aa494789490ed132689f0c48c91a4b0920c937767dd41564ad7e782578bdb92c567ae71e4a231de296dde1756261a7f75
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'active_support/tagged_logging'
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
module ApiValve
|
5
|
+
class Logger < ::Logger
|
6
|
+
include ActiveSupport::TaggedLogging
|
7
|
+
|
8
|
+
class Formatter < ActiveSupport::Logger::SimpleFormatter
|
9
|
+
include ActiveSupport::TaggedLogging::Formatter
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(target = STDOUT)
|
13
|
+
super(target)
|
14
|
+
self.formatter = Formatter.new
|
15
|
+
end
|
16
|
+
|
17
|
+
# some rack apps have weird ways to write to rack.logger
|
18
|
+
alias puts error
|
19
|
+
alias write info
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
module ApiValve::Middleware
|
2
|
+
class Logging
|
3
|
+
include ActiveSupport::Configurable
|
4
|
+
|
5
|
+
class Log
|
6
|
+
INCOMING = %(Started %s "%s" for %s at %s).freeze
|
7
|
+
COMPLETE = %(Completed %s %s in %dms\n).freeze
|
8
|
+
URL_PARAMS = %(URL params %s).freeze
|
9
|
+
REQUEST_PAYLOAD = %(Request payload\n%s).freeze
|
10
|
+
REQUEST_HEADERS = %(Request HTTP Headers %s).freeze
|
11
|
+
RESPONSE_HEADERS = %(Response HTTP headers %s).freeze
|
12
|
+
RESPONSE_PAYLOAD = %(Response payload\n%s).freeze
|
13
|
+
NON_STANDARD_REQUEST_HEADERS = %w(CONTENT_LENGTH CONTENT_TYPE).freeze
|
14
|
+
|
15
|
+
attr_accessor :began_at, :env, :status, :response_headers, :response_payload
|
16
|
+
|
17
|
+
def initialize(options = {})
|
18
|
+
assign options
|
19
|
+
end
|
20
|
+
|
21
|
+
def assign(options = {})
|
22
|
+
options.each do |k, v|
|
23
|
+
public_send "#{k}=", v
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def before_request
|
28
|
+
log_request
|
29
|
+
log_url_params
|
30
|
+
log_request_headers if Logging.log_request_headers
|
31
|
+
log_request_payload if Logging.log_request_payload
|
32
|
+
end
|
33
|
+
|
34
|
+
def after_request
|
35
|
+
log_response_headers if Logging.log_response_headers
|
36
|
+
log_response_payload if Logging.log_response_payload
|
37
|
+
log_response
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
delegate :logger, to: ApiValve
|
43
|
+
|
44
|
+
def log_request
|
45
|
+
logger.info INCOMING % [
|
46
|
+
env['REQUEST_METHOD'],
|
47
|
+
[env['PATH_INFO'], env['QUERY_STRING'].presence].compact.join('?'),
|
48
|
+
(env['HTTP_X_FORWARDED_FOR'] || env['REMOTE_ADDR']),
|
49
|
+
began_at.strftime('%Y-%m-%d %H:%M:%S %z')
|
50
|
+
]
|
51
|
+
end
|
52
|
+
|
53
|
+
def log_url_params
|
54
|
+
return unless env['QUERY_STRING'].present?
|
55
|
+
logger.info URL_PARAMS % Rack::Utils.parse_nested_query(env['QUERY_STRING']).inspect
|
56
|
+
end
|
57
|
+
|
58
|
+
def log_request_headers
|
59
|
+
headers = {}
|
60
|
+
env.each_pair do |k, v|
|
61
|
+
next unless k =~ /^HTTP_/ && v.present?
|
62
|
+
next if v.blank? || (!k.start_with?('HTTP_') && !NON_STANDARD_REQUEST_HEADERS.include?(k))
|
63
|
+
headers[k] = v
|
64
|
+
end
|
65
|
+
return if headers.empty?
|
66
|
+
logger.debug REQUEST_HEADERS % headers
|
67
|
+
end
|
68
|
+
|
69
|
+
def log_request_payload
|
70
|
+
return unless %w(PATCH POST PUT).include? env['REQUEST_METHOD']
|
71
|
+
logger.debug REQUEST_PAYLOAD % env['rack.input'].read(1000)
|
72
|
+
env['rack.input'].rewind
|
73
|
+
end
|
74
|
+
|
75
|
+
def log_response_headers
|
76
|
+
return if response_headers&.empty?
|
77
|
+
logger.debug RESPONSE_HEADERS % response_headers.inspect
|
78
|
+
end
|
79
|
+
|
80
|
+
def log_response_payload
|
81
|
+
return if response_payload&.empty?
|
82
|
+
logger.debug RESPONSE_PAYLOAD % response_payload.first(config_log_body_size)
|
83
|
+
end
|
84
|
+
|
85
|
+
def log_response
|
86
|
+
logger.info COMPLETE % [
|
87
|
+
status,
|
88
|
+
Rack::Utils::HTTP_STATUS_CODES[status],
|
89
|
+
(Time.now - began_at) * 1000
|
90
|
+
]
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
config_accessor :log_request_headers do
|
95
|
+
false
|
96
|
+
end
|
97
|
+
|
98
|
+
config_accessor :log_request_payload do
|
99
|
+
false
|
100
|
+
end
|
101
|
+
|
102
|
+
config_accessor :log_response_headers do
|
103
|
+
false
|
104
|
+
end
|
105
|
+
|
106
|
+
config_accessor :log_response_payload do
|
107
|
+
false
|
108
|
+
end
|
109
|
+
|
110
|
+
def initialize(app)
|
111
|
+
@app = app
|
112
|
+
end
|
113
|
+
|
114
|
+
def call(env)
|
115
|
+
env['rack.logger'] = ApiValve.logger
|
116
|
+
env['rack.errors'] = ApiValve.logger
|
117
|
+
ApiValve.logger.tagged(Thread.current[:request_id]) do
|
118
|
+
log = Log.new(began_at: Time.now, env: env)
|
119
|
+
log.before_request
|
120
|
+
status, headers, body = @app.call(env)
|
121
|
+
log.assign status: status, response_headers: headers, response_payload: body
|
122
|
+
log.after_request
|
123
|
+
[status, headers, body]
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
data/lib/api_valve/proxy.rb
CHANGED
data/lib/api_valve.rb
CHANGED
@@ -16,6 +16,7 @@ module ApiValve
|
|
16
16
|
autoload :Error, 'api_valve/error'
|
17
17
|
autoload :ErrorResponder, 'api_valve/error_responder'
|
18
18
|
autoload :Forwarder, 'api_valve/forwarder'
|
19
|
+
autoload :Logger, 'api_valve/logger'
|
19
20
|
autoload :Proxy, 'api_valve/proxy'
|
20
21
|
autoload :Router, 'api_valve/router'
|
21
22
|
|
@@ -23,6 +24,7 @@ module ApiValve
|
|
23
24
|
|
24
25
|
module Middleware
|
25
26
|
autoload :ErrorHandling, 'api_valve/middleware/error_handling'
|
27
|
+
autoload :Logging, 'api_valve/middleware/logging'
|
26
28
|
end
|
27
29
|
|
28
30
|
config_accessor :logger do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: api_valve
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.1.beta.
|
4
|
+
version: 0.0.1.beta.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- mkon
|
@@ -48,16 +48,16 @@ dependencies:
|
|
48
48
|
name: multi_json
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
|
-
- - "
|
51
|
+
- - "~>"
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: '
|
53
|
+
version: '1.13'
|
54
54
|
type: :runtime
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
|
-
- - "
|
58
|
+
- - "~>"
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: '
|
60
|
+
version: '1.13'
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
name: rack
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -186,7 +186,9 @@ files:
|
|
186
186
|
- lib/api_valve/forwarder/permission_handler.rb
|
187
187
|
- lib/api_valve/forwarder/request.rb
|
188
188
|
- lib/api_valve/forwarder/response.rb
|
189
|
+
- lib/api_valve/logger.rb
|
189
190
|
- lib/api_valve/middleware/error_handling.rb
|
191
|
+
- lib/api_valve/middleware/logging.rb
|
190
192
|
- lib/api_valve/proxy.rb
|
191
193
|
- lib/api_valve/router.rb
|
192
194
|
homepage: https://github.com/mkon/api_valve
|