json.Decoding 在 Go 中同时记录原始数据的 TCP 连接

json.Decoding a TCP connection and logging the original data at the same time in Go

我正在使用 json.Decodernet.Conn 解码为自定义结构。我还想记录在 net.Conn 上发送的原始 JSON 字符串而不修改它。

我正在寻找一种有效的方法来实现这一目标。我目前有以下代码:

reader := bufio.NewReader(conn)   // conn is a net.Conn
dec := json.NewDecoder(reader)

for {   

    // How can I also log the original data before decoding it into the struct?

    var dst customStruct
    if err = dec.Decode(&dst); err == io.EOF {
        break
    } else if err != nil {
        log.Errorf("failed to decode message: %s", err)
        break
    }

    // do something with dst...

}
    

您可以使用ioutil.ReadAll(),然后从字节中打印和解码。但是由于您在不使用缓冲区的情况下读取所有字节,因此理想情况下您应该将其放在 debug 标志检查之后。

bs,err := ioutil.ReadAll()
if err != nil {
    panic(err)
}

log.Printf("output: %s", string(bs))

var dst customStruct
if err := json.Unmarshal(bs, &dst); err != nil {
    panic(err)
}

使用iotest.NewReadLogger在读取数据时记录数据:

prefix := fmt.Sprintf("%p:", conn)
reader := bufio.NewReader(iotest.NewReadLogger(prefix, conn)) 
dec := json.NewDecoder(reader)

for {   

    var dst customStruct
    if err = dec.Decode(&dst); err == io.EOF {
        break
    } else if err != nil {
        log.Errorf("failed to decode message: %s", err)
        break
    }

    // do something with dst...

}
    

如果读取记录器的输出不符合您的口味,请复制 the implementation 并根据需要进行调整。实现非常简单。