You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用http-conduit的ManagerSettings实现请求与响应全日志记录?

验证与优化http-conduit的请求/响应追踪ManagerSettings

Let's take a look at your tracing ManagerSettings code and go over its correctness plus some optimizations you can make:

Correctness Check

  • managerModifyRequest: This section works functionally—it prints the request object before passing it along. The only minor quirk is mixing putStr + print + putStrLn might create inconsistent line breaks (since print automatically adds a newline), but this isn't a breaking issue.
  • managerModifyResponse: Here are critical correctness gaps in your current code:
    1. The code is truncated (the fu... part), but assuming you meant fullResponse, the bigger problem is that brConsume drains the entire responseBody (a one-time ByteReader stream). If you don't reconstruct the response body, any downstream code trying to read the response will get an empty stream, leading to silent bugs.
    2. Using decodeUtf8 directly will throw exceptions if the response body isn't valid UTF-8 (common with binary data or non-UTF-8 text responses).

Optimization & Fixed Code

Here's a revised version of your code with key fixes and improvements, plus explanations:

import qualified Data.ByteString.Lazy as LBS
import Data.Text.Encoding (decodeUtf8With)
import Data.Text.Encoding.Error (lenientDecode)
import System.IO (stderr, hPutStrLn)

tracingManagerSettings :: ManagerSettings
tracingManagerSettings = tlsManagerSettings {
    managerModifyRequest = \req -> do
        -- Print targeted request details instead of the verbose full object
        hPutStrLn stderr $ "TRACE: Request Method: " ++ show (method req)
        hPutStrLn stderr $ "TRACE: Request URL: " ++ show (getUri req)
        hPutStrLn stderr $ "TRACE: Request Headers: " ++ show (requestHeaders req)
        pure req
    , managerModifyResponse = \r -> do
        -- Read the full response body
        responseChunks <- brConsume $ responseBody r
        let fullResponseBody = mconcat responseChunks
            -- Safely handle non-UTF-8 content without crashing
            bodyText = decodeUtf8With lenientDecode fullResponseBody

        -- Print response metadata + readable body
        hPutStrLn stderr $ "TRACE: Response Status: " ++ show (responseStatus r)
        hPutStrLn stderr $ "TRACE: Response Headers: " ++ show (responseHeaders r)
        hPutStrLn stderr $ "TRACE: Response Body: " ++ LBS.unpack fullResponseBody

        -- Reconstruct the response body so downstream code can still access it
        let newResponseBody = brFromChunks [fullResponseBody]
            newResponse = r { responseBody = newResponseBody }
        pure newResponse
}

Key Improvements:

  • Fixed response body handling: We use brFromChunks to recreate a readable ByteReader from the consumed chunks, ensuring downstream code can still access the response data.
  • Safer UTF-8 decoding: decodeUtf8With lenientDecode replaces invalid bytes with replacement characters instead of crashing your application.
  • Cleaner logging:
    • Logging to stderr keeps trace output separate from your app's normal stdout output.
    • Printing specific request/response fields (method, URL, status code) instead of the full verbose objects makes logs easier to parse.
  • Memory awareness: For debugging, loading the full response body into memory is fine, but if you expect large responses in production, you could modify this to stream the body while logging (using brRead in a loop) to avoid high memory usage.

Additional Tips:

  • Consider using a proper logging library like monad-logger or katip instead of direct hPutStrLn—this lets you add timestamps, log levels, and structured logging with minimal effort.
  • For ad-hoc debugging, tools like Wireshark or tcpdump can also trace HTTP traffic without modifying your code, but in-app tracing is invaluable for production or targeted debugging scenarios.

内容的提问来源于stack exchange,提问作者Robin Green

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:54:14