Golang:从http.ResponseWriter获取数据以进行日志记录

Jag*_*ati 10 go

我不知道这个问题是否有意义,但我想知道是否有任何方法可以获得写入的数据http.ResponseWriter.我需要它logging.

我在Golang写了一个api.

func api1(w http.ResponseWriter, req *http.Request) {       
    var requestData MyStruct
    err := json.NewDecoder(req.Body).Decode(&requestData)
    if err != nil {
        writeError(w, "JSON request is not in correct format")
        return
    }
    log.Println(" Request Data :", req.Body) // I am logging req
    result, err := compute()                 // getting result from a function

    if err != nil {
        errRes := ErrorResponse{"ERROR", err}
        response, er = json.Marshal(errRes) // getting error response
    } else {
        response, er = json.Marshal(result)
    }
    if er != nil {
        http.Error(w, er.Error(), 500) // writing error
        return
    }
    io.WriteString(w, string(response)) // writing response
}
Run Code Online (Sandbox Code Playgroud)

The aim is to create a single log with request and response data.响应可以是错误响应或处理响应.

我在想是否能获得写在http.ResponseWriter上的数据,然后我可以创建单个有意义的日志.

Is this possible? 如果没有,请建议我如何实现这一目标.

ain*_*ain 8

您可以使用io.MultiWriter - 它创建一个写入器,复制其对所有提供的编写器的写入.所以要记录响应

func api1(w http.ResponseWriter, req *http.Request) {
    var log bytes.Buffer
    rsp := io.MultiWriter(w, &log)
    // from this point on use rsp instead of w, ie
    err := json.NewDecoder(req.Body).Decode(&requestData)
    if err != nil {
        writeError(rsp, "JSON request is not in correct format")
        return
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

现在,您有重复写入的信息的rsp两种w,并log和您可以将内容保存log缓冲到控制台上的显示等它的盘

你可以使用io.TeeReader来创建一个Reader,它向给定的Writer写入它从给定读者读取的内容 - 这将允许你保存req.Body到日志的副本,即

func api1(w http.ResponseWriter, req *http.Request) {
    var log bytes.Buffer
    tee := io.TeeReader(req.Body, &log)
    err := json.NewDecoder(tee).Decode(&requestData)
    ...
}
Run Code Online (Sandbox Code Playgroud)

现在自从json解码器读取表单后tee,内容req.Body也被复制到log缓冲区中.