Class: Fbe::Middleware::Formatter

Inherits:
Faraday::Logging::Formatter
  • Object
show all
Defined in:
lib/fbe/middleware/formatter.rb

Overview

Custom Faraday formatter that logs only error responses (4xx/5xx).

This formatter reduces log noise by only outputting details when HTTP requests fail. For 403 errors with JSON responses, it shows a compact warning with the error message. For other errors, it logs the full request/response details including headers and bodies.

Author

Yegor Bugayenko ([email protected])

Copyright

Copyright © 2024-2025 Zerocracy

License

MIT

Examples:

Usage in Faraday middleware

connection = Faraday.new do |f|
  f.response :logger, nil, formatter: Fbe::Middleware::Formatter
end

Log output for 403 error

# GET https://api.github.com/repos/private/repo -> 403 / Repository access denied

Log output for other errors (500, 404, etc)

# GET https://api.example.com/endpoint HTTP/1.1
#   Content-Type: "application/json"
#   Authorization: "Bearer [FILTERED]"
#
#   {"query": "data"}
# HTTP/1.1 500
#   Content-Type: "text/html"
#
#   Internal Server Error

Instance Method Summary collapse

Instance Method Details

#request(http) ⇒ void

This method returns an undefined value.

Captures HTTP request details for later use in error logging.



46
47
48
# File 'lib/fbe/middleware/formatter.rb', line 46

def request(http)
  @req = http
end

#response(http) ⇒ void

Note:

Only logs when status >= 400

Note:

Special handling for 403 JSON responses to show compact error message

This method returns an undefined value.

Logs HTTP response details only for error responses (4xx/5xx).



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
# File 'lib/fbe/middleware/formatter.rb', line 56

def response(http)
  return if http.status < 400
  if http.status == 403 && http.response_headers['content-type'].start_with?('application/json')
    warn(
      [
        "#{@req.method.upcase} #{apply_filters(@req.url.to_s)}",
        '->',
        http.status,
        '/',
        JSON.parse(http.response_body)['message']
      ].join(' ')
    )
    return
  end
  if http.status >= 500 && http.response_headers['content-type']&.start_with?('text')
    error(
      [
        "#{@req.method.upcase} #{apply_filters(@req.url.to_s)} HTTP/1.1",
        shifted(apply_filters(dump_headers(@req.request_headers))),
        '',
        shifted(apply_filters(@req.request_body)),
        "HTTP/1.1 #{http.status}",
        shifted(apply_filters(dump_headers(http.response_headers))),
        '',
        shifted(apply_filters(http.response_body&.ellipsized(100, :right)))
      ].join("\n")
    )
    return
  end
  error(
    [
      "#{@req.method.upcase} #{apply_filters(@req.url.to_s)} HTTP/1.1",
      shifted(apply_filters(dump_headers(@req.request_headers))),
      '',
      shifted(apply_filters(@req.request_body)),
      "HTTP/1.1 #{http.status}",
      shifted(apply_filters(dump_headers(http.response_headers))),
      '',
      shifted(apply_filters(http.response_body))
    ].join("\n")
  )
end