-
Notifications
You must be signed in to change notification settings - Fork 966
/
formatter.rb
122 lines (96 loc) · 3.13 KB
/
formatter.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# frozen_string_literal: true
require 'pp' # rubocop:disable Lint/RedundantRequireStatement
module Faraday
module Logging
# Serves as an integration point to customize logging
class Formatter
extend Forwardable
DEFAULT_OPTIONS = { headers: true, bodies: false, errors: false,
log_level: :info }.freeze
def initialize(logger:, options:)
@logger = logger
@filter = []
@options = DEFAULT_OPTIONS.merge(options)
end
def_delegators :@logger, :debug, :info, :warn, :error, :fatal
def request(env)
request_log = proc do
"#{env.method.upcase} #{apply_filters(env.url.to_s)}"
end
public_send(log_level, 'request', &request_log)
log_headers('request', env.request_headers) if log_headers?(:request)
log_body('request', env[:body]) if env[:body] && log_body?(:request)
end
def response(env)
status = proc { "Status #{env.status}" }
public_send(log_level, 'response', &status)
log_headers('response', env.response_headers) if log_headers?(:response)
log_body('response', env[:body]) if env[:body] && log_body?(:response)
end
def error(error)
return unless log_errors?
error_log = proc { error.full_message }
public_send(log_level, 'error', &error_log)
log_headers('error', error.response_headers) if error.respond_to?(:response_headers) && log_headers?(:error)
return unless error.respond_to?(:response_body) && error.response_body && log_body?(:error)
log_body('error', error.response_body)
end
def filter(filter_word, filter_replacement)
@filter.push([filter_word, filter_replacement])
end
private
def dump_headers(headers)
headers.map { |k, v| "#{k}: #{v.inspect}" }.join("\n")
end
def dump_body(body)
if body.respond_to?(:to_str)
body.to_str
else
pretty_inspect(body)
end
end
def pretty_inspect(body)
body.pretty_inspect
end
def log_headers?(type)
case @options[:headers]
when Hash
@options[:headers][type]
else
@options[:headers]
end
end
def log_body?(type)
case @options[:bodies]
when Hash
@options[:bodies][type]
else
@options[:bodies]
end
end
def log_errors?
@options[:errors]
end
def apply_filters(output)
@filter.each do |pattern, replacement|
output = output.to_s.gsub(pattern, replacement)
end
output
end
def log_level
unless %i[debug info warn error fatal].include?(@options[:log_level])
return :info
end
@options[:log_level]
end
def log_headers(type, headers)
headers_log = proc { apply_filters(dump_headers(headers)) }
public_send(log_level, type, &headers_log)
end
def log_body(type, body)
body_log = proc { apply_filters(dump_body(body)) }
public_send(log_level, type, &body_log)
end
end
end
end