为了账号安全,请及时绑定邮箱和手机立即绑定

Go HTTP ListenAndServe 记录响应

Go HTTP ListenAndServe 记录响应

Go
30秒到达战场 2022-01-04 19:33:23
我想知道在使用 ListenAndServe 时是否有办法记录响应。据我所知,处理程序无权访问“响应”对象。只是一个ResponseWriter,所以我不能调用httputil.DumpResponse。
查看完整描述

3 回答

?
泛舟湖上清波郎朗

TA贡献1818条经验 获得超3个赞

http.ResponseWriter 是一个接口。您可以使用嵌入来扩展它以进行日志记录,如下所示。


package main

import (

    "log"

    "net/http"

)


func sampleHandler(w http.ResponseWriter, r *http.Request) {

    w.WriteHeader(http.StatusOK)

    response := []byte("Sample Response")

    w.Write(response)

}


type loggingResponseWriter struct {

    status int

    body   string

    http.ResponseWriter

}


func (w *loggingResponseWriter) WriteHeader(code int) {

    w.status = code

    w.ResponseWriter.WriteHeader(code)

}


func (w *loggingResponseWriter) Write(body []byte) (int, error) {

    w.body = string(body)

    return w.ResponseWriter.Write(body)

}


func responseLogger(h http.Handler) http.Handler {

    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

        loggingRW := &loggingResponseWriter{

            ResponseWriter: w,

        }

        h.ServeHTTP(loggingRW, r)

        log.Println("Status : ", loggingRW.status, "Response : ", loggingRW.body)

    })

}


func main() {

    http.Handle("/", responseLogger(http.HandlerFunc(sampleHandler)))

    http.ListenAndServe(":8080", nil)

}

您可以使用 responseLogger 包装要记录响应的处理程序函数。


查看完整回答
反对 回复 2022-01-04
?
沧海一幻觉

TA贡献1824条经验 获得超5个赞

你不能,因为在你将它写入ResponseWriter.


但response仅仅是header,body并response code因此在处理函数可以使用方法Header()上ResponseWriter,以获得标题,然后您可以登录response code与body您将它写入之前ResponseWriter。


如果你提供一个你想要做什么的例子,我可以详细说明如何去做。


这是我为一个小项目修复此问题所做的工作:我在所有处理程序中都使用它:


type transaction struct {

    res Response // Create this type also

    req Request // Create this type also

}


func NewTransaction(w http.ResponseWriter, req *http.Request) *transaction{}


Log := make(chan transaction, 100)

go func{

    // Read from channel and log the info however you want.

}()


func indexHandler(w http.ResponseWriter, req *http.Request) {

    tx := NewTransaction(w, req) // Struct with the request and response

    defer func() {

        Log <- tx

    }()


    /*

    Handle request here

    */


    // Update request and response

    Request.Body = body

}

在处理函数结束时,在提供请求的数据后,我更新请求和响应的值。


并有一个 goroutine 监听通道 Log 并完成所有日志记录。


您也可以编写一个包装函数来为文件提供服务并返回响应。


查看完整回答
反对 回复 2022-01-04
?
阿晨1998

TA贡献2037条经验 获得超6个赞

作为替代方案,可以使用 fasthttp。


查看完整回答
反对 回复 2022-01-04
  • 3 回答
  • 0 关注
  • 120 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信