api_valve 0.0.1.beta.1 → 0.0.1.beta.2
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 +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
|